Diff
316 commits, 279 files changed
+403719 -8142

UTIL: Add function for atomic I/O
Ondrej Kos • 11 years ago  
Add new debug level macros
Ondrej Kos • 11 years ago  
Do not send SIGPIPE on disconnection
Shantanu Goel • 11 years ago  
Fix FTBFS related to -Werror=format-security
Krzysztof Klimonda • 12 years ago  
Add vetoed_shells option
John Hodrien • 12 years ago  
Changing default to Default for consistency
Kaushik Banerjee • 12 years ago  
file modified
+20 -1
@@ -59,5 +59,24 @@

  sssd_pam

  krb5_child

  ldap_child

+ sss_cache

  *~

- 

+ crypto-tests

+ debug-tests

+ fail_over-tests

+ files-tests

+ find_uid-tests

+ ipa_hbac-tests

+ ipa_ldap_opt-tests

+ krb5-utils-tests

+ pam_test_client

+ proxy_child

+ refcount-tests

+ resolv-tests

+ simple_access-tests

+ stress-tests

+ strtonum-tests

+ sysdb-tests

+ util-tests

+ auth-tests

+ check_and_open-tests

file added
+13
@@ -0,0 +1,13 @@

+ [main]

+ host = https://www.transifex.net

+ 

+ [sssd.master-po-sssd-pot]

+ file_filter = po/<lang>.po

+ source_file = po/sssd.pot

+ source_lang = en

+ 

+ [sssd.sssd-docspot_1]

+ file_filter = src/man/po/<lang>.po

+ source_file = src/man/po/sssd-docs.pot

+ source_lang = en

+ 

file modified
+11 -5
@@ -10,7 +10,11 @@

  

  They are now available in major distribution development branches.

  

- If you want to build them from source download the latest samba master branch.

+ If you want to build them from source download them from the following links:

+ http://samba.org/ftp/talloc/

+ http://samba.org/ftp/tdb/

+ http://samba.org/ftp/tevent/

+ http://samba.org/ftp/ldb/

  

  Additionally the ding-libs are needed. These used to be included in the sssd

  release but are now a separate project. The lastest ding-libs release can be
@@ -18,10 +22,12 @@

  

  To install all of the dependencies in Fedora before building sssd:

  yum install openldap-devel gettext libtool pcre-devel c-ares-devel \

-     dbus-devel libxslt-devel docbook-style-xsl krb5-devel \

-     docbook-style-xsl libxml2 pam-devel nss-devel libtevent \

+     dbus-devel libxslt docbook-style-xsl krb5-devel nspr-devel \

+     libxml2 pam-devel nss-devel libtevent python-devel \

      libtevent-devel libtdb libtdb-devel libtalloc libtalloc-devel \

-     libldb libldb-devel cvs popt-devel c-ares-devel

+     libldb libldb-devel cvs popt-devel c-ares-devel check-devel \

+     doxygen libselinux-devel libsemanage-devel bind-utils libnl-devel \

+     nscd gettext-devel

  

  ding-libs are available in Fedora 14 and later version:

  yum install  libcollection-devel  libdhash-devel  libini_config-devel \
@@ -57,4 +63,4 @@

  ./pam_test_client [auth|chau|acct|setc|open|clos] username@domain

  

  ~~~~~

- Simo and Steve (Last updated for 1.4.1)

+ Simo and Steve (Last updated for 1.5.2)

file modified
+105 -15
@@ -1,6 +1,10 @@

  DISTCHECK_CONFIGURE_FLAGS = --with-ldb-lib-dir="$$dc_install_base"/lib/ldb

  

- SUBDIRS = po src/man

+ SUBDIRS = po

+ 

+ if HAVE_MANPAGES

+ SUBDIRS += src/man

+ endif

  

  # Some old versions of automake don't define builddir

  builddir ?= .
@@ -32,6 +36,10 @@

  initdir = @initdir@

  logpath = @logpath@

  pubconfpath = @pubconfpath@

+ pkgconfigdir = $(libdir)/pkgconfig

+ krb5rcachedir = @krb5rcachedir@

+ 

+ UNICODE_LIBS=@UNICODE_LIBS@

  

  AM_CFLAGS =

  if WANT_AUX_INFO
@@ -40,9 +48,12 @@

  if HAVE_GCC

      AM_CFLAGS += -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith \

                   -Wcast-qual -Wcast-align -Wwrite-strings \

-                  -Werror-implicit-function-declaration

+                  -Werror-implicit-function-declaration \

+                  -fno-strict-aliasing

  endif

  

+ dist_pkgconfig_DATA =

+ 

  ACLOCAL_AMFLAGS = -I m4 -I .

  

  sbin_PROGRAMS = \
@@ -78,7 +89,8 @@

          ipa_ldap_opt-tests \

          simple_access-tests \

          crypto-tests \

-         util-tests

+         util-tests \

+         ipa_hbac-tests

  endif

  

  check_PROGRAMS = \
@@ -88,7 +100,8 @@

  PYTHON_TESTS =

  

  if BUILD_PYTHON_BINDINGS

- PYTHON_TESTS += $(srcdir)/src/config/SSSDConfigTest.py

+ PYTHON_TESTS += src/config/SSSDConfigTest.py \

+                 src/tests/pyhbac-test.py

  endif

  

  TESTS = \
@@ -111,7 +124,8 @@

  endif

  

  noinst_LTLIBRARIES = \

-     libsss_crypt.la

+     libsss_crypt.la \

+     libsss_utf8.la

  

  if HAVE_NSS

      SSS_CRYPT_SOURCES = src/util/crypto/nss/nss_sha512crypt.c \
@@ -134,9 +148,13 @@

  libsss_crypt_la_LIBADD = \

      $(SSS_CRYPT_LIBS)

  

+ libsss_utf8_la_SOURCES = src/util/sss_utf8.c

+ libsss_utf8_la_LIBADD = $(UNICODE_LIBS)

+ 

  if BUILD_PYTHON_BINDINGS

  pyexec_LTLIBRARIES = \

-     pysss.la

+     pysss.la \

+     pyhbac.la

  endif

  

  dist_noinst_SCRIPTS = \
@@ -145,7 +163,8 @@

      src/config/ipachangeconf.py \

      src/config/SSSDConfig.py \

      src/config/SSSDConfigTest.py \

-     src/config/sssd_upgrade_config.py

+     src/config/sssd_upgrade_config.py \

+     src/tests/pyhbac-test.py

  

  dist_noinst_DATA = \

      src/config/testconfigs/sssd-valid.conf \
@@ -179,6 +198,7 @@

      $(INI_CONFIG_CFLAGS) \

      $(DHASH_CFLAGS) \

      $(LIBNL_CFLAGS) \

+     $(GLIB2_CFLAGS) \

      -DLIBDIR=\"$(libdir)\" \

      -DVARDIR=\"$(localstatedir)\" \

      -DSHLIBEXT=\"$(SHLIBEXT)\" \
@@ -217,6 +237,7 @@

      src/util/backup_file.c \

      src/util/strtonum.c \

      src/util/check_and_open.c \

+     src/util/atomic_io.c \

      src/util/refcount.c \

      $(SSSD_DEBUG_OBJ)

  
@@ -259,7 +280,8 @@

      $(SSS_CRYPT_LIBS) \

      $(OPENLDAP_LIBS) \

      $(TDB_LIBS) \

-     libsss_crypt.la

+     libsss_crypt.la \

+     libsss_utf8.la

  

  PYTHON_BINDINGS_LIBS = \

      $(TALLOC_LIBS) \
@@ -284,8 +306,9 @@

      $(INI_CONFIG_LIBS) \

      $(COLLECTION_LIBS) \

      $(DHASH_LIBS) \

- 	$(OPENLDAP_LIBS) \

- 	$(TDB_LIBS) \

+     $(OPENLDAP_LIBS) \

+     $(TDB_LIBS) \

+     $(UNICODE_LIBS) \

      libsss_crypt.la

  

  if BUILD_SELINUX
@@ -299,12 +322,15 @@

  

  dist_noinst_HEADERS = \

      src/monitor/monitor.h \

+     src/util/atomic_io.h \

      src/util/crypto/sss_crypto.h \

      src/util/dlinklist.h \

      src/util/util.h \

      src/util/strtonum.h \

      src/util/sss_ldap.h \

+     src/util/sss_python.h \

      src/util/sss_krb5.h \

+     src/util/sss_utf8.h \

      src/util/refcount.h \

      src/util/find_uid.h \

      src/util/user_info_msg.h \
@@ -357,6 +383,16 @@

      dist_noinst_HEADERS += src/util/crypto/nss/nss_util.h

  endif

  

+ lib_LTLIBRARIES = libipa_hbac.la

+ dist_pkgconfig_DATA += src/providers/ipa/ipa_hbac.pc

+ libipa_hbac_la_SOURCES = \

+     src/providers/ipa/hbac_evaluator.c

+ libipa_hbac_la_LDFLAGS = \

+     -version 1:0:1

+ libipa_hbac_la_LIBADD = libsss_utf8.la

+ 

+ include_HEADERS = \

+     src/providers/ipa/ipa_hbac.h

  

  ####################

  # Program Binaries #
@@ -365,6 +401,7 @@

      src/monitor/monitor.c \

      src/monitor/monitor_netlink.c \

      src/confdb/confdb_setup.c \

+     src/providers/child_common.c \

      $(SSSD_UTIL_OBJ)

  sssd_LDADD = \

      $(SSSD_LIBS) \
@@ -392,6 +429,7 @@

      $(SSSD_LIBS)

  

  sssd_be_SOURCES = \

+     src/providers/child_common.c \

      src/providers/data_provider_be.c \

      src/providers/data_provider_fo.c \

      src/providers/data_provider_opts.c \
@@ -478,6 +516,12 @@

  #################

  # Feature Tests #

  #################

+ TESTS_ENVIRONMENT = LDB_MODULES_PATH=$(abs_top_builddir)/ldb_mod_test_dir

+ 

+ ldb_mod_test_dir: memberof.la

+ 	mkdir -p $(builddir)/ldb_mod_test_dir

+ 	cp $(builddir)/.libs/memberof.so $(builddir)/ldb_mod_test_dir

+ 

  noinst_LTLIBRARIES += \

      libsss_test_common.la

  
@@ -494,7 +538,6 @@

      src/tests/sysdb-tests.c \

      $(SSSD_UTIL_OBJ)

  sysdb_tests_CFLAGS = \

-     -DSYSDB_TEST \

      $(AM_CFLAGS) \

      $(CHECK_CFLAGS)

  sysdb_tests_LDADD = \
@@ -563,6 +606,7 @@

      src/tests/files-tests.c \

      src/util/check_and_open.c \

      src/tools/selinux.c \

+     src/util/atomic_io.c \

      src/tools/files.c

  files_tests_CFLAGS = \

      $(AM_CFLAGS) \
@@ -690,6 +734,18 @@

      $(CHECK_LIBS) \

      libsss_test_common.la

  

+ ipa_hbac_tests_SOURCES = \

+     src/tests/ipa_hbac-tests.c \

+     $(SSSD_UTIL_OBJ)

+ ipa_hbac_tests_CFLAGS = \

+     $(AM_CFLAGS) \

+     $(CHECK_CFLAGS)

+ ipa_hbac_tests_LDADD = \

+     $(SSSD_LIBS) \

+     $(CHECK_LIBS) \

+     libsss_test_common.la \

+     libipa_hbac.la

+ 

  endif

  

  stress_tests_SOURCES = \
@@ -833,12 +889,19 @@

      src/providers/ipa/ipa_auth.c \

      src/providers/ipa/ipa_access.c \

      src/providers/ipa/ipa_dyndns.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_services.c \

+     src/providers/ipa/ipa_hbac_users.c \

+     src/providers/ipa/ipa_hbac_common.c \

      src/providers/ldap/ldap_id.c \

      src/providers/ldap/ldap_id_enum.c \

      src/providers/ldap/ldap_id_cleanup.c \

      src/providers/ldap/ldap_id_netgroup.c \

      src/providers/ldap/ldap_auth.c \

      src/providers/ldap/ldap_common.c \

+     src/providers/ldap/sdap_access.c \

      src/providers/ldap/sdap_async.c \

      src/providers/ldap/sdap_async_accounts.c \

      src/providers/ldap/sdap_async_connection.c \
@@ -870,7 +933,8 @@

      $(DHASH_LIBS) \

      $(KEYUTILS_LIBS) \

      $(KRB5_LIBS) \

-     libsss_crypt.la

+     libsss_crypt.la \

+     libipa_hbac.la

  libsss_ipa_la_LDFLAGS = \

      -version-info 1:0:0 \

      -module
@@ -882,7 +946,9 @@

      src/providers/child_common.c \

      src/providers/dp_pam_data_util.c \

      src/util/user_info_msg.c \

-     src/util/sss_krb5.c

+     src/util/sss_krb5.c \

+     src/util/util.c \

+     src/util/signal.c

  krb5_child_CFLAGS = \

      $(AM_CFLAGS) \

      $(POPT_CFLAGS) \
@@ -891,13 +957,16 @@

      $(TALLOC_LIBS) \

      $(TEVENT_LIBS) \

      $(POPT_LIBS) \

+     $(DHASH_LIBS) \

      $(KRB5_LIBS)

  

  ldap_child_SOURCES = \

      $(SSSD_DEBUG_OBJ) \

      src/providers/ldap/ldap_child.c \

      src/providers/child_common.c \

-     src/util/sss_krb5.c

+     src/util/sss_krb5.c \

+     src/util/util.c \

+     src/util/signal.c

  ldap_child_CFLAGS = \

      $(AM_CFLAGS) \

      $(POPT_CFLAGS) \
@@ -907,6 +976,7 @@

      $(TEVENT_LIBS) \

      $(POPT_LIBS) \

      $(OPENLDAP_LIBS) \

+     $(DHASH_LIBS) \

      $(KRB5_LIBS)

  

  proxy_child_SOURCES = \
@@ -955,13 +1025,28 @@

  pysss_la_LDFLAGS = \

      -avoid-version \

      -module

+ 

+ pyhbac_la_SOURCES = \

+     src/python/pyhbac.c \

+     src/util/sss_python.c

+ pyhbac_la_CFLAGS = \

+     $(AM_CFLAGS)  \

+     $(PYTHON_CFLAGS)

+ pyhbac_la_LIBADD = \

+     $(PYTHON_LIBS) \

+     libipa_hbac.la

+ pyhbac_la_LDFLAGS = \

+     -avoid-version \

+     -module

  endif

  

  ################

  # TRANSLATIONS #

  ################

  update-po:

+ if HAVE_MANPAGES

  	$(MAKE) -C src/man update-po

+ endif

  	$(MAKE) -C po update-po

  

  #######################
@@ -1016,13 +1101,14 @@

  if HAVE_DOXYGEN

  docs:

  	$(DOXYGEN) src/doxy.config

+ 	$(DOXYGEN) src/providers/ipa/ipa_hbac.doxy

  else

  docs:

  	@echo "Doxygen not installed, cannot generate documentation"

  	@exit 1

  endif

  

- all-local:

+ all-local: ldb_mod_test_dir

  if BUILD_PYTHON_BINDINGS

  	cd $(srcdir)/src/config; $(PYTHON) setup.py build --build-base $(abs_builddir)/src/config

  endif
@@ -1041,6 +1127,9 @@

  	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/.files ]; then \
@@ -1054,6 +1143,7 @@

  	cd $(srcdir)/src/config; $(PYTHON) setup.py build --build-base $(abs_builddir)/src/config clean --all

  endif

  	rm -Rf doc

+ 	rm -Rf ldb_mod_test_dir

  

  CLEANFILES = *.X */*.X */*/*.X

  

file modified
+36 -2
@@ -55,6 +55,10 @@

      [AC_DEFINE([HAVE_PTHREAD], [1], [Pthread mutexes available.])],

      [AC_MSG_WARN([Pthread library not found! Clients will not be thread safe...])])

  

+ # Check for presence of modern functions for setting file timestamps

+ AC_CHECK_FUNCS([ utimensat \

+                  futimens ])

+ 

  #Check for PAM headers

  AC_CHECK_HEADERS([security/pam_appl.h security/pam_misc.h security/pam_modules.h],

      [AC_CHECK_LIB(pam, pam_get_item, [ PAM_LIBS="-lpam" ], [AC_MSG_ERROR([PAM must support pam_get_item])])],
@@ -90,11 +94,13 @@

  WITH_MANPAGES

  WITH_XML_CATALOG

  WITH_KRB5_PLUGIN_PATH

+ WITH_KRB5_RCACHE_DIR

  WITH_PYTHON_BINDINGS

  WITH_SELINUX

  WITH_NSCD

  WITH_SEMANAGE

  WITH_LIBNL

+ WITH_NOLOGIN_SHELL

  

  m4_include([src/external/pkg.m4])

  m4_include([src/external/libpopt.m4])
@@ -121,6 +127,19 @@

  m4_include([src/external/libnl.m4])

  m4_include([src/util/signal.m4])

  

+ 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=-lunistring

+             AC_SUBST(UNICODE_LIBS)

+ else

+     m4_include([src/external/glib.m4])

+             AC_DEFINE_UNQUOTED(HAVE_GLIB2, 1, [Using libunistring for unicode])

+             UNICODE_LIBS=$GLIB2_LIBS

+             AC_SUBST(UNICODE_LIBS)

+ 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
@@ -143,14 +162,16 @@

                       [http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl],

                       [Docbook XSL templates])

      AC_CHECK_PROG([PO4A],[po4a],[po4a],[no])

-     AM_CONDITIONAL([HAVE_PO4A], [test "x$PO4A" != "xno"])

  fi

+ AM_CONDITIONAL([HAVE_MANPAGES], [test "x$HAVE_MANPAGES" != "x"])

+ AM_CONDITIONAL([HAVE_PO4A], [test "x$PO4A" != "xno"])

  

  if test x$HAVE_PYTHON_BINDINGS != x; then

      AM_PATH_PYTHON([2.4])

      AM_CHECK_PYTHON_HEADERS([],

                              AC_MSG_ERROR([Could not find python headers]))

      AM_PYTHON_CONFIG

+     AM_CHECK_PYTHON_COMPAT

  fi

  

  if test x$HAVE_SELINUX != x; then
@@ -169,6 +190,18 @@

  

  AC_CHECK_HEADERS([sasl/sasl.h],,AC_MSG_ERROR([Could not find SASL headers]))

  

+ 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

+ 

  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])
@@ -186,6 +219,7 @@

  AC_SUBST([abs_builddir], $abs_build_dir)

  

  AC_CONFIG_FILES([Makefile contrib/sssd.spec src/examples/rwtab src/doxy.config

-                  src/sysv/systemd/sssd.service po/Makefile.in src/man/Makefile])

+                  src/sysv/systemd/sssd.service po/Makefile.in src/man/Makefile

+                  src/providers/ipa/ipa_hbac.pc src/providers/ipa/ipa_hbac.doxy])

  AC_OUTPUT

  

file modified
+106 -23
@@ -3,6 +3,9 @@

  %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}

  %endif

  

+ # Determine the location of the LDB modules directory

+ %global ldb_modulesdir %(pkg-config --variable=modulesdir ldb)

+ 

  Name: @PACKAGE_NAME@

  Version: @PACKAGE_VERSION@

  Release: 0@PRERELEASE_VERSION@%{?dist}
@@ -19,7 +22,8 @@

  

  Requires: libldb >= 0.9.3

  Requires: libtdb >= 1.1.3

- Requires: sssd-client = %{version}-%{release}

+ Requires: sssd-client%{?_isa} = %{version}-%{release}

+ Requires: libipa_hbac = %{version}-%{release}

  Requires: cyrus-sasl-gssapi

  Requires: keyutils-libs

  Requires(post): initscripts chkconfig /sbin/ldconfig
@@ -73,7 +77,10 @@

  BuildRequires: keyutils-libs-devel

  BuildRequires: libnl-devel

  BuildRequires: nscd

- BuildRequires: gettext

+ BuildRequires: gettext-devel

+ BuildRequires: pkgconfig

+ BuildRequires: libunistring-devel

+ BuildRequires: findutils

  

  %description

  Provides a set of daemons to manage access to remote directories and
@@ -104,21 +111,71 @@

  Also provides a userspace tool for generating an obfuscated LDAP password for

  use with ldap_default_authtok_type = obfuscated_password.

  

+ %package -n libipa_hbac

+ Summary: FreeIPA HBAC Evaluator library

+ Group: Development/Libraries

+ License: LGPLv3+

+ 

+ %description -n libipa_hbac

+ Utility library to validate FreeIPA HBAC rules for authorization requests

+ 

+ %package -n libipa_hbac-devel

+ Summary: FreeIPA HBAC Evaluator library

+ Group: Development/Libraries

+ License: LGPLv3+

+ Requires: libipa_hbac = %{version}-%{release}

+ 

+ %description -n libipa_hbac-devel

+ Utility library to validate FreeIPA HBAC rules for authorization requests

+ 

+ %package -n libipa_hbac-python

+ Summary: Python bindings for the FreeIPA HBAC Evaluator library

+ Group: Development/Libraries

+ License: LGPLv3+

+ Requires: libipa_hbac = %{version}-%{release}

+ 

+ %description -n libipa_hbac-python

+ The libipa_hbac-python contains the bindings so that libipa_hbac can be

+ used by Python applications.

+ 

  %prep

  %setup -q

  

  %build

+ 

+ # RHEL 5 uses an old libtool, so we need to force it to reconfigure

+ # This is safe to do on newer packages too, as it will just

+ # gather the appropriate m4 files from the libtool package

+ for i in libtool.m4  lt~obsolete.m4  ltoptions.m4  ltsugar.m4  ltversion.m4

+ do

+     find . -name $i -exec rm -f {} \;

+ done

+ 

+ autoreconf -ivf

+ 

  %configure \

      --with-db-path=%{dbpath} \

      --with-pipe-path=%{pipepath} \

      --with-pubconf-path=%{pubconfpath} \

      --with-init-dir=%{_initrddir} \

+     --with-krb5-rcache-dir=%{_localstatedir}/cache/krb5rcache \

      --enable-nsslibdir=/%{_lib} \

      --enable-pammoddir=/%{_lib}/security \

      --disable-static \

      --disable-rpath

  

- make %{?_smp_mflags}

+ make %{?_smp_mflags} all

+ 

+ 

+ # Only build docs on recent distros

+ %if 0%{?fedora}

+ make %{?_smp_mflags} docs

+ %endif

+ 

+ %if 0%{?rhel} >= 6

+ make %{?_smp_mflags} docs

+ %endif

+ 

  

  %check

  export CK_TIMEOUT_MULTIPLIER=10
@@ -136,8 +193,8 @@

  # Copy default sssd.conf file

  mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/sssd

  install -m600 src/examples/sssd.conf $RPM_BUILD_ROOT%{_sysconfdir}/sssd/sssd.conf

- install -m400 src/config/etc/sssd.api.conf $RPM_BUILD_ROOT%{_sysconfdir}/sssd/sssd.api.conf

- install -m400 src/config/etc/sssd.api.d/* $RPM_BUILD_ROOT%{_sysconfdir}/sssd/sssd.api.d/

+ install -m444 src/config/etc/sssd.api.conf $RPM_BUILD_ROOT%{_sysconfdir}/sssd/sssd.api.conf

+ install -m444 src/config/etc/sssd.api.d/* $RPM_BUILD_ROOT%{_sysconfdir}/sssd/sssd.api.d/

  

  # Copy default logrotate file

  mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/logrotate.d
@@ -148,17 +205,10 @@

  install -m644 src/examples/rwtab $RPM_BUILD_ROOT%{_sysconfdir}/rwtab.d/sssd

  

  # Remove .la files created by libtool

- rm -f \

-     $RPM_BUILD_ROOT/%{_lib}/libnss_sss.la \

-     $RPM_BUILD_ROOT/%{_lib}/security/pam_sss.la \

-     $RPM_BUILD_ROOT/%{_libdir}/ldb/memberof.la \

-     $RPM_BUILD_ROOT/%{_libdir}/sssd/libsss_ldap.la \

-     $RPM_BUILD_ROOT/%{_libdir}/sssd/libsss_proxy.la \

-     $RPM_BUILD_ROOT/%{_libdir}/sssd/libsss_krb5.la \

-     $RPM_BUILD_ROOT/%{_libdir}/sssd/libsss_ipa.la \

-     $RPM_BUILD_ROOT/%{_libdir}/sssd/libsss_simple.la \

-     $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.la \

-     $RPM_BUILD_ROOT/%{python_sitearch}/pysss.la

+ find $RPM_BUILD_ROOT -name "*.la" -exec rm -f {} \;

+ 

+ # Suppress developer-only documentation

+ rm -Rf ${RPM_BUILD_ROOT}/%{_docdir}/%{name}/doc

  

  # Older versions of rpmbuild can only handle one -f option

  # So we need to append to the sssd.lang file
@@ -167,6 +217,20 @@

      echo %{python_sitelib}/`basename $file` >> sssd.lang

  done

  

+ touch sssd_tools.lang

+ for man in `find $RPM_BUILD_ROOT/%{_mandir}/??/man?/ -type f | sed -e "s#$RPM_BUILD_ROOT/%{_mandir}/##"`

+ do

+     lang=`echo $man | cut -c 1-2`

+     case `basename $man` in

+         sss_*)

+             echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_tools.lang

+             ;;

+         *)

+             echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd.lang

+             ;;

+     esac

+ done

+ 

  %clean

  rm -rf $RPM_BUILD_ROOT

  
@@ -177,19 +241,20 @@

  %{_sbindir}/sssd

  %{_libexecdir}/%{servicename}/

  %{_libdir}/%{name}/

- %{_libdir}/ldb/memberof.so

+ %{ldb_modulesdir}/memberof.so

  %dir %{sssdstatedir}

+ %dir %{_localstatedir}/cache/krb5rcache

  %attr(700,root,root) %dir %{dbpath}

  %attr(755,root,root) %dir %{pipepath}

  %attr(755,root,root) %dir %{pubconfpath}

  %attr(700,root,root) %dir %{pipepath}/private

  %attr(750,root,root) %dir %{_var}/log/%{name}

- %attr(700,root,root) %dir %{_sysconfdir}/sssd

+ %attr(711,root,root) %dir %{_sysconfdir}/sssd

  %config(noreplace) %{_sysconfdir}/sssd/sssd.conf

  %config(noreplace) %{_sysconfdir}/logrotate.d/sssd

  %config(noreplace) %{_sysconfdir}/rwtab.d/sssd

  %config %{_sysconfdir}/sssd/sssd.api.conf

- %attr(700,root,root) %dir %{_sysconfdir}/sssd/sssd.api.d

+ %attr(755,root,root) %dir %{_sysconfdir}/sssd/sssd.api.d

  %config %{_sysconfdir}/sssd/sssd.api.d/

  %{_mandir}/man5/sssd.conf.5*

  %{_mandir}/man5/sssd-ipa.5*
@@ -200,9 +265,6 @@

  %{python_sitearch}/pysss.so

  %{python_sitelib}/*.py*

  

- %lang(cs)       %{_mandir}/cs/man[58]/*

- %lang(uk)       %{_mandir}/uk/man[58]/*

- 

  %files client

  %defattr(-,root,root,-)

  %doc src/sss_client/COPYING src/sss_client/COPYING.LESSER
@@ -212,7 +274,7 @@

  %{_mandir}/man8/pam_sss.8*

  %{_mandir}/man8/sssd_krb5_locator_plugin.8*

  

- %files tools

+ %files tools -f sssd_tools.lang

  %defattr(-,root,root,-)

  %doc COPYING

  %{_sbindir}/sss_useradd
@@ -232,6 +294,27 @@

  %{_mandir}/man8/sss_usermod.8*

  %{_mandir}/man8/sss_obfuscate.8*

  

+ %files -n libipa_hbac

+ %defattr(-,root,root,-)

+ %doc src/sss_client/COPYING src/sss_client/COPYING.LESSER

+ %{_libdir}/libipa_hbac.so.*

+ 

+ %files -n libipa_hbac-devel

+ %defattr(-,root,root,-)

+ %if 0%{?fedora}

+ %doc hbac_doc/html

+ %endif

+ %if 0%{?rhel} >= 6

+ %doc hbac_doc/html

+ %endif

+ %{_includedir}/ipa_hbac.h

+ %{_libdir}/libipa_hbac.so

+ %{_libdir}/pkgconfig/ipa_hbac.pc

+ 

+ %files -n libipa_hbac-python

+ %defattr(-,root,root,-)

+ %{python_sitearch}/pyhbac.so

+ 

  %post

  /sbin/ldconfig

  /sbin/chkconfig --add %{servicename}

file modified
+60 -7
@@ -1,14 +1,67 @@

+ ar

+ as

+ ast

+ bal

+ bg

+ bn_IN

+ bn

+ bs

+ ca

+ cs_CZ

+ cs

+ da

+ de_CH

+ de

+ el

+ en_GB

  es

- pl

+ et

+ fa_IR

+ fa

+ fi

+ fr

+ gu

+ he

+ hi

+ hu

+ id

+ is

+ it

+ ja_JP

  ja

+ kn

+ ko

+ lt_LT

+ lt

+ mai

+ ml

+ mr

+ nb

+ nds

  nl

+ nn

+ or

+ pa

+ pl

+ pt_BR

  pt

- de

+ ro

+ ru

+ sk

+ sl

+ sq

+ sr

  sv

- it

- fr

- id

- zh_TW

+ ta_IN

+ ta

+ te

+ tg

+ tr

  uk

- ru

+ ur

+ vi

+ vi_VN

+ zh_CN

+ zh_HK

+ zh_TW

  

file added
+1168
The added file is too large to be shown here, see it at: po/ar.po
file added
+1168
The added file is too large to be shown here, see it at: po/as.po
file added
+1168
The added file is too large to be shown here, see it at: po/ast.po
file added
+1167
The added file is too large to be shown here, see it at: po/bal.po
file added
+1167
The added file is too large to be shown here, see it at: po/bg.po
file added
+1167
The added file is too large to be shown here, see it at: po/bn.po
file added
+1167
The added file is too large to be shown here, see it at: po/bn_IN.po
file added
+1169
The added file is too large to be shown here, see it at: po/bs.po
file added
+1167
The added file is too large to be shown here, see it at: po/ca.po
file added
+1167
The added file is too large to be shown here, see it at: po/cs.po
file added
+1167
The added file is too large to be shown here, see it at: po/cs_CZ.po
file added
+1167
The added file is too large to be shown here, see it at: po/da.po
file modified
+197 -149
@@ -8,7 +8,7 @@

  msgstr ""

  "Project-Id-Version: SSS\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: 2009-12-09 11:13+0100\n"

  "Last-Translator: Fabian Affolter <fab@fedoraproject.org>\n"

  "Language-Team: German <fedora-trans-de@redhat.com>\n"
@@ -62,576 +62,624 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:54

- msgid "Enumeration cache timeout length (seconds)"

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

  msgstr ""

  

  #: src/config/SSSDConfig.py:55

- msgid "Entry cache background update timeout length (seconds)"

+ msgid "Enumeration cache timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:56

- msgid "Negative cache timeout length (seconds)"

+ msgid "Entry cache background update timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:57

- msgid "Users that SSSD should explicitly ignore"

+ msgid "Negative cache timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:58

- msgid "Groups that SSSD should explicitly ignore"

+ msgid "Users that SSSD should explicitly ignore"

  msgstr ""

  

  #: src/config/SSSDConfig.py:59

- msgid "Should filtered users appear in groups"

+ msgid "Groups that SSSD should explicitly ignore"

  msgstr ""

  

  #: src/config/SSSDConfig.py:60

+ msgid "Should filtered users appear in groups"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr ""

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

- msgid "How long to allow cached logins between online logins (days)"

+ msgid "The list of shells users are allowed to log in with"

  msgstr ""

  

  #: src/config/SSSDConfig.py:64

- msgid "How many failed logins attempts are allowed when offline"

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

  msgstr ""

  

  #: src/config/SSSDConfig.py:65

  msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

+ msgid "How long to allow cached logins between online logins (days)"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:69

+ msgid "How many failed logins attempts are allowed when offline"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:70

+ msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"

  msgstr ""

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr ""

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr ""

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr ""

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr ""

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr ""

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr ""

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr "IPA-Domain"

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr "IPA-Serveradresse"

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr "IPA-Client-Rechnername"

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr ""

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr "Kerberos-Serveradresse"

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr "Kerberos Realm"

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr ""

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr ""

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr ""

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr ""

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr ""

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr ""

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr ""

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr ""

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr ""

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr ""

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  msgid "File that contains CA certificates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr ""

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  msgid "File that contains the client certificate"

  msgstr ""

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  msgid "File that contains the client key"

  msgstr ""

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr ""

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr ""

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr ""

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr ""

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  msgid "Lifetime of TGT for LDAP connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr ""

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  msgid "Service name for DNS service lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  #, fuzzy

  msgid "entryUSN attribute"

  msgstr "UID-Attribut"

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  #, fuzzy

  msgid "lastUSN attribute"

  msgstr "UID-Attribut"

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr ""

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  msgid "Length of time to wait for a enumeration request"

  msgstr ""

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  msgid "Length of time between cache cleanups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  msgid "Require TLS for ID lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr "Benutzername-Attribut"

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr "UID-Attribut"

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr "GECOS-Attribut"

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr "Shell-Attribut"

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr "UUID-Attribut"

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr "Vollständiger Name"

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  #, fuzzy

  msgid "shadowMin attribute"

  msgstr "Benutzername-Attribut"

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  #, fuzzy

  msgid "shadowMax attribute"

  msgstr "Benutzername-Attribut"

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  #, fuzzy

  msgid "shadowWarning attribute"

  msgstr "Benutzername-Attribut"

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  #, fuzzy

  msgid "shadowInactive attribute"

  msgstr "Benutzername-Attribut"

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  #, fuzzy

  msgid "shadowExpire attribute"

  msgstr "Benutzername-Attribut"

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  #, fuzzy

  msgid "shadowFlag attribute"

  msgstr "Shell-Attribut"

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr ""

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  msgid "krbPasswordExpiration attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  #, fuzzy

  msgid "accountExpires attribute of AD"

  msgstr "Benutzername-Attribut"

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  #, fuzzy

  msgid "nsAccountLock attribute"

  msgstr "Benutzername-Attribut"

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  msgid "Base DN for group lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  msgid "Objectclass for groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  #, fuzzy

  msgid "Group name"

  msgstr "Gruppen"

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  #, fuzzy

  msgid "Group password"

  msgstr "Gruppen"

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  #, fuzzy

  msgid "GID attribute"

  msgstr "UID-Attribut"

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  #, fuzzy

  msgid "Group member attribute"

  msgstr "Benutzername-Attribut"

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  #, fuzzy

  msgid "Group UUID attribute"

  msgstr "UUID-Attribut"

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  msgid "Modification time attribute for groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr ""

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  msgid "Base DN for netgroup lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  msgid "Objectclass for netgroups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  #, fuzzy

  msgid "Netgroups members attribute"

  msgstr "Benutzername-Attribut"

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  #, fuzzy

  msgid "Netgroup triple attribute"

  msgstr "Benutzername-Attribut"

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  #, fuzzy

  msgid "Netgroup UUID attribute"

  msgstr "UUID-Attribut"

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  msgid "Modification time attribute for netgroups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr ""

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr ""

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr ""

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr ""

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr ""

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr ""

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr ""

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr ""

  
@@ -653,27 +701,27 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr ""

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  msgid "Unexpected format of the server credential message."

  msgstr ""

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr ""

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr ""

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr ""

  
@@ -719,23 +767,23 @@

  msgid "Server message: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  msgid "Current Password: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr ""

  

file added
+1167
The added file is too large to be shown here, see it at: po/de_CH.po
file added
+1167
The added file is too large to be shown here, see it at: po/el.po
file added
+1168
The added file is too large to be shown here, see it at: po/en_GB.po
file modified
+197 -149
@@ -8,7 +8,7 @@

  msgstr ""

  "Project-Id-Version: sss_daemon 0.4.0\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: 2010-07-20 09:18-0300\n"

  "Last-Translator: Héctor Daniel Cabrera <logan@fedoraproject.org>\n"

  "Language-Team: Fedora Spanish <trans-es@lists.fedoraproject.org>\n"
@@ -68,46 +68,71 @@

  msgstr ""

  "Formato compatible con printf para mostrar nombres completamente calificados"

  

- #: src/config/SSSDConfig.py:54

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:55

  msgid "Enumeration cache timeout length (seconds)"

  msgstr "Tiempo máximo (segundos) del caché de enumeración"

  

- #: src/config/SSSDConfig.py:55

+ #: src/config/SSSDConfig.py:56

  msgid "Entry cache background update timeout length (seconds)"

  msgstr ""

  "Tiempo máximo (segundos) de la entrada de caché a actualizar en segundo plano"

  

- #: src/config/SSSDConfig.py:56

+ #: src/config/SSSDConfig.py:57

  msgid "Negative cache timeout length (seconds)"

  msgstr "Tiempo máximo negativo del cache (segundos)"

  

- #: src/config/SSSDConfig.py:57

+ #: src/config/SSSDConfig.py:58

  msgid "Users that SSSD should explicitly ignore"

  msgstr "Usuarios que deben ser explícitamente ignorados por SSSD"

  

- #: src/config/SSSDConfig.py:58

+ #: src/config/SSSDConfig.py:59

  msgid "Groups that SSSD should explicitly ignore"

  msgstr "Grupos que deben ser explícitamente ignorados por SSSD"

  

- #: src/config/SSSDConfig.py:59

+ #: src/config/SSSDConfig.py:60

  msgid "Should filtered users appear in groups"

  msgstr "Deben aparecer los usuarios filtrados en los grupos"

  

- #: src/config/SSSDConfig.py:60

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr "El valor del campo contraseña que el proveedor NSS debe devolver"

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

+ msgid "The list of shells users are allowed to log in with"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:64

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:65

+ msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

  msgid "How long to allow cached logins between online logins (days)"

  msgstr ""

  "Por cuánto tiempo permitir ingresos cacheados entre ingresos en línea (días)"

  

- #: src/config/SSSDConfig.py:64

+ #: src/config/SSSDConfig.py:69

  msgid "How many failed logins attempts are allowed when offline"

  msgstr ""

  "Cuantos intentos de ingreso fallidos se permiten cuando está desconectado"

  

- #: src/config/SSSDConfig.py:65

+ #: src/config/SSSDConfig.py:70

  msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"
@@ -115,557 +140,580 @@

  "Cuántos minutos se denegará el ingreso después de que se alcance el máximo "

  "de ingresos fallidos offline_failed_login_attempts"

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr "Proveedor de identidad"

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr "Proveedor de Autenticación"

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr "Proveedor de control de acceso"

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr "Proveedor de cambio de contraseña"

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr "ID mínimo de usuario"

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr "ID máximo de usuario"

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr "Habilitar la enumeración de todos los usuarios/grupos"

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr "Hacer caché de las credenciales para ingresos fuera de línea"

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr "Guardar los hashes de la contraseña"

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr "Mostrar los usuarios/grupos en un formato completamente calificado"

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr "Tiempo máximo de una entrada del caché (segundos)"

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  "Restringir o preferir una familia de direcciones específica, cuando se "

  "realicen búsquedas DNS"

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr "Por cuánto tiempo permitir ingresos cacheados luego del último (días)"

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  "Cantidad de tiempo (en segundos) a esperar respuestas desde DNS cuando se "

  "estén resolviendo servidores"

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr "La sección del dominio de la consulta para descubrir servicios DNS"

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr "Dominio IPA"

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr "Dirección del servidor IPA"

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr "Nombre de equipo del cliente IPA"

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  "Si actualizar o no en forma automática la entrada DNS del cliente en FreeIPA"

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  "La interfaz cuya IP debería ser utilizada para actualizaciones DNS "

  "automáticas"

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr ""

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr "Dirección del servidor Kerberos"

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr "Reinado Kerberos"

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr "Expiración de la autenticación"

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr "Directorio donde almacenar las credenciales cacheadas"

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr "Ubicación del caché de credenciales del usuario"

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr "Ubicación de la tabla de claves para validar las credenciales"

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr "Habilitar la validación de credenciales"

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  "Si se encuentra desconectado, almacena contraseñas para más tarde realizar "

  "una autenticación en línea"

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr ""

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr ""

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  "El servidor en donde está ejecutándose el servicio de modificación de "

  "contraseña, en caso de no ser KDC. "

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr "ldap_uri, El URI del servidor LDAP"

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr "DN base predeterminado"

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr "El Tipo de Esquema a usar en el servidor LDAP, rfc2307"

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr "El DN Bind predeterminado"

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr "El tipo del token de autenticación del DN bind predeterminado"

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr "El token de autenticación del DN bind predeterminado"

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr "Tiempo durante el que se intentará la conexión"

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr "Tiempo durante el que se intentará operaciones LDAP sincrónicas"

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr "Tiempo entre intentos de reconexión cuando esté fuera de línea"

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  msgid "File that contains CA certificates"

  msgstr "Archivo que contiene los certificados CA"

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr "Ruta hacia un directorio certificado CA"

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  #, fuzzy

  msgid "File that contains the client certificate"

  msgstr "Archivo que contiene los certificados CA"

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  #, fuzzy

  msgid "File that contains the client key"

  msgstr "Archivo que contiene los certificados CA"

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr ""

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr "Requiere la verificación de certificado TLS"

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr "Especificar el mecanismo sasl a usar"

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr "Especifique el id de autorización sasl a usar"

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr "Tabla de clave del servicio Kerberos"

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr "Usar auth Kerberos para la conexión LDAP"

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr "Seguir referencias LDAP"

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  msgid "Lifetime of TGT for LDAP connection"

  msgstr "Período de vida del TGT para la conexión LDAP"

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr ""

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  #, fuzzy

  msgid "Service name for DNS service lookups"

  msgstr "Filtro para las búsquedas del usuario"

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  #, fuzzy

  msgid "entryUSN attribute"

  msgstr "Atributo UID"

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  #, fuzzy

  msgid "lastUSN attribute"

  msgstr "Atributo UID"

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr "Tiempo máximo a esperar un pedido de búsqueda"

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  #, fuzzy

  msgid "Length of time to wait for a enumeration request"

  msgstr "Tiempo máximo a esperar un pedido de búsqueda"

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr "Tiempo en segundos entre las actualizaciones de enumeración"

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  #, fuzzy

  msgid "Length of time between cache cleanups"

  msgstr "Tiempo en segundos entre las actualizaciones de enumeración"

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  msgid "Require TLS for ID lookups"

  msgstr "Requiere TLS para búsquedas de ID"

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr "DN base para búsquedas de usuario"

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr "Ambito de las búsquedas del usuario"

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr "Filtro para las búsquedas del usuario"

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr "Objectclass para los usuarios"

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr "Atributo Username"

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr "Atributo UID"

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr "Atributo GID primario"

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr "Atributo GECOS"

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr "Atributo Directorio de inicio"

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr "Atributo shell"

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr "Atributo UUID"

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr "Atributo principal del usuario (para Kerberos) "

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr "Nombre completo"

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr "Atributo memberOf"

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr "Atributo hora de modificación"

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  #, fuzzy

  msgid "shadowMin attribute"

  msgstr "Atributo Username"

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  #, fuzzy

  msgid "shadowMax attribute"

  msgstr "Atributo Username"

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  #, fuzzy

  msgid "shadowWarning attribute"

  msgstr "Atributo Username"

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  #, fuzzy

  msgid "shadowInactive attribute"

  msgstr "Atributo Username"

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  #, fuzzy

  msgid "shadowExpire attribute"

  msgstr "Atributo Username"

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  #, fuzzy

  msgid "shadowFlag attribute"

  msgstr "Atributo shell"

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr ""

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  #, fuzzy

  msgid "krbPasswordExpiration attribute"

  msgstr "Atributo hora de modificación"

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  #, fuzzy

  msgid "accountExpires attribute of AD"

  msgstr "Atributo Username"

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  #, fuzzy

  msgid "nsAccountLock attribute"

  msgstr "Atributo Username"

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  #, fuzzy

  msgid "Base DN for group lookups"

  msgstr "DN base para búsquedas de usuario"

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  #, fuzzy

  msgid "Objectclass for groups"

  msgstr "Objectclass para los usuarios"

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  #, fuzzy

  msgid "Group name"

  msgstr "Grupos"

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  #, fuzzy

  msgid "Group password"

  msgstr "Grupos"

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  #, fuzzy

  msgid "GID attribute"

  msgstr "Atributo UID"

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  #, fuzzy

  msgid "Group member attribute"

  msgstr "Atributo memberOf"

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  #, fuzzy

  msgid "Group UUID attribute"

  msgstr "Atributo UUID"

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  #, fuzzy

  msgid "Modification time attribute for groups"

  msgstr "Atributo hora de modificación"

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr ""

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  #, fuzzy

  msgid "Base DN for netgroup lookups"

  msgstr "DN base para búsquedas de usuario"

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  #, fuzzy

  msgid "Objectclass for netgroups"

  msgstr "Objectclass para los usuarios"

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  #, fuzzy

  msgid "Netgroups members attribute"

  msgstr "Atributo memberOf"

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  #, fuzzy

  msgid "Netgroup triple attribute"

  msgstr "Atributo hora de modificación"

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  #, fuzzy

  msgid "Netgroup UUID attribute"

  msgstr "Atributo UUID"

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  #, fuzzy

  msgid "Modification time attribute for netgroups"

  msgstr "Atributo hora de modificación"

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr "Política para evaluar el vencimiento de la contraseña"

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr "Filtro LDAP para determinar privilegios de acceso"

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr "Lista separada por comas de usuarios autorizados"

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr "Lista separada por comas de usuarios prohibidos"

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr "Shell predeterminado, /bin/bash"

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr "Base de los directorios de inicio"

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr "Nombre de la biblioteca NSS a usar"

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr "Pila PAM a usar"

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr "Convertirse en demonio (predeterminado)"

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr "Ejecutarse en forma interactiva (no un demonio)"

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr "Indicar un archivo de configuración diferente al predeterminado"

  
@@ -687,27 +735,27 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr "Dominio del proveedor de información (obligatorio)"

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr "El zócalo privilegiado posee permisos o pertenencia equivocados."

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr "El zócalo público posee permisos o pertenencia equivocados."

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  msgid "Unexpected format of the server credential message."

  msgstr "Formato no esperado del mensaje de la credencial del servidor."

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr "SSSD no está siendo ejecutado por el usuario root."

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr "Ha ocurrido un error, pero no se ha podido encontrar una descripción."

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr ""

  "Ha ocurrido un error no esperado mientras se buscaba la descripción del error"
@@ -754,23 +802,23 @@

  msgid "Server message: "

  msgstr "Mensaje del servidor:"

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr "Nueva contraseña: "

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr "Reingrese la contraseña nueva:"

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr "Contraseña: "

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  msgid "Current Password: "

  msgstr "Contraseña actual: "

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr "La contraseña ha expirado. Modifíquela en este preciso momento."

  

file added
+1168
The added file is too large to be shown here, see it at: po/et.po
file added
+1168
The added file is too large to be shown here, see it at: po/fa.po
file added
+1167
The added file is too large to be shown here, see it at: po/fa_IR.po
file added
+1168
The added file is too large to be shown here, see it at: po/fi.po
file modified
+197 -149
@@ -7,7 +7,7 @@

  msgstr ""

  "Project-Id-Version: fr\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: 2009-11-17 21:05+0100\n"

  "Last-Translator: Pablo Martin-Gomez <pablo.martin-gomez@laposte.net>\n"

  "Language-Team: Français <fedora-trans-fr@redhat.com>\n"
@@ -60,559 +60,607 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:54

- msgid "Enumeration cache timeout length (seconds)"

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

  msgstr ""

  

  #: src/config/SSSDConfig.py:55

- msgid "Entry cache background update timeout length (seconds)"

+ msgid "Enumeration cache timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:56

- msgid "Negative cache timeout length (seconds)"

+ msgid "Entry cache background update timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:57

- msgid "Users that SSSD should explicitly ignore"

+ msgid "Negative cache timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:58

- msgid "Groups that SSSD should explicitly ignore"

+ msgid "Users that SSSD should explicitly ignore"

  msgstr ""

  

  #: src/config/SSSDConfig.py:59

- msgid "Should filtered users appear in groups"

+ msgid "Groups that SSSD should explicitly ignore"

  msgstr ""

  

  #: src/config/SSSDConfig.py:60

+ msgid "Should filtered users appear in groups"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr ""

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

- msgid "How long to allow cached logins between online logins (days)"

+ msgid "The list of shells users are allowed to log in with"

  msgstr ""

  

  #: src/config/SSSDConfig.py:64

- msgid "How many failed logins attempts are allowed when offline"

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

  msgstr ""

  

  #: src/config/SSSDConfig.py:65

  msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

+ msgid "How long to allow cached logins between online logins (days)"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:69

+ msgid "How many failed logins attempts are allowed when offline"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:70

+ msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"

  msgstr ""

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  #, fuzzy

  msgid "Password change provider"

  msgstr "Le mot de passe a expiré."

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr ""

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr ""

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr ""

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr ""

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr ""

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr ""

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr ""

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr ""

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr ""

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr ""

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr ""

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr ""

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr ""

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr ""

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr ""

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr ""

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr ""

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr ""

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr ""

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr ""

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr ""

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr ""

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  msgid "File that contains CA certificates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr ""

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  msgid "File that contains the client certificate"

  msgstr ""

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  msgid "File that contains the client key"

  msgstr ""

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr ""

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr ""

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr ""

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr ""

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  msgid "Lifetime of TGT for LDAP connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr ""

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  msgid "Service name for DNS service lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  msgid "entryUSN attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  msgid "lastUSN attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr ""

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  msgid "Length of time to wait for a enumeration request"

  msgstr ""

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  msgid "Length of time between cache cleanups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  msgid "Require TLS for ID lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  msgid "shadowMin attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  msgid "shadowMax attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  msgid "shadowWarning attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  msgid "shadowInactive attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  msgid "shadowExpire attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  msgid "shadowFlag attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr ""

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  msgid "krbPasswordExpiration attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  msgid "accountExpires attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  msgid "nsAccountLock attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  msgid "Base DN for group lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  msgid "Objectclass for groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  msgid "Group name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  msgid "Group password"

  msgstr ""

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  msgid "GID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  msgid "Group member attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  msgid "Group UUID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  msgid "Modification time attribute for groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr ""

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  msgid "Base DN for netgroup lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  msgid "Objectclass for netgroups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  msgid "Netgroups members attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  msgid "Netgroup triple attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  msgid "Netgroup UUID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  msgid "Modification time attribute for netgroups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr ""

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr ""

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr ""

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr ""

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr ""

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr ""

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr ""

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr ""

  
@@ -634,27 +682,27 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr ""

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  msgid "Unexpected format of the server credential message."

  msgstr ""

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr ""

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr ""

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr ""

  
@@ -701,24 +749,24 @@

  msgid "Server message: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr "Nouveau mot de passe : "

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr "Retaper le nouveau mot de passe : "

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr "Mot de passe : "

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  #, fuzzy

  msgid "Current Password: "

  msgstr "Nouveau mot de passe : "

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr ""

  

file added
+1167
The added file is too large to be shown here, see it at: po/gu.po
file added
+1167
The added file is too large to be shown here, see it at: po/he.po
file added
+1167
The added file is too large to be shown here, see it at: po/hi.po
file added
+1167
The added file is too large to be shown here, see it at: po/hu.po
file modified
+197 -149
@@ -6,7 +6,7 @@

  msgstr ""

  "Project-Id-Version: sssd\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: 2010-03-09 10:34+0700\n"

  "Last-Translator: Teguh DC <dheche@songolimo.net>\n"

  "Language-Team: Fedora Indonesia <trans-id@lists.fedoraproject.org>\n"
@@ -61,591 +61,639 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:54

- msgid "Enumeration cache timeout length (seconds)"

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

  msgstr ""

  

  #: src/config/SSSDConfig.py:55

- msgid "Entry cache background update timeout length (seconds)"

+ msgid "Enumeration cache timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:56

- msgid "Negative cache timeout length (seconds)"

+ msgid "Entry cache background update timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:57

+ msgid "Negative cache timeout length (seconds)"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:58

  msgid "Users that SSSD should explicitly ignore"

  msgstr "Pengguna yang diabaikan secara eksplisit oleh SSSD"

  

- #: src/config/SSSDConfig.py:58

+ #: src/config/SSSDConfig.py:59

  msgid "Groups that SSSD should explicitly ignore"

  msgstr "Grup yang diabaikan secara eksplisit oleh SSSD"

  

- #: src/config/SSSDConfig.py:59

+ #: src/config/SSSDConfig.py:60

  msgid "Should filtered users appear in groups"

  msgstr "Haruskah pengguna yang disaring muncul dalam grup"

  

- #: src/config/SSSDConfig.py:60

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr "Nilai kolom kata sandi yang harus dikembalikan oleh penyedia NSS"

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

- msgid "How long to allow cached logins between online logins (days)"

+ msgid "The list of shells users are allowed to log in with"

  msgstr ""

  

  #: src/config/SSSDConfig.py:64

- msgid "How many failed logins attempts are allowed when offline"

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

  msgstr ""

  

  #: src/config/SSSDConfig.py:65

  msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

+ msgid "How long to allow cached logins between online logins (days)"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:69

+ msgid "How many failed logins attempts are allowed when offline"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:70

+ msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"

  msgstr ""

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr "Penyedia identitas"

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr "Penyedia otentikasi"

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr "Penyedia kontrol akses"

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr "Penyedia pengubah kata sandi"

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr "ID pengguna minimum"

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr "ID pengguna maksimum"

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr ""

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr ""

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr ""

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr ""

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr "Domain IPA"

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr "Alamat server IPA"

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr "Nama host klien IPA"

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr ""

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr "Alamat server Kerberos"

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr "Realm Kerberos"

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr ""

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr ""

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr ""

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr ""

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr ""

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr ""

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr ""

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr "ldap_uri, URI server LDAP"

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr "Jenis Skema yang digunakan pada server LDAP, rfc2307"

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr "Lamanya waktu untuk mencoba koneksi"

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr "Lamanya waktu untuk mencoba operasi LDAP yang sinkron"

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr "Lamanya waktu antara upaya untuk menyambung kembali saat luring"

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  #, fuzzy

  msgid "File that contains CA certificates"

  msgstr "berkas yang berisi sertifikat CA"

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr ""

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  #, fuzzy

  msgid "File that contains the client certificate"

  msgstr "berkas yang berisi sertifikat CA"

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  #, fuzzy

  msgid "File that contains the client key"

  msgstr "berkas yang berisi sertifikat CA"

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr ""

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr "Membutuhkan verifikasi sertifikat TLS"

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr "Tentukan mekanisme sasl yang digunakan"

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr "Tentukan id otorisasi sasl yang digunakan"

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr "Keytab layanan Kerberos"

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr "Gunakan otentikasi Kerberos untuk koneksi LDAP"

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr ""

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  #, fuzzy

  msgid "Lifetime of TGT for LDAP connection"

  msgstr "Gunakan otentikasi Kerberos untuk koneksi LDAP"

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr ""

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  #, fuzzy

  msgid "Service name for DNS service lookups"

  msgstr "Filter pencarian pengguna"

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  #, fuzzy

  msgid "entryUSN attribute"

  msgstr "Atribut UID"

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  #, fuzzy

  msgid "lastUSN attribute"

  msgstr "Atribut UID"

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr ""

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  #, fuzzy

  msgid "Length of time to wait for a enumeration request"

  msgstr "Lamanya waktu untuk mencoba koneksi"

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  #, fuzzy

  msgid "Length of time between cache cleanups"

  msgstr "Lamanya waktu antara upaya untuk menyambung kembali saat luring"

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  #, fuzzy

  msgid "Require TLS for ID lookups"

  msgstr "Filter pencarian pengguna"

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr "Lingkup pencarian pengguna"

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr "Filter pencarian pengguna"

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr "Objectclass untuk pengguna"

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr "Atribut Nama pengguna"

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr "Atribut UID"

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr "Atribut GID Primer"

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr "Atribut GECOS"

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr "Atribut direktori Home"

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr "Atribut Shell"

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr "Atribut UUID"

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr "Atribut utama pengguna (untuk Kerberos)"

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr "Nama Lengkap"

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr "Atribut memberOf"

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr "Atribut waktu modifikasi"

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  #, fuzzy

  msgid "shadowMin attribute"

  msgstr "Atribut Nama pengguna"

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  #, fuzzy

  msgid "shadowMax attribute"

  msgstr "Atribut Nama pengguna"

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  #, fuzzy

  msgid "shadowWarning attribute"

  msgstr "Atribut Nama pengguna"

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  #, fuzzy

  msgid "shadowInactive attribute"

  msgstr "Atribut Nama pengguna"

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  #, fuzzy

  msgid "shadowExpire attribute"

  msgstr "Atribut Nama pengguna"

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  #, fuzzy

  msgid "shadowFlag attribute"

  msgstr "Atribut Shell"

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr ""

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  #, fuzzy

  msgid "krbPasswordExpiration attribute"

  msgstr "Atribut waktu modifikasi"

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  #, fuzzy

  msgid "accountExpires attribute of AD"

  msgstr "Atribut Nama pengguna"

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  #, fuzzy

  msgid "nsAccountLock attribute"

  msgstr "Atribut Nama pengguna"

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  #, fuzzy

  msgid "Base DN for group lookups"

  msgstr "Filter pencarian pengguna"

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  #, fuzzy

  msgid "Objectclass for groups"

  msgstr "Objectclass untuk pengguna"

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  #, fuzzy

  msgid "Group name"

  msgstr "Grup"

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  #, fuzzy

  msgid "Group password"

  msgstr "Grup"

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  #, fuzzy

  msgid "GID attribute"

  msgstr "Atribut UID"

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  #, fuzzy

  msgid "Group member attribute"

  msgstr "Atribut memberOf"

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  #, fuzzy

  msgid "Group UUID attribute"

  msgstr "Atribut UUID"

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  #, fuzzy

  msgid "Modification time attribute for groups"

  msgstr "Atribut waktu modifikasi"

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr ""

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  #, fuzzy

  msgid "Base DN for netgroup lookups"

  msgstr "Filter pencarian pengguna"

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  #, fuzzy

  msgid "Objectclass for netgroups"

  msgstr "Objectclass untuk pengguna"

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  #, fuzzy

  msgid "Netgroups members attribute"

  msgstr "Atribut memberOf"

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  #, fuzzy

  msgid "Netgroup triple attribute"

  msgstr "Atribut waktu modifikasi"

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  #, fuzzy

  msgid "Netgroup UUID attribute"

  msgstr "Atribut UUID"

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  #, fuzzy

  msgid "Modification time attribute for netgroups"

  msgstr "Atribut waktu modifikasi"

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr ""

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr ""

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr "Daftar pengguna yang diijinkan dalam format yang dipisahkan koma"

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr "Daftar pengguna yang tidak diijinkan dalam format yang dipisahkan koma"

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr "Shell default, /bin/bash"

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr ""

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr ""

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr ""

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr ""

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr ""

  
@@ -668,27 +716,27 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr ""

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  msgid "Unexpected format of the server credential message."

  msgstr ""

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr ""

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr ""

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr ""

  
@@ -735,23 +783,23 @@

  msgid "Server message: "

  msgstr "Pesan server:"

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr "Kata Sandi Baru: "

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr "Masukkan lagi kata sandi baru:"

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr "Kata sandi:"

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  msgid "Current Password: "

  msgstr "Kata sandi saat ini:"

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr ""

  

file added
+1168
The added file is too large to be shown here, see it at: po/is.po
file modified
+197 -149
@@ -8,7 +8,7 @@

  msgstr ""

  "Project-Id-Version: it\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: 2010-04-08 16:50+0200\n"

  "Last-Translator: Guido Grazioli <guido.grazioli@gmail.com>\n"

  "Language-Team: Italian <trans-it@lists.fedoraproject.org>\n"
@@ -65,44 +65,69 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr "Formato compatibile con printf per la visualizzazione di nomi completi"

  

- #: src/config/SSSDConfig.py:54

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:55

  msgid "Enumeration cache timeout length (seconds)"

  msgstr "Durata timeout per la cache enumeration (secondi)"

  

- #: src/config/SSSDConfig.py:55

+ #: src/config/SSSDConfig.py:56

  msgid "Entry cache background update timeout length (seconds)"

  msgstr "Durata timeout aggiornamento cache in background (secondi)"

  

- #: src/config/SSSDConfig.py:56

+ #: src/config/SSSDConfig.py:57

  msgid "Negative cache timeout length (seconds)"

  msgstr "Durata timeout negative cache (secondi)"

  

- #: src/config/SSSDConfig.py:57

+ #: src/config/SSSDConfig.py:58

  msgid "Users that SSSD should explicitly ignore"

  msgstr "Utenti che SSSD dovrebbe ignorare esplicitamente"

  

- #: src/config/SSSDConfig.py:58

+ #: src/config/SSSDConfig.py:59

  msgid "Groups that SSSD should explicitly ignore"

  msgstr "Gruppi che SSSD dovrebbe ignorare esplicitamente"

  

- #: src/config/SSSDConfig.py:59

+ #: src/config/SSSDConfig.py:60

  msgid "Should filtered users appear in groups"

  msgstr "Specifica se mostrare gli utenti filtrati nei gruppi"

  

- #: src/config/SSSDConfig.py:60

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr ""

  "Il valore del campo password che deve essere ritornato dal provider NSS"

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

+ msgid "The list of shells users are allowed to log in with"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:64

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:65

+ msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

  msgid "How long to allow cached logins between online logins (days)"

  msgstr "Per quanto tempo accettare login in cache tra login online (giorni)"

  

- #: src/config/SSSDConfig.py:64

+ #: src/config/SSSDConfig.py:69

  msgid "How many failed logins attempts are allowed when offline"

  msgstr "Numero di tentativi di login falliti quando offline"

  

- #: src/config/SSSDConfig.py:65

+ #: src/config/SSSDConfig.py:70

  msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"
@@ -110,554 +135,577 @@

  "Per quanto tempo (minuti) negare i tentativi di login dopo che "

  "offline_failed_login_attemps è stato raggiunto"

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr "Provider di identità"

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr "Provider di autenticazione"

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr "Provider di access control"

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr "Provider di cambio password"

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr "ID utente minimo"

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr "ID utente massimo"

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr "Consentire l'enumerazione di tutti gli utenti/gruppi"

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr "Salvare in cache le credenziali per login offline"

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr "Salvare gli hash delle password"

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr "Mostrare utenti/gruppi in formato fully-qualified"

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr "Durata timeout elementi in cache (secondi)"

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  "Restringere o preferire una specifica famiglia di indirizzi per l'esecuzione "

  "di lookup DNS"

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  "Per quanto tempo tenere in cache gli elementi dopo un login che ha avuto "

  "successo (giorni)"

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr ""

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr "Dominio IPA"

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr "Indirizzo del server IPA"

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr "Hostname del client IPA"

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr ""

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr "Indirizzo del server Kerberos"

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr "Realm Kerberos"

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr "Timeout di autenticazione"

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr "Directory in cui salvare le credenziali"

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr "Percorso della cache delle credenziali utente"

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr "Percorso del keytab per la validazione delle credenziali"

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr "Abilita la validazione delle credenziali"

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr ""

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr ""

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  "Server dove viene eseguito il servizio di cambio password, se non nel KDC"

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr "ldap_uri, l'indirizzo del server LDAP"

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr "Il base DN predefinito"

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr "Lo Schema Type utilizzato dal server LDAP, rfc2307"

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr "Il bind DN predefinito"

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr "Il tipo di token di autenticazione del bind DN predefinito"

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr "Il token di autenticazione del bind DN predefinito"

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr "Durata del tentativo di connessione"

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr "Durata del tentativo di esecuzione di operazioni LDAP sincrone"

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr "Durata tra tentativi di riconnessione quando offline"

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  #, fuzzy

  msgid "File that contains CA certificates"

  msgstr "file che contiene certificati CA"

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr ""

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  #, fuzzy

  msgid "File that contains the client certificate"

  msgstr "file che contiene certificati CA"

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  #, fuzzy

  msgid "File that contains the client key"

  msgstr "file che contiene certificati CA"

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr ""

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr "Richiedere la verifica del certificato TLS"

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr "Specificare il meccanismo sasl da usare"

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr "Specificare l'id di autorizzazione sasl da usare"

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr "Keytab del servizio Kerberos"

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr "Usare autorizzazione Kerberos per la connessione LDAP"

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr "Seguire i referral LDAP"

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  #, fuzzy

  msgid "Lifetime of TGT for LDAP connection"

  msgstr "Usare autorizzazione Kerberos per la connessione LDAP"

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr ""

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  #, fuzzy

  msgid "Service name for DNS service lookups"

  msgstr "Filtro per i lookup utente"

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  #, fuzzy

  msgid "entryUSN attribute"

  msgstr "Attributo UID"

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  #, fuzzy

  msgid "lastUSN attribute"

  msgstr "Attributo UID"

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr "Durata attesa per le richieste di ricerca"

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  #, fuzzy

  msgid "Length of time to wait for a enumeration request"

  msgstr "Durata attesa per le richieste di ricerca"

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr "Durata tra gli aggiornamenti alle enumeration"

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  #, fuzzy

  msgid "Length of time between cache cleanups"

  msgstr "Durata tra gli aggiornamenti alle enumeration"

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  #, fuzzy

  msgid "Require TLS for ID lookups"

  msgstr "Richiedere TLS per gli ID lookup, false"

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr "Base DN per i lookup utente"

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr "Ambito di applicazione dei lookup utente"

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr "Filtro per i lookup utente"

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr "Objectclass per gli utenti"

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr "Attributo del nome utente"

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr "Attributo UID"

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr "Attributo del GID primario"

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr "Attributo GECOS"

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr "Attributo della home directory"

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr "Attributo della shell"

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr "Attributo UUID"

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr "Attributo user principal (per Kerberos)"

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr "Nome completo"

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr "Attributo memberOf"

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr "Attributo data di modifica"

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  #, fuzzy

  msgid "shadowMin attribute"

  msgstr "Attributo del nome utente"

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  #, fuzzy

  msgid "shadowMax attribute"

  msgstr "Attributo del nome utente"

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  #, fuzzy

  msgid "shadowWarning attribute"

  msgstr "Attributo del nome utente"

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  #, fuzzy

  msgid "shadowInactive attribute"

  msgstr "Attributo del nome utente"

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  #, fuzzy

  msgid "shadowExpire attribute"

  msgstr "Attributo del nome utente"

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  #, fuzzy

  msgid "shadowFlag attribute"

  msgstr "Attributo della shell"

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr ""

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  #, fuzzy

  msgid "krbPasswordExpiration attribute"

  msgstr "Attributo data di modifica"

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  #, fuzzy

  msgid "accountExpires attribute of AD"

  msgstr "Attributo del nome utente"

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  #, fuzzy

  msgid "nsAccountLock attribute"

  msgstr "Attributo del nome utente"

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  #, fuzzy

  msgid "Base DN for group lookups"

  msgstr "Base DN per i lookup utente"

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  #, fuzzy

  msgid "Objectclass for groups"

  msgstr "Objectclass per gli utenti"

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  #, fuzzy

  msgid "Group name"

  msgstr "Gruppi"

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  #, fuzzy

  msgid "Group password"

  msgstr "Gruppi"

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  #, fuzzy

  msgid "GID attribute"

  msgstr "Attributo UID"

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  #, fuzzy

  msgid "Group member attribute"

  msgstr "Attributo memberOf"

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  #, fuzzy

  msgid "Group UUID attribute"

  msgstr "Attributo UUID"

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  #, fuzzy

  msgid "Modification time attribute for groups"

  msgstr "Attributo data di modifica"

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr ""

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  #, fuzzy

  msgid "Base DN for netgroup lookups"

  msgstr "Base DN per i lookup utente"

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  #, fuzzy

  msgid "Objectclass for netgroups"

  msgstr "Objectclass per gli utenti"

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  #, fuzzy

  msgid "Netgroups members attribute"

  msgstr "Attributo memberOf"

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  #, fuzzy

  msgid "Netgroup triple attribute"

  msgstr "Attributo data di modifica"

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  #, fuzzy

  msgid "Netgroup UUID attribute"

  msgstr "Attributo UUID"

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  #, fuzzy

  msgid "Modification time attribute for netgroups"

  msgstr "Attributo data di modifica"

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr "Politica per controllare la scadenza della password"

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr ""

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr "Lista separata da virgola degli utenti abilitati"

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr "Lista separata da virgola degli utenti non abilitati"

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr "Shell predefinita, /bin/bash"

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr "Base delle home directory"

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr "Il nome della libreria NSS da usare"

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr "Stack PAM da usare"

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr "Esegui come demone (default)"

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr "Esegui interattivamente (non come demone)"

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr "Specificare un file di configurazione specifico"

  
@@ -679,28 +727,28 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr "Dominio del provider di informazioni (obbligatorio)"

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  #, fuzzy

  msgid "Unexpected format of the server credential message."

  msgstr "Percorso della cache delle credenziali utente"

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr ""

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr ""

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr ""

  
@@ -747,23 +795,23 @@

  msgid "Server message: "

  msgstr "Messaggio del server:"

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr "Nuova password: "

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr "Conferma nuova password: "

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr "Password: "

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  msgid "Current Password: "

  msgstr "Password corrente: "

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr "Password scaduta. Cambiare la password ora."

  

file modified
+204 -157
@@ -1,22 +1,21 @@

- # translation of sss_daemon_ja.po to Japanese

+ # SOME DESCRIPTIVE TITLE.

  # Copyright (C) YEAR Red Hat, Inc.

  # This file is distributed under the same license as the PACKAGE package.

  #

- # Noriko Mizumoto <noriko@fedoraproject.org>, 2009.

  msgid ""

  msgstr ""

- "Project-Id-Version: sss_daemon_ja\n"

+ "Project-Id-Version: SSSD\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

- "PO-Revision-Date: 2009-11-18 09:48+1000\n"

- "Last-Translator: Noriko Mizumoto <noriko@fedoraproject.org>\n"

- "Language-Team: Japanese <fedora-trans-ja@redhat.com>\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

+ "PO-Revision-Date: 2011-05-27 19:57+0000\n"

+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"

+ "Language-Team: Japanese (http://www.transifex.net/projects/p/fedora/team/"

+ "ja/)\n"

  "Language: ja\n"

  "MIME-Version: 1.0\n"

  "Content-Type: text/plain; charset=UTF-8\n"

  "Content-Transfer-Encoding: 8bit\n"

- "X-Generator: KBabel 1.11.4\n"

- "Plural-Forms:  nplurals=1; plural=0;\n"

+ "Plural-Forms: nplurals=1; plural=0\n"

  

  #: src/config/SSSDConfig.py:39

  msgid "Set the verbosity of the debug logging"
@@ -62,558 +61,606 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:54

- msgid "Enumeration cache timeout length (seconds)"

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

  msgstr ""

  

  #: src/config/SSSDConfig.py:55

- msgid "Entry cache background update timeout length (seconds)"

+ msgid "Enumeration cache timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:56

- msgid "Negative cache timeout length (seconds)"

+ msgid "Entry cache background update timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:57

- msgid "Users that SSSD should explicitly ignore"

+ msgid "Negative cache timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:58

- msgid "Groups that SSSD should explicitly ignore"

+ msgid "Users that SSSD should explicitly ignore"

  msgstr ""

  

  #: src/config/SSSDConfig.py:59

- msgid "Should filtered users appear in groups"

+ msgid "Groups that SSSD should explicitly ignore"

  msgstr ""

  

  #: src/config/SSSDConfig.py:60

+ msgid "Should filtered users appear in groups"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr ""

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

- msgid "How long to allow cached logins between online logins (days)"

+ msgid "The list of shells users are allowed to log in with"

  msgstr ""

  

  #: src/config/SSSDConfig.py:64

- msgid "How many failed logins attempts are allowed when offline"

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

  msgstr ""

  

  #: src/config/SSSDConfig.py:65

  msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

+ msgid "How long to allow cached logins between online logins (days)"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:69

+ msgid "How many failed logins attempts are allowed when offline"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:70

+ msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"

  msgstr ""

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr ""

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr ""

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr ""

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr ""

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr ""

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr ""

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr ""

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr ""

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr ""

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr ""

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr ""

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr ""

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr ""

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr ""

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr ""

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr ""

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr ""

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr ""

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr ""

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr ""

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr ""

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr ""

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  msgid "File that contains CA certificates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr ""

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  msgid "File that contains the client certificate"

  msgstr ""

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  msgid "File that contains the client key"

  msgstr ""

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr ""

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr ""

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr ""

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr ""

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  msgid "Lifetime of TGT for LDAP connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr ""

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  msgid "Service name for DNS service lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  msgid "entryUSN attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  msgid "lastUSN attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr ""

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  msgid "Length of time to wait for a enumeration request"

  msgstr ""

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  msgid "Length of time between cache cleanups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  msgid "Require TLS for ID lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  msgid "shadowMin attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  msgid "shadowMax attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  msgid "shadowWarning attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  msgid "shadowInactive attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  msgid "shadowExpire attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  msgid "shadowFlag attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr ""

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  msgid "krbPasswordExpiration attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  msgid "accountExpires attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  msgid "nsAccountLock attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  msgid "Base DN for group lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  msgid "Objectclass for groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  msgid "Group name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  msgid "Group password"

  msgstr ""

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  msgid "GID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  msgid "Group member attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  msgid "Group UUID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  msgid "Modification time attribute for groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr ""

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  msgid "Base DN for netgroup lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  msgid "Objectclass for netgroups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  msgid "Netgroups members attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  msgid "Netgroup triple attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  msgid "Netgroup UUID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  msgid "Modification time attribute for netgroups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr ""

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr ""

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr ""

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr ""

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr ""

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr ""

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr ""

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr ""

  
@@ -635,27 +682,27 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr ""

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  msgid "Unexpected format of the server credential message."

  msgstr ""

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr ""

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr ""

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr ""

  
@@ -701,23 +748,23 @@

  msgid "Server message: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  msgid "Current Password: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr ""

  

file added
+1167
The added file is too large to be shown here, see it at: po/ja_JP.po
file added
+1168
The added file is too large to be shown here, see it at: po/kn.po
file added
+1167
The added file is too large to be shown here, see it at: po/ko.po
file added
+1169
The added file is too large to be shown here, see it at: po/lt.po
file added
+1168
The added file is too large to be shown here, see it at: po/lt_LT.po
file added
+1168
The added file is too large to be shown here, see it at: po/mai.po
file added
+1167
The added file is too large to be shown here, see it at: po/ml.po
file added
+1168
The added file is too large to be shown here, see it at: po/mr.po
file added
+1167
The added file is too large to be shown here, see it at: po/nb.po
file added
+1167
The added file is too large to be shown here, see it at: po/nds.po
file modified
+197 -149
@@ -7,7 +7,7 @@

  msgstr ""

  "Project-Id-Version: sssd.master.sss_daemon\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: 2009-11-19 12:19+0100\n"

  "Last-Translator: Richard van der Luit <nippur@fedoraproject.org>\n"

  "Language-Team: Dutch <nl@li.org>\n"
@@ -62,558 +62,606 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:54

- msgid "Enumeration cache timeout length (seconds)"

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

  msgstr ""

  

  #: src/config/SSSDConfig.py:55

- msgid "Entry cache background update timeout length (seconds)"

+ msgid "Enumeration cache timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:56

- msgid "Negative cache timeout length (seconds)"

+ msgid "Entry cache background update timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:57

- msgid "Users that SSSD should explicitly ignore"

+ msgid "Negative cache timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:58

- msgid "Groups that SSSD should explicitly ignore"

+ msgid "Users that SSSD should explicitly ignore"

  msgstr ""

  

  #: src/config/SSSDConfig.py:59

- msgid "Should filtered users appear in groups"

+ msgid "Groups that SSSD should explicitly ignore"

  msgstr ""

  

  #: src/config/SSSDConfig.py:60

+ msgid "Should filtered users appear in groups"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr ""

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

- msgid "How long to allow cached logins between online logins (days)"

+ msgid "The list of shells users are allowed to log in with"

  msgstr ""

  

  #: src/config/SSSDConfig.py:64

- msgid "How many failed logins attempts are allowed when offline"

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

  msgstr ""

  

  #: src/config/SSSDConfig.py:65

  msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

+ msgid "How long to allow cached logins between online logins (days)"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:69

+ msgid "How many failed logins attempts are allowed when offline"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:70

+ msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"

  msgstr ""

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr ""

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr ""

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr ""

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr ""

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr ""

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr ""

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr ""

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr ""

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr ""

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr ""

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr ""

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr ""

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr ""

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr ""

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr ""

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr ""

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr ""

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr ""

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr ""

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr ""

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr ""

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr ""

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  msgid "File that contains CA certificates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr ""

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  msgid "File that contains the client certificate"

  msgstr ""

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  msgid "File that contains the client key"

  msgstr ""

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr ""

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr ""

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr ""

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr ""

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  msgid "Lifetime of TGT for LDAP connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr ""

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  msgid "Service name for DNS service lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  msgid "entryUSN attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  msgid "lastUSN attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr ""

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  msgid "Length of time to wait for a enumeration request"

  msgstr ""

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  msgid "Length of time between cache cleanups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  msgid "Require TLS for ID lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  msgid "shadowMin attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  msgid "shadowMax attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  msgid "shadowWarning attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  msgid "shadowInactive attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  msgid "shadowExpire attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  msgid "shadowFlag attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr ""

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  msgid "krbPasswordExpiration attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  msgid "accountExpires attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  msgid "nsAccountLock attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  msgid "Base DN for group lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  msgid "Objectclass for groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  msgid "Group name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  msgid "Group password"

  msgstr ""

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  msgid "GID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  msgid "Group member attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  msgid "Group UUID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  msgid "Modification time attribute for groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr ""

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  msgid "Base DN for netgroup lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  msgid "Objectclass for netgroups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  msgid "Netgroups members attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  msgid "Netgroup triple attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  msgid "Netgroup UUID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  msgid "Modification time attribute for netgroups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr ""

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr ""

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr ""

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr ""

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr ""

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr ""

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr ""

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr ""

  
@@ -635,27 +683,27 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr ""

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  msgid "Unexpected format of the server credential message."

  msgstr ""

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr ""

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr ""

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr ""

  
@@ -702,24 +750,24 @@

  msgid "Server message: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr "Nieuw Wachtwoord: "

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr "Voer nieuw wachtwoord nogmaals in: "

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr "Wachtwoord: "

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  #, fuzzy

  msgid "Current Password: "

  msgstr "Nieuw Wachtwoord: "

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr ""

  

file added
+1167
The added file is too large to be shown here, see it at: po/nn.po
file added
+1167
The added file is too large to be shown here, see it at: po/or.po
file added
+1167
The added file is too large to be shown here, see it at: po/pa.po
file modified
+197 -149
@@ -5,7 +5,7 @@

  msgstr ""

  "Project-Id-Version: pl\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: 2011-01-23 17:33+0100\n"

  "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"

  "Language-Team: Polish <trans-pl@lists.fedoraproject.org>\n"
@@ -58,45 +58,70 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr "Format zgodny z printf do wyświetlania pełnych nazw"

  

- #: src/config/SSSDConfig.py:54

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:55

  msgid "Enumeration cache timeout length (seconds)"

  msgstr "Czas oczekiwania pamięci podręcznej wyliczania (sekundy)"

  

- #: src/config/SSSDConfig.py:55

+ #: src/config/SSSDConfig.py:56

  msgid "Entry cache background update timeout length (seconds)"

  msgstr "Czas oczekiwania aktualizacji tła pamięci podręcznej wpisów (sekundy)"

  

- #: src/config/SSSDConfig.py:56

+ #: src/config/SSSDConfig.py:57

  msgid "Negative cache timeout length (seconds)"

  msgstr "Ujemny czas oczekiwania pamięci podręcznej (sekundy)"

  

- #: src/config/SSSDConfig.py:57

+ #: src/config/SSSDConfig.py:58

  msgid "Users that SSSD should explicitly ignore"

  msgstr "Użytkownicy, którzy powinni być bezpośrednio ignorowani przez SSSD"

  

- #: src/config/SSSDConfig.py:58

+ #: src/config/SSSDConfig.py:59

  msgid "Groups that SSSD should explicitly ignore"

  msgstr "Grupy, które powinny być bezpośrednio ignorowane przez SSSD"

  

- #: src/config/SSSDConfig.py:59

+ #: src/config/SSSDConfig.py:60

  msgid "Should filtered users appear in groups"

  msgstr "Czy filtrowani użytkownicy powinni pojawiać się w grupach"

  

- #: src/config/SSSDConfig.py:60

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr "Wartość pola hasła, jaką dostawca NSS powinien zwrócić"

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

+ msgid "The list of shells users are allowed to log in with"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:64

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:65

+ msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

  msgid "How long to allow cached logins between online logins (days)"

  msgstr ""

  "Jak długo umożliwiać logowania w pamięci podręcznej między logowaniami w "

  "trybie online (dni)"

  

- #: src/config/SSSDConfig.py:64

+ #: src/config/SSSDConfig.py:69

  msgid "How many failed logins attempts are allowed when offline"

  msgstr "Ile nieudanych prób zalogowania jest dozwolonych w trybie offline"

  

- #: src/config/SSSDConfig.py:65

+ #: src/config/SSSDConfig.py:70

  msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"
@@ -104,533 +129,556 @@

  "Ile czasu (minut) nie pozwalać na zalogowanie po osiągnięciu "

  "offline_failed_login_attempts"

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  "Jaki rodzaj komunikatów wyświetlać użytkownikowi podczas uwierzytelniania"

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  "Ile sekund zatrzymać informacje o tożsamości w pamięci podręcznej dla żądań "

  "PAM"

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr "Ile dni przed wygaśnięciem hasła wyświetlić ostrzeżenie"

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr "Dostawca tożsamości"

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr "Dostawca uwierzytelniania"

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr "Dostawca kontroli dostępu"

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr "Dostawca zmiany hasła"

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr "Minimalny identyfikator użytkownika"

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr "Maksymalny identyfikator użytkownika"

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr "Włącza wyliczanie wszystkich użytkowników/grup"

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr "Dane uwierzytelniające pamięci podręcznej dla logowań w trybie offline"

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr "Przechowuje mieszanie haseł"

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr "Wyświetla użytkowników/grupy w pełnej formie"

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr "Czas oczekiwania pamięci podręcznej wpisów (sekundy)"

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  "Ogranicza lub preferuje podaną rodzinę adresów podczas wykonywania "

  "wyszukiwań DNS"

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  "Jak długo utrzymywać wpisy logowania w pamięci podręcznej po ostatnim udanym "

  "zalogowaniu (dni)"

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  "Jak długo czekać na odpowiedzi od serwera DNS podczas rozwiązywania serwerów "

  "(sekundy)"

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr "Część domeny zapytania DNS wykrywania usługi"

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr "Domena IPA"

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr "Adres serwera IPA"

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr "Nazwa komputera klienta IPA"

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  "Czy automatycznie aktualizować wpis DNS klienta w oprogramowaniu FreeIPA"

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  "Interfejs, którego adres IP powinien być używany do dynamicznych "

  "aktualizacji DNS"

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr "Wyszukiwanie podstawy pod kątem obiektów związanych z HBAC"

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr "Adres serwera Kerberos"

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr "Obszar Kerberos"

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr "Czas oczekiwania na uwierzytelnienie"

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr ""

  "Katalog do przechowywania pamięci podręcznych danych uwierzytelniających"

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr "Położenie pamięci podręcznej danych uwierzytelniających użytkownika"

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr "Położenie tablicy kluczy do sprawdzania danych uwierzytelniających"

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr "Włącza sprawdzanie danych uwierzytelniających"

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  "Przechowuje hasło, jeśli w trybie offline do późniejszego uwierzytelnienia w "

  "trybie online"

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr "Odnawialny czas trwania TGT"

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr "Czas trwania TGT"

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr "Czas między dwoma sprawdzaniami odnowy"

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr "Włącza FAST"

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  "Serwer, w którym jest uruchomiona usługa zmiany haseł, jeśli nie znajduje "

  "się w KDC"

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr "ldap_uri, adres URI serwera LDAP"

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr "Domyślna podstawowa DN"

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr "Typ Schema do użycia na serwerze LDAP, RFC2307"

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr "Domyślne DN dowiązania"

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr "Typ tokenu uwierzytelniania domyślnego DN dowiązania"

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr "Token uwierzytelniania domyślnego DN dowiązania"

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr "Czas do próby połączenia"

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr "Czas do próby synchronicznych działań LDAP"

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr "Czas między próbami ponownego połączenia w trybie offline"

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr "Użycie tylko małych znaków w nazwach obszarów"

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  msgid "File that contains CA certificates"

  msgstr "Plik zawierający certyfikaty CA"

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr "Ścieżka do katalogu certyfikatów CA"

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  msgid "File that contains the client certificate"

  msgstr "Plik zawierający certyfikat klienta"

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  msgid "File that contains the client key"

  msgstr "Plik zawierający klucz klienta"

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr "Lista możliwych zestawów szyfrów"

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr "Wymaga sprawdzenia certyfikatu TLS"

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr "Podaje używany mechanizm SASL"

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr "Podaje używany identyfikator upoważnienia SASL"

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr "Tablica kluczy usługi Kerberos"

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr "Używa uwierzytelniania Kerberos dla połączenia LDAP"

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr "Podąża za odsyłaniami LDAP"

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  msgid "Lifetime of TGT for LDAP connection"

  msgstr "Czas trwania TGT dla połączenia LDAP"

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr "Jak wskazywać aliasy"

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  msgid "Service name for DNS service lookups"

  msgstr "Nazwa usługi do wyszukiwań usługi DNS"

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  msgid "entryUSN attribute"

  msgstr "Atrybut entryUSN"

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  msgid "lastUSN attribute"

  msgstr "Atrybut lastUSN"

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr "Czas oczekiwania na żądanie wyszukiwania"

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  msgid "Length of time to wait for a enumeration request"

  msgstr "Czas oczekiwania na żądanie wyliczenia"

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr "Czas między aktualizacjami wyliczania"

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  msgid "Length of time between cache cleanups"

  msgstr "Czas między czyszczeniem pamięci podręcznej"

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  msgid "Require TLS for ID lookups"

  msgstr "Wymaga TLS dla wyszukiwania identyfikatorów"

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr "Podstawowe DN dla wyszukiwania użytkowników"

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr "Zakres wyszukiwania użytkowników"

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr "Filtruje wyszukiwania użytkowników"

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr "Klasa obiektów dla użytkowników"

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr "Atrybut nazwy użytkownika"

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr "Atrybut UID"

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr "Pierwszy atrybut GID"

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr "Atrybut GECOS"

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr "Atrybut katalogu domowego"

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr "Atrybut powłoki"

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr "Atrybut UUID"

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr "Atrybut głównego użytkownika (dla Kerberos)"

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr "Imię i nazwisko"

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr "Atrybut memberOf"

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr "Atrybut czasu modyfikacji"

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr "Atrybut shadowLastChange"

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  msgid "shadowMin attribute"

  msgstr "Atrybut shadowMin"

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  msgid "shadowMax attribute"

  msgstr "Atrybut shadowMax"

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  msgid "shadowWarning attribute"

  msgstr "Atrybut shadowWarning"

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  msgid "shadowInactive attribute"

  msgstr "Atrybut shadowInactive"

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  msgid "shadowExpire attribute"

  msgstr "Atrybut shadowExpire"

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  msgid "shadowFlag attribute"

  msgstr "Atrybut shadowFlag"

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr "Atrybut zawierający listę upoważnionych usług PAM"

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr "Atrybut krbLastPwdChange"

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  msgid "krbPasswordExpiration attribute"

  msgstr "Atrybut krbPasswordExpiration"

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr "Atrybut wskazujący, czy polityki haseł po stronie serwera są aktywne"

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  msgid "accountExpires attribute of AD"

  msgstr "Atrybut accountExpires AD"

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr "Atrybut userAccountControl AD"

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  msgid "nsAccountLock attribute"

  msgstr "Atrybut nsAccountLock"

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  msgid "Base DN for group lookups"

  msgstr "Podstawowe DN dla wyszukiwania grup"

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  msgid "Objectclass for groups"

  msgstr "Klasa obiektów dla grup"

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  msgid "Group name"

  msgstr "Nazwa grupy"

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  msgid "Group password"

  msgstr "Hasło grupy"

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  msgid "GID attribute"

  msgstr "Atrybut GID"

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  msgid "Group member attribute"

  msgstr "Atrybut elementu grupy"

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  msgid "Group UUID attribute"

  msgstr "Atrybut UUID grupy"

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  msgid "Modification time attribute for groups"

  msgstr "Atrybut czasu modyfikacji grup"

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr "Maksymalny poziom zagnieżdżenia, jaki usługa SSSD będzie używała"

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  msgid "Base DN for netgroup lookups"

  msgstr "Podstawowe DN dla wyszukiwania grupy sieciowej"

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  msgid "Objectclass for netgroups"

  msgstr "Klasa obiektów dla grup sieciowych"

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr "Nazwa grupy sieciowej"

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  msgid "Netgroups members attribute"

  msgstr "Atrybut elementów grupy sieciowej"

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  msgid "Netgroup triple attribute"

  msgstr "Potrójny atrybut grupy sieciowej"

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  msgid "Netgroup UUID attribute"

  msgstr "Atrybut UUID grupy sieciowej"

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  msgid "Modification time attribute for netgroups"

  msgstr "Atrybut czasu modyfikacji grup sieciowych"

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr "Polityka do oszacowania wygaszenia hasła"

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr "Filtr LDAP do określenia uprawnień dostępu"

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr "Które atrybuty powinny być używane do sprawdzenia, czy konto wygasło"

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr "Które reguły powinny być używane do sprawdzania kontroli dostępu"

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr "Adres URI serwera LDAP, gdzie zmiany hasła są dozwolone"

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr "Nazwa usługi DNS serwera zmiany hasła LDAP"

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr "Lista dozwolonych użytkowników oddzielonych przecinkami"

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr "Lista zabronionych użytkowników oddzielonych przecinkami"

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr "Domyślna powłoka, /bin/bash"

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr "Podstawa katalogów domowych"

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr "Nazwa używanej biblioteki NSS"

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr "Używany stos PAM"

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr "Uruchamia jako demon (domyślnie)"

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr "Uruchamia interaktywnie (nie jako demon)"

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr "Podaje niedomyślny plik konfiguracji"

  
@@ -652,27 +700,27 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr "Domena dostawcy informacji (wymagane)"

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr "Uprawnione gniazdo posiada błędnego właściciela lub uprawnienia."

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr "Publiczne gniazdo posiada błędnego właściciela lub uprawnienia"

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  msgid "Unexpected format of the server credential message."

  msgstr "Nieoczekiwany format komunikatu uwierzytelniającego serwera."

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr "SSSD nie zostało uruchomione w trybie roota."

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr "Wystąpił błąd, ale nie odnaleziono jego opisu."

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr "Nieoczekiwany błąd podczas wyszukiwania opisu błędu"

  
@@ -718,23 +766,23 @@

  msgid "Server message: "

  msgstr "Komunikat serwera: "

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr "Nowe hasło: "

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr "Proszę ponownie podać nowe hasło: "

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr "Hasło: "

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  msgid "Current Password: "

  msgstr "Bieżące hasło: "

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr "Hasło wygasło. Proszę je zmienić teraz."

  

file modified
+197 -149
@@ -6,7 +6,7 @@

  msgstr ""

  "Project-Id-Version: sssd.master.sss_daemon\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: 2010-02-23 13:59+0100\n"

  "Last-Translator: Rui Gouveia <rui.gouveia@gmail.com>\n"

  "Language-Team: fedora-trans-pt@redhat.com\n"
@@ -63,46 +63,71 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr "Formato compatível com o printf para apresentar nomes completos"

  

- #: src/config/SSSDConfig.py:54

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:55

  msgid "Enumeration cache timeout length (seconds)"

  msgstr "Validade da cache de enumeração (segundos)"

  

- #: src/config/SSSDConfig.py:55

+ #: src/config/SSSDConfig.py:56

  msgid "Entry cache background update timeout length (seconds)"

  msgstr "Validade da actualização da cache em segundo plano (segundos)"

  

- #: src/config/SSSDConfig.py:56

+ #: src/config/SSSDConfig.py:57

  msgid "Negative cache timeout length (seconds)"

  msgstr "Validade da cache negativa (segundos)"

  

- #: src/config/SSSDConfig.py:57

+ #: src/config/SSSDConfig.py:58

  msgid "Users that SSSD should explicitly ignore"

  msgstr "Utilizadores que o SSSD devem explicitamente ignorar"

  

- #: src/config/SSSDConfig.py:58

+ #: src/config/SSSDConfig.py:59

  msgid "Groups that SSSD should explicitly ignore"

  msgstr "Grupos que o SSSD devem explicitamente ignorar"

  

- #: src/config/SSSDConfig.py:59

+ #: src/config/SSSDConfig.py:60

  msgid "Should filtered users appear in groups"

  msgstr "Devem os utilizadores filtrados aparecer em grupos"

  

- #: src/config/SSSDConfig.py:60

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr "O valor do campo da senha que o fornecedor NSS deve retornar"

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

+ msgid "The list of shells users are allowed to log in with"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:64

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:65

+ msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

  msgid "How long to allow cached logins between online logins (days)"

  msgstr ""

  "Durante quanto tempo devem ser permitidas as caches de sessões entre sessões "

  "online (dias)"

  

- #: src/config/SSSDConfig.py:64

+ #: src/config/SSSDConfig.py:69

  msgid "How many failed logins attempts are allowed when offline"

  msgstr ""

  "Quantas tentativas falhadas de inicio de sessão são permitidas quando offline"

  

- #: src/config/SSSDConfig.py:65

+ #: src/config/SSSDConfig.py:70

  msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"
@@ -110,553 +135,576 @@

  "Quanto tempo (minutos) para negar a sessão após "

  "offline_failed_login_attempts ter sido atingido"

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr "Fornecedor de identidade"

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr "Fornecedor de autenticação"

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr "Fornecedor de controle de acesso"

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr "Fornecedor de Alteração de Senha"

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr "ID de utilizador mínimo"

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr "ID de utilizador máximo"

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr "Permitir enumeração de todos os utilizadores/grupos"

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr "Efectuar cache de credenciais para sessões em modo desligado"

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr "Guardar hashes da senha"

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr "Apresentar utilizadores/grupos na forma completa"

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr "Validade da cache (segundos)"

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  "Restringir ou preferir famílias de endereços especificas quando efectua "

  "consultas DNS"

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  "Durante quanto tempo devem ser permitidas as caches de sessões entre sessões "

  "bem sucedidas (dias)"

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr ""

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr "Domínio IPA"

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr "Endereço do servidor IPA"

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr "Nome da máquina do cliente IPA"

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr ""

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr "Endereço do servidor Kerberos"

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr "Reino Kerberos"

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr "Tempo de expiração da autenticação"

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr "Directório para armazenar as caches de credenciais"

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr "Localização da cache de credenciais dos utilizadores"

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr "Localização da tabela de chaves (keytab) para validar credenciais"

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr "Activar validação de credenciais"

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr ""

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr ""

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  "Servidor onde está em execução o serviço de alteração de senha, se não "

  "coincide com o KDC"

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr "ldap_uri, O URI do servidor LDAP"

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr "A base DN por omissão"

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr "O tipo de Schema em utilização no servidor LDAP, rfc2307"

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr "O DN por omissão para a ligação"

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr "O tipo de token de autenticação do bind DN por omissão"

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr "O token de autenticação do bind DN por omissão"

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr "Período de tempo para tentar ligação"

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr "Tempo de espera para tentar operações LDAP síncronas"

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr "Tempo de espera entre tentativas para re-conectar quando desligado"

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  msgid "File that contains CA certificates"

  msgstr "Ficheiro que contêm os certificados CA"

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr "Caminho para o directório do certificado CA"

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  #, fuzzy

  msgid "File that contains the client certificate"

  msgstr "Ficheiro que contêm os certificados CA"

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  #, fuzzy

  msgid "File that contains the client key"

  msgstr "Ficheiro que contêm os certificados CA"

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr ""

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr "Obriga a verificação de certificados TLS"

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr "Especificar mecanismo sasl a utilizar"

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr "Especifique o id sasl para utilizar na autorização"

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr "Separador chave do serviço Kerberos"

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr "Utilizar autenticação Kerberos para ligações LDAP"

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr "Seguir os referrals LDAP"

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  #, fuzzy

  msgid "Lifetime of TGT for LDAP connection"

  msgstr "Utilizar autenticação Kerberos para ligações LDAP"

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr ""

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  #, fuzzy

  msgid "Service name for DNS service lookups"

  msgstr "Filtro para as pesquisas do utilizador"

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  #, fuzzy

  msgid "entryUSN attribute"

  msgstr "Atributo UID"

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  #, fuzzy

  msgid "lastUSN attribute"

  msgstr "Atributo UID"

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr "Tempo de espera por um pedido de pesquisa"

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  #, fuzzy

  msgid "Length of time to wait for a enumeration request"

  msgstr "Tempo de espera por um pedido de pesquisa"

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr "Período de tempo entre enumeração de actualizações"

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  #, fuzzy

  msgid "Length of time between cache cleanups"

  msgstr "Período de tempo entre enumeração de actualizações"

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  msgid "Require TLS for ID lookups"

  msgstr "Requer TLS para consultas de ID"

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr "DN base para pesquisa de utilizadores"

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr "Âmbito das pesquisas do utilizador"

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr "Filtro para as pesquisas do utilizador"

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr "Objectclass para utilizadores"

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr "Atributo do nome do utilizador"

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr "Atributo UID"

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr "Atributo GID primário"

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr "Atributo GECOS"

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr "Atributo da pasta pessoal"

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr "Atributo da Shell"

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr "Atributo UUID"

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr "Atributo principal do utilizador (para Kerberos)"

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr "Nome Completo"

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr "Atributo memberOf"

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr "Atributo da alteração da data"

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  #, fuzzy

  msgid "shadowMin attribute"

  msgstr "Atributo do nome do utilizador"

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  #, fuzzy

  msgid "shadowMax attribute"

  msgstr "Atributo do nome do utilizador"

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  #, fuzzy

  msgid "shadowWarning attribute"

  msgstr "Atributo do nome do utilizador"

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  #, fuzzy

  msgid "shadowInactive attribute"

  msgstr "Atributo do nome do utilizador"

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  #, fuzzy

  msgid "shadowExpire attribute"

  msgstr "Atributo do nome do utilizador"

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  #, fuzzy

  msgid "shadowFlag attribute"

  msgstr "Atributo da Shell"

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr ""

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  #, fuzzy

  msgid "krbPasswordExpiration attribute"

  msgstr "Atributo da alteração da data"

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  #, fuzzy

  msgid "accountExpires attribute of AD"

  msgstr "Atributo do nome do utilizador"

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  #, fuzzy

  msgid "nsAccountLock attribute"

  msgstr "Atributo do nome do utilizador"

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  #, fuzzy

  msgid "Base DN for group lookups"

  msgstr "DN base para pesquisa de utilizadores"

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  #, fuzzy

  msgid "Objectclass for groups"

  msgstr "Objectclass para utilizadores"

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  #, fuzzy

  msgid "Group name"

  msgstr "Grupos"

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  #, fuzzy

  msgid "Group password"

  msgstr "Grupos"

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  #, fuzzy

  msgid "GID attribute"

  msgstr "Atributo UID"

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  #, fuzzy

  msgid "Group member attribute"

  msgstr "Atributo memberOf"

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  #, fuzzy

  msgid "Group UUID attribute"

  msgstr "Atributo UUID"

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  #, fuzzy

  msgid "Modification time attribute for groups"

  msgstr "Atributo da alteração da data"

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr ""

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  #, fuzzy

  msgid "Base DN for netgroup lookups"

  msgstr "DN base para pesquisa de utilizadores"

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  #, fuzzy

  msgid "Objectclass for netgroups"

  msgstr "Objectclass para utilizadores"

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  #, fuzzy

  msgid "Netgroups members attribute"

  msgstr "Atributo memberOf"

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  #, fuzzy

  msgid "Netgroup triple attribute"

  msgstr "Atributo da alteração da data"

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  #, fuzzy

  msgid "Netgroup UUID attribute"

  msgstr "Atributo UUID"

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  #, fuzzy

  msgid "Modification time attribute for netgroups"

  msgstr "Atributo da alteração da data"

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr "Politica para avaliar a expiração da senha"

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr ""

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr "Lista de utilizadores autorizados separados por vírgulas"

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr "Lista de utilizadores não autorizados separados por vírgulas"

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr "Shell pré-definida, /bin/bash"

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr "Directório base para as pastas pessoais"

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr "O nome da biblioteca NSS a utilizar"

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr "Stack PAM a utilizar"

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr "Tornar-se num serviço (omissão)"

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr "Executar interactivamente (não como serviço)"

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr "Especificar um ficheiro de configuração não standard"

  
@@ -678,28 +726,28 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr "Domínio do fornecedor de informação (obrigatório)"

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  #, fuzzy

  msgid "Unexpected format of the server credential message."

  msgstr "Localização da cache de credenciais dos utilizadores"

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr ""

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr ""

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr ""

  
@@ -746,23 +794,23 @@

  msgid "Server message: "

  msgstr "Mensagem do Servidor: "

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr "Nova Senha: "

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr "Digite a senha novamente: "

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr "Senha: "

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  msgid "Current Password: "

  msgstr "Senha actual: "

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr "A senha expirou. Altere a sua senha agora."

  

file added
+1167
The added file is too large to be shown here, see it at: po/pt_BR.po
file added
+1169
The added file is too large to be shown here, see it at: po/ro.po
file modified
+197 -149
@@ -7,7 +7,7 @@

  msgstr ""

  "Project-Id-Version: ru\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: 2010-04-07 21:39+0300\n"

  "Last-Translator: Dmitry Drozdov <dmi3652@gmail.com>\n"

  "Language-Team: Russian <fedora-trans-ru@redhat.com>\n"
@@ -63,45 +63,70 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr "Отображать полные имена в формате, совместимом с printf"

  

- #: src/config/SSSDConfig.py:54

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:55

  msgid "Enumeration cache timeout length (seconds)"

  msgstr "Длина тайм-аута кэша перечисления (в секундах)"

  

- #: src/config/SSSDConfig.py:55

+ #: src/config/SSSDConfig.py:56

  msgid "Entry cache background update timeout length (seconds)"

  msgstr "Тайм-аут фонового обновления элемента списка кэша (в секундах)"

  

- #: src/config/SSSDConfig.py:56

+ #: src/config/SSSDConfig.py:57

  msgid "Negative cache timeout length (seconds)"

  msgstr "Отрицательная длина тайм-аута кэша (в секундах)"

  

- #: src/config/SSSDConfig.py:57

+ #: src/config/SSSDConfig.py:58

  msgid "Users that SSSD should explicitly ignore"

  msgstr "Пользователи, которых SSSD должен явно игнорировать "

  

- #: src/config/SSSDConfig.py:58

+ #: src/config/SSSDConfig.py:59

  msgid "Groups that SSSD should explicitly ignore"

  msgstr "Группы, которые SSSD должен явно игнорировать "

  

- #: src/config/SSSDConfig.py:59

+ #: src/config/SSSDConfig.py:60

  msgid "Should filtered users appear in groups"

  msgstr "Должны ли отфильтрованные пользователи появляться в группах"

  

- #: src/config/SSSDConfig.py:60

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr "Значение поля пароля, которое должен вернуть поставщик NSS"

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

+ msgid "The list of shells users are allowed to log in with"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:64

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:65

+ msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

  msgid "How long to allow cached logins between online logins (days)"

  msgstr ""

  "Разрешённый интервал кэшированных входов между интерактивными входами (в "

  "днях)"

  

- #: src/config/SSSDConfig.py:64

+ #: src/config/SSSDConfig.py:69

  msgid "How many failed logins attempts are allowed when offline"

  msgstr "Разрешённое количество неудачных попыток неинтерактивного входа"

  

- #: src/config/SSSDConfig.py:65

+ #: src/config/SSSDConfig.py:70

  msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"
@@ -109,555 +134,578 @@

  "Временной интервал (в минутах), в течение которого будет запрещён вход после "

  "достижения offline_failed_login_attempts"

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr "Поставщик данных для идентификации"

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr "Поставщик данных для проверки подлинности"

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr "Поставщик данных для контроля доступа"

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr "Поставщик операции смены пароля"

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr "Минимальный ID пользователя"

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr "Максимальный ID пользователя"

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr "Включить перечисление всех пользователей/групп"

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr "Кэшировать учётные данные для неинтерактивного входа"

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr "Хранить хеши паролей"

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr "Отображать пользователей/группы в полной форме"

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr "Тайм-аут элемента списка кэша (в секундах)"

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  "Ограничивать или предпочитать определённое семейство адресов при выполнении "

  "запросов DNS"

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  "Как долго хранить кэшированные элементы списка после последнего успешного "

  "входа (в днях)"

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr ""

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr "IPA-домен"

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr "адрес сервера IPA"

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr "имя узла клиента IPA"

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr ""

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr "Имя сервера Kerberos"

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr "Область действия Kerberos"

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr "Тайм-аут проверки подлинности"

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr "Каталог для хранения кэшей учётных данных"

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr "Расположения кэша учётных данных пользователей"

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr "Расположение keytab-файла для проверки учётных данных"

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr "Включить проверку учётных данных"

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr ""

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr ""

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr "Сервер, на котором запущена служба смены пароля (если не на KDC)"

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr "ldap_uri, URI сервера LDAP "

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr "Base DN по умолчанию"

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr "Тип схемы, используемой на LDAP-сервере, rfc2307"

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr "Bind DN по умолчанию"

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr "Тип маркера проверки подлинности для bind DN по умолчанию"

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr "Маркер проверки подлинности для bind DN по умолчанию"

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr "Временной интервал для попытки соединения"

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr "Временной интервал для попытки синхронизации операций LDAP"

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr ""

  "Временной интервал между попытками возобновления соединения в автономного "

  "режиме"

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  #, fuzzy

  msgid "File that contains CA certificates"

  msgstr "Файл, содержащий CA сертификаты"

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr ""

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  #, fuzzy

  msgid "File that contains the client certificate"

  msgstr "Файл, содержащий CA сертификаты"

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  #, fuzzy

  msgid "File that contains the client key"

  msgstr "Файл, содержащий CA сертификаты"

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr ""

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr "Требуется проверка сертификата TLS"

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr "Укажите механизм sasl"

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr "Укажите идентификатор авторизации sasl"

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr "Keytab-файл службы Kerberos"

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr "Использовать проверку подлинности Kerberos для LDAP-соединения"

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr "Следовать ссылкам LDAP"

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  #, fuzzy

  msgid "Lifetime of TGT for LDAP connection"

  msgstr "Использовать проверку подлинности Kerberos для LDAP-соединения"

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr ""

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  #, fuzzy

  msgid "Service name for DNS service lookups"

  msgstr "Фильтр поиска"

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  #, fuzzy

  msgid "entryUSN attribute"

  msgstr "Атрибут «UID»"

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  #, fuzzy

  msgid "lastUSN attribute"

  msgstr "Атрибут «UID»"

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr "Временной интервал, в течение которого ожидать поискового запроса"

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  #, fuzzy

  msgid "Length of time to wait for a enumeration request"

  msgstr "Временной интервал, в течение которого ожидать поискового запроса"

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr "Временной интервал между обновлениями перечисления"

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  #, fuzzy

  msgid "Length of time between cache cleanups"

  msgstr "Временной интервал между обновлениями перечисления"

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  #, fuzzy

  msgid "Require TLS for ID lookups"

  msgstr "Требуется TLS для поиска ID"

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr "Base DN для поиска"

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr "Глубина поиска"

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr "Фильтр поиска"

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr "Objectclass для пользователей"

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr "Атрибут «username»"

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr "Атрибут «UID»"

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr "Атрибут «primary GID»"

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr "Атрибут «GECOS»"

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr "Атрибут домашнего каталога"

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr "Атрибут оболочки"

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr "Атрибут «UUID»"

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr "Атрибут участника-пользователя (для Kerberos)"

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr "Полное имя"

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr "Атрибут memberOf"

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr "Атрибут времени изменения"

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  #, fuzzy

  msgid "shadowMin attribute"

  msgstr "Атрибут «username»"

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  #, fuzzy

  msgid "shadowMax attribute"

  msgstr "Атрибут «username»"

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  #, fuzzy

  msgid "shadowWarning attribute"

  msgstr "Атрибут «username»"

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  #, fuzzy

  msgid "shadowInactive attribute"

  msgstr "Атрибут «username»"

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  #, fuzzy

  msgid "shadowExpire attribute"

  msgstr "Атрибут «username»"

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  #, fuzzy

  msgid "shadowFlag attribute"

  msgstr "Атрибут оболочки"

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr ""

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  #, fuzzy

  msgid "krbPasswordExpiration attribute"

  msgstr "Атрибут времени изменения"

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  #, fuzzy

  msgid "accountExpires attribute of AD"

  msgstr "Атрибут «username»"

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  #, fuzzy

  msgid "nsAccountLock attribute"

  msgstr "Атрибут «username»"

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  #, fuzzy

  msgid "Base DN for group lookups"

  msgstr "Base DN для поиска"

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  #, fuzzy

  msgid "Objectclass for groups"

  msgstr "Objectclass для пользователей"

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  #, fuzzy

  msgid "Group name"

  msgstr "Группы"

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  #, fuzzy

  msgid "Group password"

  msgstr "Группы"

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  #, fuzzy

  msgid "GID attribute"

  msgstr "Атрибут «UID»"

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  #, fuzzy

  msgid "Group member attribute"

  msgstr "Атрибут memberOf"

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  #, fuzzy

  msgid "Group UUID attribute"

  msgstr "Атрибут «UUID»"

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  #, fuzzy

  msgid "Modification time attribute for groups"

  msgstr "Атрибут времени изменения"

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr ""

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  #, fuzzy

  msgid "Base DN for netgroup lookups"

  msgstr "Base DN для поиска"

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  #, fuzzy

  msgid "Objectclass for netgroups"

  msgstr "Objectclass для пользователей"

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  #, fuzzy

  msgid "Netgroups members attribute"

  msgstr "Атрибут memberOf"

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  #, fuzzy

  msgid "Netgroup triple attribute"

  msgstr "Атрибут времени изменения"

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  #, fuzzy

  msgid "Netgroup UUID attribute"

  msgstr "Атрибут «UUID»"

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  #, fuzzy

  msgid "Modification time attribute for netgroups"

  msgstr "Атрибут времени изменения"

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr "Политика вычисления окончания срока действия пароля"

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr ""

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr "Разделённый запятыми список разрешённых пользователей"

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr "Разделённый запятыми список запрещённых пользователей"

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr "Оболочка по умолчанию, /bin/bash"

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr "Место для домашних каталогов"

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr "Имя используемой библиотеки NSS"

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr "Используемый стек PAM"

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr "Запускаться в качестве службы (по умолчанию)"

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr "Запускаться интерактивно (не службой)"

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr "Указать файл конфигурации"

  
@@ -679,28 +727,28 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr "Домен поставщика информации (обязательный)"

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  #, fuzzy

  msgid "Unexpected format of the server credential message."

  msgstr "Расположения кэша учётных данных пользователей"

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr ""

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr ""

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr ""

  
@@ -747,23 +795,23 @@

  msgid "Server message: "

  msgstr "Сообщение сервера:"

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr "Новый пароль:"

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr "Введите новый пароль ещё раз:"

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr "Пароль:"

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  msgid "Current Password: "

  msgstr "Текущий пароль:"

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr "Срок действия пароля истёк. Необходимо сейчас изменить ваш пароль."

  

file added
+1166
The added file is too large to be shown here, see it at: po/sk.po
file added
+1168
The added file is too large to be shown here, see it at: po/sl.po
file added
+1168
The added file is too large to be shown here, see it at: po/sq.po
file added
+1168
The added file is too large to be shown here, see it at: po/sr.po
file modified
+197 -149
@@ -8,7 +8,7 @@

  msgstr ""

  "Project-Id-Version: PACKAGE VERSION\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"

  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"

  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -61,558 +61,606 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:54

- msgid "Enumeration cache timeout length (seconds)"

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

  msgstr ""

  

  #: src/config/SSSDConfig.py:55

- msgid "Entry cache background update timeout length (seconds)"

+ msgid "Enumeration cache timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:56

- msgid "Negative cache timeout length (seconds)"

+ msgid "Entry cache background update timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:57

- msgid "Users that SSSD should explicitly ignore"

+ msgid "Negative cache timeout length (seconds)"

  msgstr ""

  

  #: src/config/SSSDConfig.py:58

- msgid "Groups that SSSD should explicitly ignore"

+ msgid "Users that SSSD should explicitly ignore"

  msgstr ""

  

  #: src/config/SSSDConfig.py:59

- msgid "Should filtered users appear in groups"

+ msgid "Groups that SSSD should explicitly ignore"

  msgstr ""

  

  #: src/config/SSSDConfig.py:60

+ msgid "Should filtered users appear in groups"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr ""

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

- msgid "How long to allow cached logins between online logins (days)"

+ msgid "The list of shells users are allowed to log in with"

  msgstr ""

  

  #: src/config/SSSDConfig.py:64

- msgid "How many failed logins attempts are allowed when offline"

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

  msgstr ""

  

  #: src/config/SSSDConfig.py:65

  msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

+ msgid "How long to allow cached logins between online logins (days)"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:69

+ msgid "How many failed logins attempts are allowed when offline"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:70

+ msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"

  msgstr ""

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr ""

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr ""

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr ""

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr ""

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr ""

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr ""

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr ""

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr ""

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr ""

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr ""

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr ""

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr ""

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr ""

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr ""

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr ""

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr ""

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr ""

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr ""

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr ""

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr ""

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr ""

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr ""

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr ""

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  msgid "File that contains CA certificates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr ""

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  msgid "File that contains the client certificate"

  msgstr ""

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  msgid "File that contains the client key"

  msgstr ""

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr ""

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr ""

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr ""

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr ""

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  msgid "Lifetime of TGT for LDAP connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr ""

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  msgid "Service name for DNS service lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  msgid "entryUSN attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  msgid "lastUSN attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr ""

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  msgid "Length of time to wait for a enumeration request"

  msgstr ""

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  msgid "Length of time between cache cleanups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  msgid "Require TLS for ID lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  msgid "shadowMin attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  msgid "shadowMax attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  msgid "shadowWarning attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  msgid "shadowInactive attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  msgid "shadowExpire attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  msgid "shadowFlag attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr ""

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  msgid "krbPasswordExpiration attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  msgid "accountExpires attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  msgid "nsAccountLock attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  msgid "Base DN for group lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  msgid "Objectclass for groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  msgid "Group name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  msgid "Group password"

  msgstr ""

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  msgid "GID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  msgid "Group member attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  msgid "Group UUID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  msgid "Modification time attribute for groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr ""

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  msgid "Base DN for netgroup lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  msgid "Objectclass for netgroups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  msgid "Netgroups members attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  msgid "Netgroup triple attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  msgid "Netgroup UUID attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  msgid "Modification time attribute for netgroups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr ""

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr ""

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr ""

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr ""

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr ""

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr ""

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr ""

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr ""

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr ""

  
@@ -634,27 +682,27 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr ""

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  msgid "Unexpected format of the server credential message."

  msgstr ""

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr ""

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr ""

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr ""

  
@@ -700,23 +748,23 @@

  msgid "Server message: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  msgid "Current Password: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr ""

  

file modified
+197 -149
@@ -8,7 +8,7 @@

  msgstr ""

  "Project-Id-Version: sss_server\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: 2009-12-30 17:58+0100\n"

  "Last-Translator: Göran Uddeborg <goeran@uddeborg.se>\n"

  "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
@@ -61,594 +61,642 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr "Printf-kompatibla format för att visa fullständigt kvalificerade namn"

  

- #: src/config/SSSDConfig.py:54

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:55

  msgid "Enumeration cache timeout length (seconds)"

  msgstr "Tidsgränslängd för uppräkningscache (sekunder)"

  

- #: src/config/SSSDConfig.py:55

+ #: src/config/SSSDConfig.py:56

  msgid "Entry cache background update timeout length (seconds)"

  msgstr "Tidsgränslängd för bakgrundsuppdateringar av postcache (sekunder)"

  

- #: src/config/SSSDConfig.py:56

+ #: src/config/SSSDConfig.py:57

  msgid "Negative cache timeout length (seconds)"

  msgstr "Tidsgränslängd för negativ cache (sekunder)"

  

- #: src/config/SSSDConfig.py:57

+ #: src/config/SSSDConfig.py:58

  msgid "Users that SSSD should explicitly ignore"

  msgstr "Användare som SSSD uttryckligen skall bortse ifrån"

  

- #: src/config/SSSDConfig.py:58

+ #: src/config/SSSDConfig.py:59

  msgid "Groups that SSSD should explicitly ignore"

  msgstr "Grupper som SSSD uttryckligen skall bortse ifrån"

  

- #: src/config/SSSDConfig.py:59

+ #: src/config/SSSDConfig.py:60

  msgid "Should filtered users appear in groups"

  msgstr "Skall filtrerade användare förekomma i grupper"

  

- #: src/config/SSSDConfig.py:60

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr "Värdet på lösenordfältet som NSS-leverantörer skall returnera"

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

+ msgid "The list of shells users are allowed to log in with"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:64

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:65

+ msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

  msgid "How long to allow cached logins between online logins (days)"

  msgstr ""

  "Hur länge sparade inloggningar tillåts mellan online-inloggningar (dagar)"

  

- #: src/config/SSSDConfig.py:64

+ #: src/config/SSSDConfig.py:69

  msgid "How many failed logins attempts are allowed when offline"

  msgstr ""

  

- #: src/config/SSSDConfig.py:65

+ #: src/config/SSSDConfig.py:70

  msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"

  msgstr ""

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr "Identifiera leverantör"

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr "Autentiseringsleverantör"

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr "Leverantör av åtkomstkontroll"

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr "Leverantör av lösenordsändringar"

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr "Minsta användar-ID"

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr "Största användar-ID"

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr "Aktivera uppräkning av alla användare/grupper"

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr "Cache-kreditiv för frånkopplad inloggning"

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr "Lagra lösenords-kontrollsummor"

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr "Visa användare/grupper i fullständigt kvalificerat format"

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr "Tidsgränslängd för postcache (sekunder)"

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  #, fuzzy

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  "Hur länge sparade inloggningar tillåts mellan online-inloggningar (dagar)"

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr ""

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr "IPA-domän"

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr "IPA-serveradress"

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr "IPA-klienvärdnamn"

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr ""

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr "Kerberosserveradress"

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr "Kerberosrike"

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr "Autentiseringstidsgräns"

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr "Katalog att lagra kreditiv-cachar i"

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr "Plats för användarens kreditiv-cache"

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr "Plats för nyckeltabellen för att validera kreditiv"

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr "Aktivera validering av kreditiv"

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr ""

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr ""

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr "ldap_uri, URI:n för LDAP-servern"

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr "Standard bas-DN"

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr "Schematypen som används i LDAP-servern, rfc2307"

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr "Standard bindnings-DN"

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr "Typen på autenticerings-token för standard bindnings-DN"

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr "Autenticerings-token för standard bindnings-DN"

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr "Tidslängd att försöka ansluta"

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr "Tidslängd att försök synkrona LDAP-operationer"

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr "Tidslängd mellan försök att återansluta under frånkoppling"

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  #, fuzzy

  msgid "File that contains CA certificates"

  msgstr "fil som innehåller CA-certifikat"

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr ""

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  #, fuzzy

  msgid "File that contains the client certificate"

  msgstr "fil som innehåller CA-certifikat"

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  #, fuzzy

  msgid "File that contains the client key"

  msgstr "fil som innehåller CA-certifikat"

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr ""

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr "Kräv TLS-certifikatverifiering"

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr "Ange sasl-mekanismen att använda"

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr "Ange sasl-auktorisering-id att använda"

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr "Kerberostjänstens nyckeltabell"

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr "Avnänd Kerberosautenticering för LDAP-anslutning"

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr ""

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  #, fuzzy

  msgid "Lifetime of TGT for LDAP connection"

  msgstr "Avnänd Kerberosautenticering för LDAP-anslutning"

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr ""

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  #, fuzzy

  msgid "Service name for DNS service lookups"

  msgstr "Filter för användaruppslagningar"

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  #, fuzzy

  msgid "entryUSN attribute"

  msgstr "UID-attribut"

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  #, fuzzy

  msgid "lastUSN attribute"

  msgstr "UID-attribut"

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr "Tidslängd att vänta på en sökbegäran"

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  #, fuzzy

  msgid "Length of time to wait for a enumeration request"

  msgstr "Tidslängd att vänta på en sökbegäran"

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr "Tidslängd mellan uppräkningsuppdateringar"

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  #, fuzzy

  msgid "Length of time between cache cleanups"

  msgstr "Tidslängd mellan uppräkningsuppdateringar"

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  #, fuzzy

  msgid "Require TLS for ID lookups"

  msgstr "Kräv TLS för ID-uppslagningar, falsk"

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr "Bas-DN för användaruppslagningar"

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr "Omfång av användaruppslagningar"

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr "Filter för användaruppslagningar"

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr "Objektklass för användare"

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr "Användarnamnsattribut"

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr "UID-attribut"

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr "Primärt GID-attribut"

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr "GECOS-attribut"

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr "Hemkatalogattribut"

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr "Skalattribut"

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr "UUID-attribut"

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr "Användarens huvudmansattribut (för Kerberos)"

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr "Fullständigt namn"

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr "medlemAv-attribut"

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr "Modifieringstidsattribut"

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  #, fuzzy

  msgid "shadowMin attribute"

  msgstr "Användarnamnsattribut"

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  #, fuzzy

  msgid "shadowMax attribute"

  msgstr "Användarnamnsattribut"

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  #, fuzzy

  msgid "shadowWarning attribute"

  msgstr "Användarnamnsattribut"

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  #, fuzzy

  msgid "shadowInactive attribute"

  msgstr "Användarnamnsattribut"

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  #, fuzzy

  msgid "shadowExpire attribute"

  msgstr "Användarnamnsattribut"

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  #, fuzzy

  msgid "shadowFlag attribute"

  msgstr "Skalattribut"

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr ""

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  #, fuzzy

  msgid "krbPasswordExpiration attribute"

  msgstr "Modifieringstidsattribut"

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  #, fuzzy

  msgid "accountExpires attribute of AD"

  msgstr "Användarnamnsattribut"

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  #, fuzzy

  msgid "nsAccountLock attribute"

  msgstr "Användarnamnsattribut"

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  #, fuzzy

  msgid "Base DN for group lookups"

  msgstr "Bas-DN för användaruppslagningar"

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  #, fuzzy

  msgid "Objectclass for groups"

  msgstr "Objektklass för användare"

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  #, fuzzy

  msgid "Group name"

  msgstr "Grupper"

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  #, fuzzy

  msgid "Group password"

  msgstr "Grupper"

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  #, fuzzy

  msgid "GID attribute"

  msgstr "UID-attribut"

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  #, fuzzy

  msgid "Group member attribute"

  msgstr "medlemAv-attribut"

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  #, fuzzy

  msgid "Group UUID attribute"

  msgstr "UUID-attribut"

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  #, fuzzy

  msgid "Modification time attribute for groups"

  msgstr "Modifieringstidsattribut"

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr ""

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  #, fuzzy

  msgid "Base DN for netgroup lookups"

  msgstr "Bas-DN för användaruppslagningar"

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  #, fuzzy

  msgid "Objectclass for netgroups"

  msgstr "Objektklass för användare"

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  #, fuzzy

  msgid "Netgroups members attribute"

  msgstr "medlemAv-attribut"

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  #, fuzzy

  msgid "Netgroup triple attribute"

  msgstr "Modifieringstidsattribut"

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  #, fuzzy

  msgid "Netgroup UUID attribute"

  msgstr "UUID-attribut"

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  #, fuzzy

  msgid "Modification time attribute for netgroups"

  msgstr "Modifieringstidsattribut"

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr "Policy för att utvärdera utgång av lösenord"

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr ""

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr "Standardskal, /bin/bash"

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr "Bas för hemkataloger"

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr "Namnet på NSS-biblioteket att använda"

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr "PAM-stack att använda"

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr ""

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr ""

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr ""

  
@@ -671,28 +719,28 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr ""

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  #, fuzzy

  msgid "Unexpected format of the server credential message."

  msgstr "Plats för användarens kreditiv-cache"

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr ""

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr ""

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr ""

  
@@ -740,24 +788,24 @@

  msgid "Server message: "

  msgstr ""

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr "Nytt lösenord: "

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr "Skriv det nya lösenordet igen: "

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr "Lösenord: "

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  #, fuzzy

  msgid "Current Password: "

  msgstr "Nytt lösenord: "

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr ""

  

file added
+1167
The added file is too large to be shown here, see it at: po/ta.po
file added
+1167
The added file is too large to be shown here, see it at: po/ta_IN.po
file added
+1167
The added file is too large to be shown here, see it at: po/te.po
file added
+1167
The added file is too large to be shown here, see it at: po/tg.po
file added
+1168
The added file is too large to be shown here, see it at: po/tr.po
file modified
+197 -149
@@ -6,7 +6,7 @@

  msgstr ""

  "Project-Id-Version: \n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: 2011-01-23 10:08+0200\n"

  "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"

  "Language-Team: Ukrainian <translation@linux.org.ua>\n"
@@ -62,45 +62,70 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr "Сумісний з printf формат показу повних назв"

  

- #: src/config/SSSDConfig.py:54

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:55

  msgid "Enumeration cache timeout length (seconds)"

  msgstr "Тривалість часу очікування на дані кешу нумерування (у секундах)"

  

- #: src/config/SSSDConfig.py:55

+ #: src/config/SSSDConfig.py:56

  msgid "Entry cache background update timeout length (seconds)"

  msgstr "Час очікування на фонове оновлення кешу записів (у секундах)"

  

- #: src/config/SSSDConfig.py:56

+ #: src/config/SSSDConfig.py:57

  msgid "Negative cache timeout length (seconds)"

  msgstr "Від’ємний час очікування на дані з кешу (у секундах)"

  

- #: src/config/SSSDConfig.py:57

+ #: src/config/SSSDConfig.py:58

  msgid "Users that SSSD should explicitly ignore"

  msgstr "Користувачі, яких SSSD має явно ігнорувати"

  

- #: src/config/SSSDConfig.py:58

+ #: src/config/SSSDConfig.py:59

  msgid "Groups that SSSD should explicitly ignore"

  msgstr "Групи користувачів, які SSSD має явно ігнорувати"

  

- #: src/config/SSSDConfig.py:59

+ #: src/config/SSSDConfig.py:60

  msgid "Should filtered users appear in groups"

  msgstr "Чи слід показувати відфільтрованих користувачів у групах"

  

- #: src/config/SSSDConfig.py:60

+ #: src/config/SSSDConfig.py:61

  msgid "The value of the password field the NSS provider should return"

  msgstr "Значення поля пароля, яке має повертати постачальник даних NSS"

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

+ msgid "The list of shells users are allowed to log in with"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:64

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:65

+ msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

  msgid "How long to allow cached logins between online logins (days)"

  msgstr ""

  "Тривалість зберігання кешованих реєстраційних даних між входами до системи "

  "(у днях)"

  

- #: src/config/SSSDConfig.py:64

+ #: src/config/SSSDConfig.py:69

  msgid "How many failed logins attempts are allowed when offline"

  msgstr "Макс. дозволена кількість помилкових спроб входу у автономному режимі"

  

- #: src/config/SSSDConfig.py:65

+ #: src/config/SSSDConfig.py:70

  msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"
@@ -108,536 +133,559 @@

  "Тривалість (у хвилинах) заборони входу після досягнення значення "

  "offline_failed_login_attempts"

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr "Тип повідомлень, які буде показано користувачеві під час розпізнавання"

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  "Тривалість (у секундах) зберігання даних щодо розпізнавання у кеші для "

  "запитів PAM"

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  "Визначає кількість днів між днем, коли має бути показано попередження, і "

  "днем, коли завершиться строк дії пароля"

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr "Служба профілів"

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr "Служба розпізнавання"

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr "Служба керування доступом"

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr "Служба зміни паролів"

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr "Мін. ідентифікатор користувача"

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr "Макс. ідентифікатор користувача"

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr "Увімкнути нумерацію всіх користувачів/груп"

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr "Кешувати реєстраційні дані для автономного входу"

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  msgid "Store password hashes"

  msgstr "Зберігати хеші паролів"

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr "Показувати записи користувачів/груп повністю"

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr "Тривалість кешування записів (у секундах)"

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  "Обмежити або надавати перевагу певному сімейству адрес під час виконання "

  "пошуків DNS"

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  "Тривалість зберігання кешованих записів після останнього успішного входу (у "

  "днях)"

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  "Тривалість очікування на відповідь від DNS під час визначення адрес серверів "

  "(у секундах)"

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr "Частина запиту щодо виявлення служби DNS, пов’язана з доменом"

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr "Домен IPA"

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr "Адреса сервера IPA"

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr "Назва вузла клієнта IPA"

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  "Визначає, чи слід автоматично оновлювати запис DNS клієнтського вузла у "

  "FreeIPA"

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  "Інтерфейс, чию адресу IP має бути використано для динамічних оновлень DNS"

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr "Шукати у базі об’єкти, пов’язані з HBAC"

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr "Адреса сервера Kerberos"

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr "Область Kerberos"

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr "Час очікування на розпізнавання"

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr "Каталог, де зберігатиметься кеш реєстраційних даних"

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr "Адреса кешу реєстраційних даних користувача"

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr "Адреса таблиці ключів для перевірки реєстраційних даних"

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr "Увімкнути перевірку реєстраційних даних"

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr "Зберігати пароль у автономному режимі для розпізнавання у мережі"

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr "Поновлюваний строк дії TGT"

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr "Строк дії TGT"

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr "Граничний час між двома перевірками для поновлення"

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr "Вмикає FAST"

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  "Сервер, на якому запущено службу зміни паролів, якщо такий не вдасться "

  "виявити у KDC"

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr "ldap_uri, адреса URI сервера LDAP"

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr "Типова базова назва домену"

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr "Тип схеми, використаний на сервері LDAP, rfc2307"

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr "Типова назва домену прив’язки"

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr "Тип розпізнавання для типової назви сервера прив’язки"

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr "Лексема розпізнавання типової назви сервера прив’язки"

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr "Проміжок часу між спробами встановлення з’єднання"

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr "Проміжок часу між спробами виконання синхронних операцій LDAP"

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr ""

  "Проміжок часу між повторними спробами встановлення з’єднання у автономному "

  "режимі"

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr "Використовувати для назв областей лише великі літери"

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  msgid "File that contains CA certificates"

  msgstr "Файл, що містить сертифікати CA"

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr "Шлях до каталогу сертифікатів CA"

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  msgid "File that contains the client certificate"

  msgstr "Файл, що містить клієнтський сертифікат"

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  msgid "File that contains the client key"

  msgstr "Файл, що містить клієнтський ключ"

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr "Показати список можливих інструментів шифрування"

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr "Потрібна перевірка сертифіката TLS"

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr "Вкажіть механізм SASL, який слід використовувати"

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr "Вкажіть ідентифікатор уповноваження SASL, який слід використовувати"

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr "Таблиця ключів служби Kerberos"

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr "Розпізнавання Kerberos для з’єднання LDAP"

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr "Переходити за посиланнями LDAP"

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  msgid "Lifetime of TGT for LDAP connection"

  msgstr "Строк дії TGT для з’єднання LDAP"

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr "Спосіб розіменування псевдонімів"

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  msgid "Service name for DNS service lookups"

  msgstr "Назва служби для пошуків за допомогою служби DNS"

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  msgid "entryUSN attribute"

  msgstr "Атрибут entryUSN"

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  msgid "lastUSN attribute"

  msgstr "Атрибут lastUSN"

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr "Тривалість очікування на дані запиту пошуку"

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  msgid "Length of time to wait for a enumeration request"

  msgstr "Тривалість очікування на дані запиту щодо переліку"

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  msgid "Length of time between enumeration updates"

  msgstr "Проміжок часу між оновленнями нумерації"

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  msgid "Length of time between cache cleanups"

  msgstr "Проміжок часу між спорожненнями кешу"

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  msgid "Require TLS for ID lookups"

  msgstr "Вимагати TLS для пошуків ідентифікаторів"

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr "Базова назва домену для пошуків користувачів"

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr "Діапазон пошуків користувачів"

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr "Фільтр пошуку користувачів"

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr "Клас об’єктів для користувачів"

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr "Атрибут імені користувача"

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  msgid "UID attribute"

  msgstr "Атрибут UID"

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  msgid "Primary GID attribute"

  msgstr "Головний атрибут GID"

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  msgid "GECOS attribute"

  msgstr "Атрибут GECOS"

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  msgid "Home directory attribute"

  msgstr "Атрибут домашнього каталогу"

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  msgid "Shell attribute"

  msgstr "Атрибут оболонки"

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  msgid "UUID attribute"

  msgstr "Атрибут UUID"

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  msgid "User principal attribute (for Kerberos)"

  msgstr "Атрибут реєстраційного запису користувача (для Kerberos)"

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr "Повне ім'я"

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr "Атрибут memberOf"

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  msgid "Modification time attribute"

  msgstr "Атрибут часу зміни"

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr "Атрибут shadowLastChange"

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  msgid "shadowMin attribute"

  msgstr "Атрибут shadowMin"

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  msgid "shadowMax attribute"

  msgstr "Атрибут shadowMax"

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  msgid "shadowWarning attribute"

  msgstr "Атрибут shadowWarning"

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  msgid "shadowInactive attribute"

  msgstr "Атрибут shadowInactive"

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  msgid "shadowExpire attribute"

  msgstr "Атрибут shadowExpire"

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  msgid "shadowFlag attribute"

  msgstr "Атрибут shadowFlag"

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr "Атрибути зі списком уповноважених служб PAM"

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr "Атрибут krbLastPwdChange"

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  msgid "krbPasswordExpiration attribute"

  msgstr "Атрибут krbPasswordExpiration"

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  "Атрибут, що відповідає за активізацію правил обробки паролів на боці сервера"

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  msgid "accountExpires attribute of AD"

  msgstr "Атрибут accountExpires AD"

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr "Атрибут userAccountControl AD"

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  msgid "nsAccountLock attribute"

  msgstr "Атрибут nsAccountLock"

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  msgid "Base DN for group lookups"

  msgstr "Базова назва домену для пошуків груп"

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  msgid "Objectclass for groups"

  msgstr "Клас об’єктів для груп"

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  msgid "Group name"

  msgstr "Назва групи"

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  msgid "Group password"

  msgstr "Пароль групи"

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  msgid "GID attribute"

  msgstr "Атрибут GID"

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  msgid "Group member attribute"

  msgstr "Атрибут членства у групі"

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  msgid "Group UUID attribute"

  msgstr "Атрибут UUID групи"

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  msgid "Modification time attribute for groups"

  msgstr "Атрибут часу зміни для груп"

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr "Максимальний рівень вкладеності, який використовуватиме SSSD"

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  msgid "Base DN for netgroup lookups"

  msgstr "Базова назва домену для пошуків груп у мережі"

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  msgid "Objectclass for netgroups"

  msgstr "Клас об’єктів для груп у мережі"

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr "Назва мережевої групи"

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  msgid "Netgroups members attribute"

  msgstr "Атрибут членства у групах у мережі"

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  msgid "Netgroup triple attribute"

  msgstr "Атрибут трійки груп у мережі"

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  msgid "Netgroup UUID attribute"

  msgstr "Атрибут UUID груп у мережі"

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  msgid "Modification time attribute for netgroups"

  msgstr "Атрибут часу зміни для мережевих груп"

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr "Правила оцінки завершення строку дії пароля"

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr "Фільтр LDAP для визначення прав доступу"

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  "Атрибути які слід використовувати для визначення чинності облікового запису"

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  "Правила, які має бути використано для визначення достатності прав доступу"

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr "Адреса на сервері LDAP, для якої можливі зміни паролів"

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr "Назва у службі DNS сервера зміни паролів LDAP"

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr "Відокремлений комами список дозволених користувачів"

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr "Відокремлений комами список заборонених користувачів"

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr "Типова оболонка, /bin/bash"

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  msgid "Base for home directories"

  msgstr "Базова адреса домашніх каталогів"

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr "Назва бібліотеки NSS, яку слід використовувати"

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr "Стек PAM, який слід використовувати"

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr "Запуститися фонову службу (типова поведінка)"

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr "Запустити у інтерактивному режимі (без фонової служби)"

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr "Вказати нетиповий файл налаштувань"

  
@@ -659,27 +707,27 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr "Домен надання відомостей (обов’язковий)"

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr "У привілейованого сокета помилковий власник або права доступу."

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr "У відкритого сокета помилковий власник або права доступу."

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  msgid "Unexpected format of the server credential message."

  msgstr "Некоректний формат повідомлення щодо реєстраційних даних сервера."

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr "SSSD запущено не від імені користувача root."

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr "Сталася помилка, але не вдалося знайти її опису."

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr "Неочікувана помилка під час пошуку опису помилки"

  
@@ -725,23 +773,23 @@

  msgid "Server message: "

  msgstr "Повідомлення сервера: "

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr "Новий пароль: "

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr "Ще раз введіть новий пароль: "

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr "Пароль: "

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  msgid "Current Password: "

  msgstr "Поточний пароль: "

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr "Строк дії пароля вичерпано. Змініть ваш пароль."

  

file added
+1167
The added file is too large to be shown here, see it at: po/ur.po
file added
+1168
The added file is too large to be shown here, see it at: po/vi.po
file added
+1167
The added file is too large to be shown here, see it at: po/vi_VN.po
file added
+1168
The added file is too large to be shown here, see it at: po/zh_CN.po
file added
+1167
The added file is too large to be shown here, see it at: po/zh_HK.po
file modified
+197 -149
@@ -7,7 +7,7 @@

  msgstr ""

  "Project-Id-Version: sss_daemon 1.1.0\n"

  "Report-Msgid-Bugs-To: sssd-devel@lists.fedorahosted.org\n"

- "POT-Creation-Date: 2011-01-21 16:56-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:03-0500\n"

  "PO-Revision-Date: 2010-03-22 22:00+0800\n"

  "Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"

  "Language-Team: Fedora-trans-zh_tw <trans-zh_tw@lists.fedoraproject.org>\n"
@@ -68,596 +68,644 @@

  msgid "Printf-compatible format for displaying fully-qualified names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:54

+ #: src/config/SSSDConfig.py:52

+ msgid ""

+ "Directory on the filesystem where SSSD should store Kerberos replay cache "

+ "files."

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:55

  #, fuzzy

  msgid "Enumeration cache timeout length (seconds)"

  msgstr "列表快取的逾時長度(秒)"

  

- #: src/config/SSSDConfig.py:55

+ #: src/config/SSSDConfig.py:56

  msgid "Entry cache background update timeout length (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:56

+ #: src/config/SSSDConfig.py:57

  msgid "Negative cache timeout length (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:57

+ #: src/config/SSSDConfig.py:58

  msgid "Users that SSSD should explicitly ignore"

  msgstr "SSSD 應該明確忽略的使用者"

  

- #: src/config/SSSDConfig.py:58

+ #: src/config/SSSDConfig.py:59

  msgid "Groups that SSSD should explicitly ignore"

  msgstr "SSSD 應該明確忽略的群組"

  

- #: src/config/SSSDConfig.py:59

+ #: src/config/SSSDConfig.py:60

  msgid "Should filtered users appear in groups"

  msgstr "過濾的使用者是否應該顯現在群組內"

  

- #: src/config/SSSDConfig.py:60

+ #: src/config/SSSDConfig.py:61

  #, fuzzy

  msgid "The value of the password field the NSS provider should return"

  msgstr "NSS 提供者應該回傳的密碼的值"

  

+ #: src/config/SSSDConfig.py:62

+ msgid "Override homedir value from the identity provider with this value"

+ msgstr ""

+ 

  #: src/config/SSSDConfig.py:63

- msgid "How long to allow cached logins between online logins (days)"

+ msgid "The list of shells users are allowed to log in with"

  msgstr ""

  

  #: src/config/SSSDConfig.py:64

+ msgid ""

+ "The list of shells that will be vetoed, and replaced with the fallback shell"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:65

+ msgid ""

+ "If a shell stored in central directory is allowed but not available, use "

+ "this fallback"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:68

+ msgid "How long to allow cached logins between online logins (days)"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:69

  #, fuzzy

  msgid "How many failed logins attempts are allowed when offline"

  msgstr "當離線時所許可的試圖登入失敗次數"

  

- #: src/config/SSSDConfig.py:65

+ #: src/config/SSSDConfig.py:70

  msgid ""

  "How long (minutes) to deny login after offline_failed_login_attempts has "

  "been reached"

  msgstr ""

  

- #: src/config/SSSDConfig.py:66

+ #: src/config/SSSDConfig.py:71

  msgid "What kind of messages are displayed to the user during authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:67

+ #: src/config/SSSDConfig.py:72

  msgid "How many seconds to keep identity information cached for PAM requests"

  msgstr ""

  

- #: src/config/SSSDConfig.py:68

+ #: src/config/SSSDConfig.py:73

  msgid "How many days before password expiration a warning should be displayed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:71

+ #: src/config/SSSDConfig.py:76

  msgid "Identity provider"

  msgstr "身分提供者"

  

- #: src/config/SSSDConfig.py:72

+ #: src/config/SSSDConfig.py:77

  msgid "Authentication provider"

  msgstr "認證提供者"

  

- #: src/config/SSSDConfig.py:73

+ #: src/config/SSSDConfig.py:78

  msgid "Access control provider"

  msgstr "存取控制提供者"

  

- #: src/config/SSSDConfig.py:74

+ #: src/config/SSSDConfig.py:79

  msgid "Password change provider"

  msgstr "密碼變更提供者"

  

- #: src/config/SSSDConfig.py:77

+ #: src/config/SSSDConfig.py:82

  msgid "Minimum user ID"

  msgstr "最小的使用者 ID"

  

- #: src/config/SSSDConfig.py:78

+ #: src/config/SSSDConfig.py:83

  msgid "Maximum user ID"

  msgstr "最大的使用者 ID"

  

- #: src/config/SSSDConfig.py:79

+ #: src/config/SSSDConfig.py:84

  msgid "Enable enumerating all users/groups"

  msgstr "啟用所有使用者或群組的列舉"

  

- #: src/config/SSSDConfig.py:80

+ #: src/config/SSSDConfig.py:85

  msgid "Cache credentials for offline login"

  msgstr "供離線登入使用的快取憑證"

  

- #: src/config/SSSDConfig.py:81

+ #: src/config/SSSDConfig.py:86

  #, fuzzy

  msgid "Store password hashes"

  msgstr "儲存密碼雜湊"

  

- #: src/config/SSSDConfig.py:82

+ #: src/config/SSSDConfig.py:87

  msgid "Display users/groups in fully-qualified form"

  msgstr ""

  

- #: src/config/SSSDConfig.py:83

+ #: src/config/SSSDConfig.py:88

  msgid "Entry cache timeout length (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:84

+ #: src/config/SSSDConfig.py:89

  msgid ""

  "Restrict or prefer a specific address family when performing DNS lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:85

+ #: src/config/SSSDConfig.py:90

  msgid "How long to keep cached entries after last successful login (days)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:86

+ #: src/config/SSSDConfig.py:91

  msgid "How long to wait for replies from DNS when resolving servers (seconds)"

  msgstr ""

  

- #: src/config/SSSDConfig.py:87

+ #: src/config/SSSDConfig.py:92

  msgid "The domain part of service discovery DNS query"

  msgstr ""

  

- #: src/config/SSSDConfig.py:90

+ #: src/config/SSSDConfig.py:93

+ msgid "Override GID value from the identity provider with this value"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:96

  msgid "IPA domain"

  msgstr "IPA 網域"

  

- #: src/config/SSSDConfig.py:91

+ #: src/config/SSSDConfig.py:97

  msgid "IPA server address"

  msgstr "IPA 伺服器位址"

  

- #: src/config/SSSDConfig.py:92

+ #: src/config/SSSDConfig.py:98

  msgid "IPA client hostname"

  msgstr "IPA 客戶端主機名稱"

  

- #: src/config/SSSDConfig.py:93

+ #: src/config/SSSDConfig.py:99

  msgid "Whether to automatically update the client's DNS entry in FreeIPA"

  msgstr ""

  

- #: src/config/SSSDConfig.py:94

+ #: src/config/SSSDConfig.py:100

  msgid "The interface whose IP should be used for dynamic DNS updates"

  msgstr ""

  

- #: src/config/SSSDConfig.py:95

+ #: src/config/SSSDConfig.py:101

  msgid "Search base for HBAC related objects"

  msgstr ""

  

- #: src/config/SSSDConfig.py:98 src/config/SSSDConfig.py:99

+ #: src/config/SSSDConfig.py:102

+ msgid ""

+ "The amount of time between lookups of the HBAC rules against the IPA server"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:103

+ msgid "If DENY rules are present, either DENY_ALL or IGNORE"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:106 src/config/SSSDConfig.py:107

  msgid "Kerberos server address"

  msgstr "Kerberos 伺服器位址"

  

- #: src/config/SSSDConfig.py:100

+ #: src/config/SSSDConfig.py:108

  msgid "Kerberos realm"

  msgstr ""

  

- #: src/config/SSSDConfig.py:101

+ #: src/config/SSSDConfig.py:109

  msgid "Authentication timeout"

  msgstr "認證逾時"

  

- #: src/config/SSSDConfig.py:104

+ #: src/config/SSSDConfig.py:112

  msgid "Directory to store credential caches"

  msgstr "儲存憑證快取的目錄"

  

- #: src/config/SSSDConfig.py:105

+ #: src/config/SSSDConfig.py:113

  msgid "Location of the user's credential cache"

  msgstr "使用者憑證快取的位置"

  

- #: src/config/SSSDConfig.py:106

+ #: src/config/SSSDConfig.py:114

  msgid "Location of the keytab to validate credentials"

  msgstr "驗證憑證用的金鑰表格位置"

  

- #: src/config/SSSDConfig.py:107

+ #: src/config/SSSDConfig.py:115

  msgid "Enable credential validation"

  msgstr "啟用憑證驗證"

  

- #: src/config/SSSDConfig.py:108

+ #: src/config/SSSDConfig.py:116

  msgid "Store password if offline for later online authentication"

  msgstr ""

  

- #: src/config/SSSDConfig.py:109

+ #: src/config/SSSDConfig.py:117

  msgid "Renewable lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:110

+ #: src/config/SSSDConfig.py:118

  msgid "Lifetime of the TGT"

  msgstr ""

  

- #: src/config/SSSDConfig.py:111

+ #: src/config/SSSDConfig.py:119

  msgid "Time between two checks for renewal"

  msgstr ""

  

- #: src/config/SSSDConfig.py:112

+ #: src/config/SSSDConfig.py:120

  msgid "Enables FAST"

  msgstr ""

  

- #: src/config/SSSDConfig.py:115

+ #: src/config/SSSDConfig.py:123

  msgid "Server where the change password service is running if not on the KDC"

  msgstr ""

  

- #: src/config/SSSDConfig.py:118

+ #: src/config/SSSDConfig.py:126

  msgid "ldap_uri, The URI of the LDAP server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:119

+ #: src/config/SSSDConfig.py:127

  msgid "The default base DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:120

+ #: src/config/SSSDConfig.py:128

  msgid "The Schema Type in use on the LDAP server, rfc2307"

  msgstr ""

  

- #: src/config/SSSDConfig.py:121

+ #: src/config/SSSDConfig.py:129

  msgid "The default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:122

+ #: src/config/SSSDConfig.py:130

  msgid "The type of the authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:123

+ #: src/config/SSSDConfig.py:131

  msgid "The authentication token of the default bind DN"

  msgstr ""

  

- #: src/config/SSSDConfig.py:124

+ #: src/config/SSSDConfig.py:132

  msgid "Length of time to attempt connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:125

+ #: src/config/SSSDConfig.py:133

  msgid "Length of time to attempt synchronous LDAP operations"

  msgstr ""

  

- #: src/config/SSSDConfig.py:126

+ #: src/config/SSSDConfig.py:134

  msgid "Length of time between attempts to reconnect while offline"

  msgstr ""

  

- #: src/config/SSSDConfig.py:127

+ #: src/config/SSSDConfig.py:135

  msgid "Use only the upper case for realm names"

  msgstr ""

  

- #: src/config/SSSDConfig.py:128

+ #: src/config/SSSDConfig.py:136

  #, fuzzy

  msgid "File that contains CA certificates"

  msgstr "含有 CA 憑證的檔案"

  

- #: src/config/SSSDConfig.py:129

+ #: src/config/SSSDConfig.py:137

  msgid "Path to CA certificate directory"

  msgstr ""

  

- #: src/config/SSSDConfig.py:130

+ #: src/config/SSSDConfig.py:138

  #, fuzzy

  msgid "File that contains the client certificate"

  msgstr "含有 CA 憑證的檔案"

  

- #: src/config/SSSDConfig.py:131

+ #: src/config/SSSDConfig.py:139

  #, fuzzy

  msgid "File that contains the client key"

  msgstr "含有 CA 憑證的檔案"

  

- #: src/config/SSSDConfig.py:132

+ #: src/config/SSSDConfig.py:140

  msgid "List of possible ciphers suites"

  msgstr ""

  

- #: src/config/SSSDConfig.py:133

+ #: src/config/SSSDConfig.py:141

  msgid "Require TLS certificate verification"

  msgstr "需要 TLS 憑證驗證"

  

- #: src/config/SSSDConfig.py:134

+ #: src/config/SSSDConfig.py:142

  msgid "Specify the sasl mechanism to use"

  msgstr "指定要使用的 sasl 機制"

  

- #: src/config/SSSDConfig.py:135

+ #: src/config/SSSDConfig.py:143

  msgid "Specify the sasl authorization id to use"

  msgstr "指定要使用的 sasl 認證 id"

  

- #: src/config/SSSDConfig.py:136

+ #: src/config/SSSDConfig.py:144

  msgid "Kerberos service keytab"

  msgstr ""

  

- #: src/config/SSSDConfig.py:137

+ #: src/config/SSSDConfig.py:145

  msgid "Use Kerberos auth for LDAP connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:138

+ #: src/config/SSSDConfig.py:146

  msgid "Follow LDAP referrals"

  msgstr ""

  

- #: src/config/SSSDConfig.py:139

+ #: src/config/SSSDConfig.py:147

  msgid "Lifetime of TGT for LDAP connection"

  msgstr ""

  

- #: src/config/SSSDConfig.py:140

+ #: src/config/SSSDConfig.py:148

  msgid "How to dereference aliases"

  msgstr ""

  

- #: src/config/SSSDConfig.py:141

+ #: src/config/SSSDConfig.py:149

  msgid "Service name for DNS service lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:143

+ #: src/config/SSSDConfig.py:150

+ msgid "The number of records to retrieve in a single LDAP query"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:151

+ msgid ""

+ "Whether the LDAP library should perform a reverse lookup to canonicalize the "

+ "host name during a SASL bind"

+ msgstr ""

+ 

+ #: src/config/SSSDConfig.py:153

  #, fuzzy

  msgid "entryUSN attribute"

  msgstr "UID 屬性"

  

- #: src/config/SSSDConfig.py:144

+ #: src/config/SSSDConfig.py:154

  #, fuzzy

  msgid "lastUSN attribute"

  msgstr "UID 屬性"

  

- #: src/config/SSSDConfig.py:147

+ #: src/config/SSSDConfig.py:157

  msgid "Length of time to wait for a search request"

  msgstr "搜尋請求的等候時間長度"

  

- #: src/config/SSSDConfig.py:148

+ #: src/config/SSSDConfig.py:158

  #, fuzzy

  msgid "Length of time to wait for a enumeration request"

  msgstr "搜尋請求的等候時間長度"

  

- #: src/config/SSSDConfig.py:149

+ #: src/config/SSSDConfig.py:159

  #, fuzzy

  msgid "Length of time between enumeration updates"

  msgstr "在列舉更新之間的長度"

  

- #: src/config/SSSDConfig.py:150

+ #: src/config/SSSDConfig.py:160

  #, fuzzy

  msgid "Length of time between cache cleanups"

  msgstr "在列舉更新之間的長度"

  

- #: src/config/SSSDConfig.py:151

+ #: src/config/SSSDConfig.py:161

  msgid "Require TLS for ID lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:152

+ #: src/config/SSSDConfig.py:162

  msgid "Base DN for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:153

+ #: src/config/SSSDConfig.py:163

  msgid "Scope of user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:154

+ #: src/config/SSSDConfig.py:164

  msgid "Filter for user lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:155

+ #: src/config/SSSDConfig.py:165

  msgid "Objectclass for users"

  msgstr ""

  

- #: src/config/SSSDConfig.py:156

+ #: src/config/SSSDConfig.py:166

  msgid "Username attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:158

+ #: src/config/SSSDConfig.py:168

  #, fuzzy

  msgid "UID attribute"

  msgstr "UID 屬性"

  

- #: src/config/SSSDConfig.py:159

+ #: src/config/SSSDConfig.py:169

  #, fuzzy

  msgid "Primary GID attribute"

  msgstr "主要 GID 屬性"

  

- #: src/config/SSSDConfig.py:160

+ #: src/config/SSSDConfig.py:170

  #, fuzzy

  msgid "GECOS attribute"

  msgstr "GEOS 屬性"

  

- #: src/config/SSSDConfig.py:161

+ #: src/config/SSSDConfig.py:171

  #, fuzzy

  msgid "Home directory attribute"

  msgstr "家目錄屬性"

  

- #: src/config/SSSDConfig.py:162

+ #: src/config/SSSDConfig.py:172

  #, fuzzy

  msgid "Shell attribute"

  msgstr "Shell 屬性"

  

- #: src/config/SSSDConfig.py:163

+ #: src/config/SSSDConfig.py:173

  #, fuzzy

  msgid "UUID attribute"

  msgstr "UUID 屬性"

  

- #: src/config/SSSDConfig.py:164

+ #: src/config/SSSDConfig.py:174

  #, fuzzy

  msgid "User principal attribute (for Kerberos)"

  msgstr "使用者原則屬性(供 Kerberos 使用)"

  

- #: src/config/SSSDConfig.py:165

+ #: src/config/SSSDConfig.py:175

  msgid "Full Name"

  msgstr "全名"

  

- #: src/config/SSSDConfig.py:166

+ #: src/config/SSSDConfig.py:176

  msgid "memberOf attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:167

+ #: src/config/SSSDConfig.py:177

  #, fuzzy

  msgid "Modification time attribute"

  msgstr "修改時間屬性"

  

- #: src/config/SSSDConfig.py:169

+ #: src/config/SSSDConfig.py:179

  msgid "shadowLastChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:170

+ #: src/config/SSSDConfig.py:180

  #, fuzzy

  msgid "shadowMin attribute"

  msgstr "Shell 屬性"

  

- #: src/config/SSSDConfig.py:171

+ #: src/config/SSSDConfig.py:181

  #, fuzzy

  msgid "shadowMax attribute"

  msgstr "Shell 屬性"

  

- #: src/config/SSSDConfig.py:172

+ #: src/config/SSSDConfig.py:182

  msgid "shadowWarning attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:173

+ #: src/config/SSSDConfig.py:183

  #, fuzzy

  msgid "shadowInactive attribute"

  msgstr "修改時間屬性"

  

- #: src/config/SSSDConfig.py:174

+ #: src/config/SSSDConfig.py:184

  #, fuzzy

  msgid "shadowExpire attribute"

  msgstr "Shell 屬性"

  

- #: src/config/SSSDConfig.py:175

+ #: src/config/SSSDConfig.py:185

  #, fuzzy

  msgid "shadowFlag attribute"

  msgstr "Shell 屬性"

  

- #: src/config/SSSDConfig.py:176

+ #: src/config/SSSDConfig.py:186

  msgid "Attribute listing authorized PAM services"

  msgstr ""

  

- #: src/config/SSSDConfig.py:177

+ #: src/config/SSSDConfig.py:187

  msgid "krbLastPwdChange attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:178

+ #: src/config/SSSDConfig.py:188

  #, fuzzy

  msgid "krbPasswordExpiration attribute"

  msgstr "修改時間屬性"

  

- #: src/config/SSSDConfig.py:179

+ #: src/config/SSSDConfig.py:189

  msgid "Attribute indicating that server side password policies are active"

  msgstr ""

  

- #: src/config/SSSDConfig.py:180

+ #: src/config/SSSDConfig.py:190

  #, fuzzy

  msgid "accountExpires attribute of AD"

  msgstr "Shell 屬性"

  

- #: src/config/SSSDConfig.py:181

+ #: src/config/SSSDConfig.py:191

  msgid "userAccountControl attribute of AD"

  msgstr ""

  

- #: src/config/SSSDConfig.py:182

+ #: src/config/SSSDConfig.py:192

  #, fuzzy

  msgid "nsAccountLock attribute"

  msgstr "Shell 屬性"

  

- #: src/config/SSSDConfig.py:184

+ #: src/config/SSSDConfig.py:194

  msgid "Base DN for group lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:187

+ #: src/config/SSSDConfig.py:197

  msgid "Objectclass for groups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:188

+ #: src/config/SSSDConfig.py:198

  #, fuzzy

  msgid "Group name"

  msgstr "群組"

  

- #: src/config/SSSDConfig.py:189

+ #: src/config/SSSDConfig.py:199

  #, fuzzy

  msgid "Group password"

  msgstr "群組"

  

- #: src/config/SSSDConfig.py:190

+ #: src/config/SSSDConfig.py:200

  #, fuzzy

  msgid "GID attribute"

  msgstr "UID 屬性"

  

- #: src/config/SSSDConfig.py:191

+ #: src/config/SSSDConfig.py:201

  #, fuzzy

  msgid "Group member attribute"

  msgstr "家目錄屬性"

  

- #: src/config/SSSDConfig.py:192

+ #: src/config/SSSDConfig.py:202

  #, fuzzy

  msgid "Group UUID attribute"

  msgstr "UUID 屬性"

  

- #: src/config/SSSDConfig.py:193

+ #: src/config/SSSDConfig.py:203

  #, fuzzy

  msgid "Modification time attribute for groups"

  msgstr "修改時間屬性"

  

- #: src/config/SSSDConfig.py:195

+ #: src/config/SSSDConfig.py:205

  msgid "Maximum nesting level SSSd will follow"

  msgstr ""

  

- #: src/config/SSSDConfig.py:197

+ #: src/config/SSSDConfig.py:207

  msgid "Base DN for netgroup lookups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:198

+ #: src/config/SSSDConfig.py:208

  msgid "Objectclass for netgroups"

  msgstr ""

  

- #: src/config/SSSDConfig.py:199

+ #: src/config/SSSDConfig.py:209

  msgid "Netgroup name"

  msgstr ""

  

- #: src/config/SSSDConfig.py:200

+ #: src/config/SSSDConfig.py:210

  msgid "Netgroups members attribute"

  msgstr ""

  

- #: src/config/SSSDConfig.py:201

+ #: src/config/SSSDConfig.py:211

  #, fuzzy

  msgid "Netgroup triple attribute"

  msgstr "修改時間屬性"

  

- #: src/config/SSSDConfig.py:202

+ #: src/config/SSSDConfig.py:212

  #, fuzzy

  msgid "Netgroup UUID attribute"

  msgstr "UUID 屬性"

  

- #: src/config/SSSDConfig.py:203

+ #: src/config/SSSDConfig.py:213

  #, fuzzy

  msgid "Modification time attribute for netgroups"

  msgstr "修改時間屬性"

  

- #: src/config/SSSDConfig.py:206

+ #: src/config/SSSDConfig.py:216

  msgid "Policy to evaluate the password expiration"

  msgstr "評估密碼過期時效的策略"

  

- #: src/config/SSSDConfig.py:209

+ #: src/config/SSSDConfig.py:219

  msgid "LDAP filter to determine access privileges"

  msgstr ""

  

- #: src/config/SSSDConfig.py:210

+ #: src/config/SSSDConfig.py:220

  msgid "Which attributes shall be used to evaluate if an account is expired"

  msgstr ""

  

- #: src/config/SSSDConfig.py:211

+ #: src/config/SSSDConfig.py:221

  msgid "Which rules should be used to evaluate access control"

  msgstr ""

  

- #: src/config/SSSDConfig.py:214

+ #: src/config/SSSDConfig.py:224

  msgid "URI of an LDAP server where password changes are allowed"

  msgstr ""

  

- #: src/config/SSSDConfig.py:215

+ #: src/config/SSSDConfig.py:225

  msgid "DNS service name for LDAP password change server"

  msgstr ""

  

- #: src/config/SSSDConfig.py:218

+ #: src/config/SSSDConfig.py:228

  msgid "Comma separated list of allowed users"

  msgstr "許可的使用者清單,請使用半形逗號作為分隔"

  

- #: src/config/SSSDConfig.py:219

+ #: src/config/SSSDConfig.py:229

  msgid "Comma separated list of prohibited users"

  msgstr "被禁止的使用者清單,請使用半形逗號作為分隔"

  

- #: src/config/SSSDConfig.py:222

+ #: src/config/SSSDConfig.py:232

  msgid "Default shell, /bin/bash"

  msgstr "預設 shell,/bin/bash"

  

- #: src/config/SSSDConfig.py:223

+ #: src/config/SSSDConfig.py:233

  #, fuzzy

  msgid "Base for home directories"

  msgstr "家目錄的基礎"

  

- #: src/config/SSSDConfig.py:226

+ #: src/config/SSSDConfig.py:236

  msgid "The name of the NSS library to use"

  msgstr "要使用的 NSS 函式庫名稱"

  

- #: src/config/SSSDConfig.py:229

+ #: src/config/SSSDConfig.py:239

  msgid "PAM stack to use"

  msgstr "要使用的 PAM 堆疊"

  

- #: src/monitor/monitor.c:2245

+ #: src/monitor/monitor.c:2321

  msgid "Become a daemon (default)"

  msgstr "作為幕後程式 (預設)"

  

- #: src/monitor/monitor.c:2247

+ #: src/monitor/monitor.c:2323

  msgid "Run interactive (not a daemon)"

  msgstr "以互動方式執行 (非幕後程式)"

  

- #: src/monitor/monitor.c:2249

+ #: src/monitor/monitor.c:2325

  msgid "Specify a non-default config file"

  msgstr "指定非預設的配置檔"

  
@@ -681,28 +729,28 @@

  msgid "Domain of the information provider (mandatory)"

  msgstr "資訊提供者的網域(委任)"

  

- #: src/sss_client/common.c:779

+ #: src/sss_client/common.c:822

  msgid "Privileged socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:782

+ #: src/sss_client/common.c:825

  msgid "Public socket has wrong ownership or permissions."

  msgstr ""

  

- #: src/sss_client/common.c:785

+ #: src/sss_client/common.c:828

  #, fuzzy

  msgid "Unexpected format of the server credential message."

  msgstr "使用者憑證快取的位置"

  

- #: src/sss_client/common.c:788

+ #: src/sss_client/common.c:831

  msgid "SSSD is not run by root."

  msgstr ""

  

- #: src/sss_client/common.c:793

+ #: src/sss_client/common.c:836

  msgid "An error occurred, but no description can be found."

  msgstr ""

  

- #: src/sss_client/common.c:799

+ #: src/sss_client/common.c:842

  msgid "Unexpected error while looking for an error description"

  msgstr ""

  
@@ -749,23 +797,23 @@

  msgid "Server message: "

  msgstr "伺服器訊息:"

  

- #: src/sss_client/pam_sss.c:1212

+ #: src/sss_client/pam_sss.c:1227

  msgid "New Password: "

  msgstr "新密碼:"

  

- #: src/sss_client/pam_sss.c:1213

+ #: src/sss_client/pam_sss.c:1228

  msgid "Reenter new Password: "

  msgstr "再次輸入新密碼:"

  

- #: src/sss_client/pam_sss.c:1295

+ #: src/sss_client/pam_sss.c:1314

  msgid "Password: "

  msgstr "密碼:"

  

- #: src/sss_client/pam_sss.c:1327

+ #: src/sss_client/pam_sss.c:1346

  msgid "Current Password: "

  msgstr "目前的密碼:"

  

- #: src/sss_client/pam_sss.c:1473

+ #: src/sss_client/pam_sss.c:1493

  msgid "Password expired. Change your password now."

  msgstr "密碼已過期。請立刻變更您的密碼。"

  

file modified
+49
@@ -161,6 +161,21 @@

      AC_SUBST(krb5pluginpath)

    ])

  

+ AC_DEFUN([WITH_KRB5_RCACHE_DIR],

+   [ AC_ARG_WITH([krb5-rcache-dir],

+                 [AC_HELP_STRING([--with-krb5-rcache-dir=PATH],

+                                 [Path to store Kerberos replay caches [__LIBKRB5_DEFAULTS__]]

+                                )

+                 ]

+                )

+     krb5rcachedir="__LIBKRB5_DEFAULTS__"

+     if test x"$with_krb5_rcache_dir" != x; then

+         krb5rcachedir=$with_krb5_rcache_dir

+     fi

+     AC_SUBST(krb5rcachedir)

+     AC_DEFINE_UNQUOTED(KRB5_RCACHE_DIR, "$krb5rcachedir", [Directory used for storing Kerberos replay caches])

+   ])

+ 

  AC_DEFUN([WITH_PYTHON_BINDINGS],

    [ AC_ARG_WITH([python-bindings],

                  [AC_HELP_STRING([--with-python-bindings],
@@ -251,3 +266,37 @@

          AC_SUBST(BUILD_LIBNL)

      fi

    ])

+ 

+ AC_DEFUN([WITH_NOLOGIN_SHELL],

+   [ AC_ARG_WITH([nologin-shell],

+                 [AC_HELP_STRING([--with-nologin-shell=PATH],

+                                 [The shell used to deny access to users [/sbin/nologin]]

+                                )

+                 ]

+                )

+     nologin_shell="/sbin/nologin"

+     if test x"$with_nologin_shell" != x; then

+         nologin_shell=$with_nologin_shell

+     fi

+     AC_DEFINE_UNQUOTED(NOLOGIN_SHELL, "$nologin_shell", [The shell used to deny access to users])

+   ])

+ 

+ AC_DEFUN([WITH_UNICODE_LIB],

+   [ AC_ARG_WITH([unicode-lib],

+                 [AC_HELP_STRING([--with-unicode-lib=<library>],

+                                 [Which library to use for unicode processing (libunistring, glib2) [libunistring]]

+                                )

+                 ]

+                )

+     unicode_lib="libunistring"

+     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

+         AC_MSG_ERROR([Unsupported unicode library])

+     fi

+ 

+     AM_CONDITIONAL([WITH_LIBUNISTRING], test x"$unicode_lib" = x"libunistring")

+     AM_CONDITIONAL([WITH_GLIB], test x"$unicode_lib" = x"glib2")

+   ])

file modified
+15 -1
@@ -842,9 +842,23 @@

          goto done;

      }

  

+     ret = get_entry_as_uint32(res->msgs[0], &domain->override_gid,

+                               CONFDB_DOMAIN_OVERRIDE_GID, 0);

+     if (ret != EOK) {

+         DEBUG(0, ("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);

+     domain->override_homedir = talloc_strdup(domain, tmp);

+     if (!domain->name) {

+         ret = ENOMEM;

+         goto done;

+     }

+ 

      *_domain = domain;

      ret = EOK;

- 

  done:

      talloc_free(tmp_ctx);

      return ret;

file modified
+15
@@ -41,6 +41,7 @@

  #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 */
@@ -53,6 +54,7 @@

  #define CONFDB_SERVICE_DEBUG_TO_FILES "debug_to_files"

  #define CONFDB_SERVICE_TIMEOUT "timeout"

  #define CONFDB_SERVICE_RECON_RETRIES "reconnection_retries"

+ #define CONFDB_SERVICE_FD_LIMIT "fd_limit"

  

  /* Monitor */

  #define CONFDB_MONITOR_CONF_ENTRY "config/sssd"
@@ -62,6 +64,11 @@

  #define CONFDB_MONITOR_NAME_REGEX   "re_expression"

  #define CONFDB_MONITOR_FULL_NAME_FORMAT "full_name_format"

  #define CONFDB_MONITOR_TRY_INOTIFY "try_inotify"

+ #define CONFDB_MONITOR_KRB5_RCACHEDIR "krb5_rcache_dir"

+ 

+ /* Responders */

+ #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"
@@ -72,6 +79,10 @@

  #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_VETOED_SHELL  "vetoed_shells"

+ #define CONFDB_NSS_ALLOWED_SHELL "allowed_shells"

+ #define CONFDB_NSS_SHELL_FALLBACK "shell_fallback"

  

  /* PAM */

  #define CONFDB_PAM_CONF_ENTRY "config/pam"
@@ -109,6 +120,7 @@

  #define CONFDB_DOMAIN_DNS_DISCOVERY_NAME "dns_discovery_domain"

  #define CONFDB_DOMAIN_FAMILY_ORDER "lookup_family_order"

  #define CONFDB_DOMAIN_ACCOUNT_CACHE_EXPIRATION "account_cache_expiration"

+ #define CONFDB_DOMAIN_OVERRIDE_GID "override_gid"

  

  /* Local Provider */

  #define CONFDB_LOCAL_DEFAULT_SHELL   "default_shell"
@@ -143,6 +155,9 @@

      bool cache_credentials;

      bool legacy_passwords;

  

+     gid_t override_gid;

+     const char *override_homedir;

+ 

      uint32_t entry_cache_timeout;

  

      struct sss_domain_info *next;

file modified
+15
@@ -42,6 +42,8 @@

      'timeout' : _('Ping timeout before restarting service'),

      'command' : _('Command to start service'),

      'reconnection_retries' : _('Number of times to attempt connection to Data Providers'),

+     'client_idle_timeout' : _('Idle time before automatic disconnection of a client'),

+     'fd_limit' : _('The number of file descriptors that may be opened by this responder'),

  

      # [sssd]

      'services' : _('SSSD Services to start'),
@@ -49,6 +51,7 @@

      'sbus_timeout' : _('Timeout for messages sent over the SBUS'),

      're_expression' : _('Regex to parse username and domain'),

      'full_name_format' : _('Printf-compatible format for displaying fully-qualified names'),

+     'krb5_rcache_dir' : _('Directory on the filesystem where SSSD should store Kerberos replay cache files.'),

  

      # [nss]

      'enum_cache_timeout' : _('Enumeration cache timeout length (seconds)'),
@@ -58,6 +61,10 @@

      'filter_groups' : _('Groups that SSSD should explicitly ignore'),

      'filter_users_in_groups' : _('Should filtered users appear in groups'),

      'pwfield' : _('The value of the password field the NSS provider should return'),

+     'override_homedir' : _('Override homedir value from the identity provider with this value'),

+     'allowed_shells' : _('The list of shells users are allowed to log in with'),

+     'vetoed_shells' : _('The list of shells that will be vetoed, and replaced with the fallback shell'),

+     'shell_fallback' : _('If a shell stored in central directory is allowed but not available, use this fallback'),

  

      # [pam]

      'offline_credentials_expiration' : _('How long to allow cached logins between online logins (days)'),
@@ -85,6 +92,7 @@

      'account_cache_expiration' : _('How long to keep cached entries after last successful login (days)'),

      'dns_resolver_timeout' : _('How long to wait for replies from DNS when resolving servers (seconds)'),

      'dns_discovery_domain' : _('The domain part of service discovery DNS query'),

+     'override_gid' : _('Override GID value from the identity provider with this value'),

  

      # [provider/ipa]

      'ipa_domain' : _('IPA domain'),
@@ -93,6 +101,9 @@

      'ipa_dyndns_update' : _("Whether to automatically update the client's DNS entry in FreeIPA"),

      'ipa_dyndns_iface' : _("The interface whose IP should be used for dynamic DNS updates"),

      'ipa_hbac_search_base' : _("Search base for HBAC related objects"),

+     'ipa_hbac_refresh' : _("The amount of time between lookups of the HBAC rules against the IPA server"),

+     'ipa_hbac_treat_deny_as' : _("If DENY rules are present, either DENY_ALL or IGNORE"),

+     'ipa_hbac_support_srchost' : _("If set to false, host argument given by PAM will be ignored"),

  

      # [provider/krb5]

      'krb5_kdcip' : _('Kerberos server address'),
@@ -139,10 +150,14 @@

      'ldap_krb5_ticket_lifetime' : _('Lifetime of TGT for LDAP connection'),

      'ldap_deref' : _('How to dereference aliases'),

      'ldap_dns_service_name' : _('Service name for DNS service lookups'),

+     'ldap_page_size' : _('The number of records to retrieve in a single LDAP query'),

+     'ldap_sasl_canonicalize' : _('Whether the LDAP library should perform a reverse lookup to canonicalize the host name during a SASL bind'),

  

      'ldap_entry_usn' : _('entryUSN attribute'),

      'ldap_rootdse_last_usn' : _('lastUSN attribute'),

  

+     'ldap_disable_paging' : _('Disable the LDAP paging control'),

+ 

      # [provider/ldap/id]

      'ldap_search_timeout' : _('Length of time to wait for a search request'),

      'ldap_enumeration_search_timeout' : _('Length of time to wait for a enumeration request'),

file modified
+25 -4
@@ -266,11 +266,14 @@

              'sbus_timeout',

              're_expression',

              'full_name_format',

+             'krb5_rcache_dir',

              'debug_level',

              'debug_timestamps',

              'debug_to_files',

              'command',

-             'reconnection_retries']

+             'reconnection_retries',

+             'client_idle_timeout',

+             'fd_limit']

  

          self.assertTrue(type(options) == dict,

                          "Options should be a dictionary")
@@ -467,6 +470,7 @@

              'min_id',

              'max_id',

              'timeout',

+             'try_inotify',

              'command',

              'enumerate',

              'cache_credentials',
@@ -479,6 +483,8 @@

              'account_cache_expiration',

              'dns_resolver_timeout',

              'dns_discovery_domain',

+             'override_gid',

+             'override_homedir',

              'id_provider',

              'auth_provider',

              'access_provider',
@@ -516,7 +522,13 @@

          domain.add_provider('local', 'id')

          control_list.extend(

              ['default_shell',

-              'base_directory'])

+              'base_directory',

+              'create_homedir',

+              'remove_homedir',

+              'homedir_umask',

+              'skel_dir',

+              'mail_dir',

+              'userdel_cmd'])

  

          options = domain.list_options()

  
@@ -693,7 +705,7 @@

              'ipa': ['id', 'auth', 'access', 'chpass'],

              'local': ['id', 'auth', 'chpass'],

              'ldap': ['id', 'auth', 'access', 'chpass'],

-             'krb5': ['auth', 'chpass'],

+             'krb5': ['auth', 'access', 'chpass'],

              'proxy': ['id', 'auth'],

              'simple': ['access'],

              'permit': ['access'],
@@ -796,6 +808,7 @@

              'min_id',

              'max_id',

              'timeout',

+             'try_inotify',

              'command',

              'enumerate',

              'cache_credentials',
@@ -808,6 +821,8 @@

              'lookup_family_order',

              'dns_resolver_timeout',

              'dns_discovery_domain',

+             'override_gid',

+             'override_homedir',

              'id_provider',

              'auth_provider',

              'access_provider',
@@ -845,7 +860,13 @@

          domain.add_provider('local', 'id')

          control_list.extend(

              ['default_shell',

-              'base_directory'])

+              'base_directory',

+              'create_homedir',

+              'remove_homedir',

+              'homedir_umask',

+              'skel_dir',

+              'mail_dir',

+              'userdel_cmd'])

  

          options = domain.list_options()

  

file modified
+12 -1
@@ -8,6 +8,8 @@

  debug_to_files = bool, None, false

  command = str, None, false

  reconnection_retries = int, None, false

+ client_idle_timeout = int, None, false

+ fd_limit = int, None, false

  

  [sssd]

  # Monitor service
@@ -17,16 +19,21 @@

  sbus_timeout = int, None, false

  re_expression = str, None, false

  full_name_format = str, None, false

+ krb5_rcache_dir = str, None, false

  

  [nss]

  # Name service

  enum_cache_timeout = int, None, false

- entry_cache_no_wait_percentage = int, None, false

+ entry_cache_nowait_percentage = int, None, false

  entry_negative_timeout = int, None, false

  filter_users = list, str, false

  filter_groups = list, str, false

  filter_users_in_groups = bool, None, false

  pwfield = str, None, false

+ override_homedir = str, None, false

+ allowed_shells = list, str, false

+ vetoed_shells = list, str, false

+ shell_fallback = str, None, false

  

  [pam]

  # Authentication service
@@ -52,6 +59,7 @@

  min_id = int, None, false

  max_id = int, None, false

  timeout = int, None, false

+ try_inotify = bool, None, false

  enumerate = bool, None, false

  cache_credentials = bool, None, true, false

  store_legacy_passwords = bool, None, false
@@ -63,6 +71,9 @@

  filter_groups = list, str, false

  dns_resolver_timeout = int, None, false

  dns_discovery_domain = str, None, false

+ override_gid = int, None, false

+ override_homedir = str, None, false

+ 

  

  # Special providers

  [provider/permit]

@@ -35,6 +35,7 @@

  ldap_krb5_ticket_lifetime = int, None, false

  ldap_dns_service_name = str, None, false

  ldap_deref = str, None, false

+ ldap_disable_paging = bool, None, false

  

  [provider/ipa/id]

  ldap_search_timeout = int, None, false
@@ -100,6 +101,9 @@

  krb5_use_fast = str, None, false

  

  [provider/ipa/access]

+ ipa_hbac_refresh = int, None, false

+ ipa_hbac_treat_deny_as = str, None, false

+ ipa_hbac_support_srchost = bool, None, false

  

  [provider/ipa/chpass]

  

@@ -16,5 +16,7 @@

  krb5_renew_interval = int, None, false

  krb5_use_fast = str, None, false

  

+ [provider/krb5/access]

+ 

  [provider/krb5/chpass]

  

@@ -27,6 +27,9 @@

  ldap_krb5_ticket_lifetime = int, None, false

  ldap_dns_service_name = str, None, false

  ldap_deref = str, None, false

+ ldap_page_size = int, None, false

+ ldap_sasl_canonicalize = bool, None, false

+ ldap_disable_paging = bool, None, false

  

  [provider/ldap/id]

  ldap_search_timeout = int, None, false

@@ -1,4 +1,10 @@

  [provider/local]

+ create_homedir = bool, None, false

+ remove_homedir = bool, None, false

+ homedir_umask = int, None, false

+ skel_dir = str, None, false

+ mail_dir = str, None, false

+ userdel_cmd = str, None, false

  

  [provider/local/id]

  default_shell = str, None, true, /bin/bash

file modified
+794 -178
@@ -25,6 +25,45 @@

  #include "confdb/confdb.h"

  #include <time.h>

  

+ #define LDB_MODULES_PATH "LDB_MODULES_PATH"

+ 

+ static 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(9, ("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(void *mem_ctx, const char *input,

                            char **sanitized)

  {
@@ -165,33 +204,68 @@

      return ldb_dn_new_fmt(memctx, ctx->ldb, SYSDB_TMPL_NETGROUP_BASE, domain);

  }

  

- errno_t sysdb_group_dn_name(struct sysdb_ctx *ctx, void *memctx,

-                             const char *_dn, char **_name)

+ errno_t sysdb_get_rdn(struct sysdb_ctx *ctx, void *memctx,

+                       const char *_dn, char **_name, char **_val)

  {

+     errno_t ret;

      struct ldb_dn *dn;

+     const char *attr_name = NULL;

      const struct ldb_val *val;

-     *_name = NULL;

+     TALLOC_CTX *tmpctx;

  

-     dn = ldb_dn_new_fmt(memctx, ctx->ldb, "%s", _dn);

-     if (dn == NULL) {

+     /* We have to create a tmpctx here because

+      * ldb_dn_new_fmt() fails if memctx is NULL

+      */

+     tmpctx = talloc_new(NULL);

+     if (!tmpctx) {

          return ENOMEM;

      }

  

+     dn = ldb_dn_new_fmt(tmpctx, ctx->ldb, "%s", _dn);

+     if (dn == NULL) {

+         ret = ENOMEM;

+         goto done;

+     }

+ 

+     if (_name) {

+         attr_name = ldb_dn_get_rdn_name(dn);

+         if (attr_name == NULL) {

+             ret = EINVAL;

+             goto done;

+         }

+ 

+         *_name = talloc_strdup(memctx, attr_name);

+         if (!*_name) {

+             ret = ENOMEM;

+             goto done;

+         }

+     }

+ 

      val = ldb_dn_get_rdn_val(dn);

      if (val == NULL) {

-         talloc_zfree(dn);

-         return EINVAL;

+         ret = EINVAL;

+         if (_name) talloc_free(*_name);

+         goto done;

      }

  

-     *_name = talloc_strndup(memctx, (char *) val->data, val->length);

-     if (!*_name) {

-         talloc_zfree(dn);

-         return ENOMEM;

+     *_val = talloc_strndup(memctx, (char *) val->data, val->length);

+     if (!*_val) {

+         ret = ENOMEM;

+         if (_name) talloc_free(*_name);

+         goto done;

      }

  

-     talloc_zfree(dn);

+     ret = EOK;

  

-     return EOK;

+ done:

+     talloc_zfree(tmpctx);

+     return ret;

+ }

+ 

+ errno_t sysdb_group_dn_name(struct sysdb_ctx *ctx, void *memctx,

+                             const char *_dn, char **_name)

+ {

+     return sysdb_get_rdn(ctx, memctx, _dn, NULL, _name);

  }

  

  struct ldb_dn *sysdb_domain_dn(struct sysdb_ctx *ctx, void *memctx,
@@ -210,8 +284,8 @@

      return talloc_zero(memctx, struct sysdb_attrs);

  }

  

- static int sysdb_attrs_get_el_int(struct sysdb_attrs *attrs, const char *name,

-                                   bool alloc, 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)

  {

      struct ldb_message_element *e = NULL;

      int i;
@@ -250,7 +324,7 @@

  int sysdb_attrs_get_el(struct sysdb_attrs *attrs, const char *name,

                         struct ldb_message_element **el)

  {

-     return sysdb_attrs_get_el_int(attrs, name, true, el);

+     return sysdb_attrs_get_el_ext(attrs, name, true, el);

  }

  

  int sysdb_attrs_get_string(struct sysdb_attrs *attrs, const char *name,
@@ -259,7 +333,7 @@

      struct ldb_message_element *el;

      int ret;

  

-     ret = sysdb_attrs_get_el_int(attrs, name, false, &el);

+     ret = sysdb_attrs_get_el_ext(attrs, name, false, &el);

      if (ret) {

          return ret;

      }
@@ -280,7 +354,7 @@

      char *endptr;

      uint32_t val;

  

-     ret = sysdb_attrs_get_el_int(attrs, name, false, &el);

+     ret = sysdb_attrs_get_el_ext(attrs, name, false, &el);

      if (ret) {

          return ret;

      }
@@ -290,7 +364,7 @@

      }

  

      errno = 0;

-     val = strtouint32((const char *) el->values[0].data, &endptr, 0);

+     val = strtouint32((const char *) el->values[0].data, &endptr, 10);

      if (errno != 0) return errno;

      if (*endptr) return EINVAL;

  
@@ -298,6 +372,28 @@

      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;

+ }

+ 

  int sysdb_attrs_get_string_array(struct sysdb_attrs *attrs, const char *name,

                                   TALLOC_CTX *mem_ctx, const char ***string)

  {
@@ -306,7 +402,7 @@

      unsigned int u;

      const char **a;

  

-     ret = sysdb_attrs_get_el_int(attrs, name, false, &el);

+     ret = sysdb_attrs_get_el_ext(attrs, name, false, &el);

      if (ret) {

          return ret;

      }
@@ -388,6 +484,9 @@

      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);
@@ -718,7 +817,7 @@

  

      ret = ldb_search(ldb, mem_ctx, &res,

                       basedn, LDB_SCOPE_SUBTREE,

-                      attrs, filter);

+                      attrs, "%s", filter);

      if (ret != LDB_SUCCESS) {

          ret = EIO;

          goto done;
@@ -874,26 +973,10 @@

          goto exit;

      }

  

-     ldb = ldb_init(tmp_ctx, NULL);

-     if (!ldb) {

-         ret = EIO;

-         goto exit;

-     }

- 

-     ret = ldb_set_debug(ldb, ldb_debug_messages, NULL);

-     if (ret != LDB_SUCCESS) {

-         ret = EIO;

-         goto exit;

-     }

- 

- #ifdef SYSDB_TEST

-     ldb_set_modules_dir(ctx->ldb, ABS_BUILD_DIR"/.libs");

- #endif

- 

-     ret = ldb_connect(ldb, ldb_file, 0, NULL);

-     if (ret != LDB_SUCCESS) {

-         ret = EIO;

-         goto exit;

+     ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb);

+     if (ret != EOK) {

+         DEBUG(1, ("sysdb_ldb_connect failed.\n"));

+         return ret;

      }

  

      verdn = ldb_dn_new(tmp_ctx, ldb, "cn=sysdb");
@@ -979,22 +1062,10 @@

      }

  

      /* reopen */

-     ldb = ldb_init(tmp_ctx, NULL);

-     if (!ldb) {

-         ret = EIO;

-         goto exit;

-     }

- 

-     ret = ldb_set_debug(ldb, ldb_debug_messages, NULL);

-     if (ret != LDB_SUCCESS) {

-         ret = EIO;

-         goto exit;

-     }

- 

-     ret = ldb_connect(ldb, ldb_file, 0, NULL);

-     if (ret != LDB_SUCCESS) {

-         ret = EIO;

-         goto exit;

+     ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb);

+     if (ret != EOK) {

+         DEBUG(1, ("sysdb_ldb_connect failed.\n"));

+         return ret;

      }

  

      /* open a transaction */
@@ -1405,162 +1476,491 @@

      return ret;

  }

  

- static 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)

+ static int sysdb_upgrade_05(struct sysdb_ctx *ctx, const char **ver)

  {

-     TALLOC_CTX *tmp_ctx = NULL;

-     struct sysdb_ctx *ctx;

-     const char *base_ldif;

-     struct ldb_ldif *ldif;

-     struct ldb_message *msg;

-     struct ldb_message_element *el;

-     struct ldb_result *res;

-     struct ldb_dn *verdn;

-     const char *version = NULL;

+     TALLOC_CTX *tmp_ctx;

      int ret;

+     struct ldb_message *msg;

  

-     ctx = talloc_zero(mem_ctx, struct sysdb_ctx);

-     if (!ctx) {

+     tmp_ctx = talloc_new(ctx);

+     if (!tmp_ctx) {

          return ENOMEM;

      }

-     ctx->domain = domain;

  

-     /* The local provider s the only true MPG,

-      * for the other domains, the provider actually unrolls MPGs */

-     if (strcasecmp(domain->provider, "local") == 0) {

-         ctx->mpg = true;

-     }

+     DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_6));

  

-     ret = sysdb_get_db_file(ctx, domain->provider,

-                             domain->name, db_path,

-                             &ctx->ldb_file);

-     if (ret != EOK) {

-         return ret;

+     ret = ldb_transaction_start(ctx->ldb);

+     if (ret != LDB_SUCCESS) {

+         ret = EIO;

+         goto done;

      }

-     DEBUG(5, ("DB File for %s: %s\n", domain->name, ctx->ldb_file));

  

-     ctx->ldb = ldb_init(ctx, NULL);

-     if (!ctx->ldb) {

-         return EIO;

+     /* Add new indexes */

+     msg = ldb_msg_new(tmp_ctx);

+     if (!msg) {

+         ret = ENOMEM;

+         goto done;

      }

- 

-     ret = ldb_set_debug(ctx->ldb, ldb_debug_messages, NULL);

-     if (ret != LDB_SUCCESS) {

-         return EIO;

+     msg->dn = ldb_dn_new(tmp_ctx, ctx->ldb, "@INDEXLIST");

+     if (!msg->dn) {

+         ret = ENOMEM;

+         goto done;

      }

  

- #ifdef SYSDB_TEST

-     ldb_set_modules_dir(ctx->ldb, ABS_BUILD_DIR"/.libs");

- #endif

- 

-     ret = ldb_connect(ctx->ldb, ctx->ldb_file, 0, NULL);

+     /* Add Index for dataExpireTimestamp */

+     ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);

      if (ret != LDB_SUCCESS) {

-         return EIO;

-     }

- 

-     tmp_ctx = talloc_new(ctx);

-     if (!tmp_ctx) {

-         return ENOMEM;

+         ret = ENOMEM;

+         goto done;

      }

- 

-     verdn = ldb_dn_new(tmp_ctx, ctx->ldb, "cn=sysdb");

-     if (!verdn) {

-         ret = EIO;

+     ret = ldb_msg_add_string(msg, "@IDXATTR", "dataExpireTimestamp");

+     if (ret != LDB_SUCCESS) {

+         ret = ENOMEM;

          goto done;

      }

  

-     ret = ldb_search(ctx->ldb, tmp_ctx, &res,

-                      verdn, LDB_SCOPE_BASE,

-                      NULL, NULL);

+     /* Add index to speed up ONELEVEL searches */

+     ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_ADD, NULL);

      if (ret != LDB_SUCCESS) {

-         ret = EIO;

+         ret = ENOMEM;

          goto done;

      }

-     if (res->count > 1) {

-         ret = EIO;

+     ret = ldb_msg_add_string(msg, "@IDXONE", "1");

+     if (ret != LDB_SUCCESS) {

+         ret = ENOMEM;

          goto done;

      }

  

-     if (res->count == 1) {

-         el = ldb_msg_find_element(res->msgs[0], "version");

-         if (el) {

-             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(0, ("Wrong DB version (got %s expected %s)\n",

-                           version, SYSDB_VERSION));

-                 ret = EINVAL;

-                 goto done;

-             }

- 

-             DEBUG(4, ("Upgrading DB [%s] from version: %s\n",

-                       domain->name, version));

- 

-             if (strcmp(version, SYSDB_VERSION_0_3) == 0) {

-                 ret = sysdb_upgrade_03(ctx, &version);

-                 if (ret != EOK) {

-                     goto done;

-                 }

-             }

- 

-             if (strcmp(version, SYSDB_VERSION_0_4) == 0) {

-                 ret = sysdb_upgrade_04(ctx, &version);

-                 goto done;

-             }

-         }

- 

-         DEBUG(0,("Unknown DB version [%s], expected [%s] for domain %s!\n",

-                  version?version:"not found", SYSDB_VERSION, domain->name));

-         ret = EINVAL;

+     ret = ldb_modify(ctx->ldb, msg);

+     if (ret != LDB_SUCCESS) {

+         ret = sysdb_error_to_errno(ret);

          goto done;

      }

  

-     /* cn=sysdb does not exists, means db is empty, populate */

- 

-     base_ldif = SYSDB_BASE_LDIF;

-     while ((ldif = ldb_ldif_read_string(ctx->ldb, &base_ldif))) {

-         ret = ldb_add(ctx->ldb, ldif->msg);

-         if (ret != LDB_SUCCESS) {

-             DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!\n",

-                       ret, ldb_errstring(ctx->ldb), domain->name));

-             ret = EIO;

-             goto done;

-         }

-         ldb_ldif_read_free(ctx->ldb, ldif);

-     }

- 

-     /* == create base domain object == */

- 

+     /* conversion done, upgrade version number */

      msg = ldb_msg_new(tmp_ctx);

      if (!msg) {

          ret = ENOMEM;

          goto done;

      }

-     msg->dn = ldb_dn_new_fmt(msg, ctx->ldb, SYSDB_DOM_BASE, domain->name);

+     msg->dn = ldb_dn_new(tmp_ctx, ctx->ldb, SYSDB_BASE);

      if (!msg->dn) {

          ret = ENOMEM;

          goto done;

      }

-     ret = ldb_msg_add_fmt(msg, "cn", "%s", domain->name);

+ 

+     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_6);

+     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_zfree(tmp_ctx);

+ 

+     if (ret != EOK) {

+         ret = ldb_transaction_cancel(ctx->ldb);

+     } else {

+         ret = ldb_transaction_commit(ctx->ldb);

+         *ver = SYSDB_VERSION_0_6;

+     }

+     if (ret != LDB_SUCCESS) {

+         ret = EIO;

+     }

+ 

+     return ret;

+ }

+ 

+ static int sysdb_upgrade_06(struct sysdb_ctx *ctx, const char **ver)

+ {

+     TALLOC_CTX *tmp_ctx;

+     int ret;

+     struct ldb_message *msg;

+ 

+     tmp_ctx = talloc_new(ctx);

+     if (!tmp_ctx) {

+         return ENOMEM;

+     }

+ 

+     DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_7));

+ 

+     ret = ldb_transaction_start(ctx->ldb);

+     if (ret != LDB_SUCCESS) {

+         ret = EIO;

+         goto done;

+     }

+ 

+     /* Add new indexes */

+     msg = ldb_msg_new(tmp_ctx);

+     if (!msg) {

+         ret = ENOMEM;

+         goto done;

+     }

+     msg->dn = ldb_dn_new(tmp_ctx, ctx->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(ctx->ldb, msg);

+     if (ret != LDB_SUCCESS) {

+         ret = sysdb_error_to_errno(ret);

+         goto done;

+     }

+ 

+     /* conversion done, upgrade version number */

+     msg = ldb_msg_new(tmp_ctx);

+     if (!msg) {

+         ret = ENOMEM;

+         goto done;

+     }

+     msg->dn = ldb_dn_new(tmp_ctx, ctx->ldb, "cn=sysdb");

+     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_7);

+     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_zfree(tmp_ctx);

+ 

+     if (ret != EOK) {

+         ret = ldb_transaction_cancel(ctx->ldb);

+     } else {

+         ret = ldb_transaction_commit(ctx->ldb);

+         *ver = SYSDB_VERSION_0_7;

+     }

+     if (ret != LDB_SUCCESS) {

+         ret = EIO;

+     }

+ 

+     return ret;

+ }

+ 

+ static int sysdb_upgrade_07(struct sysdb_ctx *ctx, const char **ver)

+ {

+     TALLOC_CTX *tmp_ctx;

+     int ret;

+     struct ldb_message *msg;

+ 

+     tmp_ctx = talloc_new(ctx);

+     if (!tmp_ctx) {

+         return ENOMEM;

+     }

+ 

+     DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_8));

+ 

+     ret = ldb_transaction_start(ctx->ldb);

+     if (ret != LDB_SUCCESS) {

+         ret = EIO;

+         goto done;

+     }

+ 

+     /* Add new indexes */

+     msg = ldb_msg_new(tmp_ctx);

+     if (!msg) {

+         ret = ENOMEM;

+         goto done;

+     }

+     msg->dn = ldb_dn_new(tmp_ctx, ctx->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(ctx->ldb, msg);

+     if (ret != LDB_SUCCESS) {

+         ret = sysdb_error_to_errno(ret);

+         goto done;

+     }

+ 

+     /* conversion done, upgrade version number */

+     msg = ldb_msg_new(tmp_ctx);

+     if (!msg) {

+         ret = ENOMEM;

+         goto done;

+     }

+     msg->dn = ldb_dn_new(tmp_ctx, 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_8);

+     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_zfree(tmp_ctx);

+ 

+     if (ret != EOK) {

+         ret = ldb_transaction_cancel(ctx->ldb);

+     } else {

+         ret = ldb_transaction_commit(ctx->ldb);

+         *ver = SYSDB_VERSION_0_8;

+     }

+     if (ret != LDB_SUCCESS) {

+         ret = EIO;

+     }

+ 

+     return ret;

+ }

+ 

+ static 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 *ctx;

+     const char *base_ldif;

+     struct ldb_ldif *ldif;

+     struct ldb_message *msg;

+     struct ldb_message_element *el;

+     struct ldb_result *res;

+     struct ldb_dn *verdn;

+     const char *version = NULL;

+     int ret;

+ 

+     ctx = talloc_zero(mem_ctx, struct sysdb_ctx);

+     if (!ctx) {

+         return ENOMEM;

+     }

+     ctx->domain = domain;

+ 

+     /* The local provider s the only true MPG,

+      * for the other domains, the provider actually unrolls MPGs */

+     if (strcasecmp(domain->provider, "local") == 0) {

+         ctx->mpg = true;

+     }

+ 

+     ret = sysdb_get_db_file(ctx, domain->provider,

+                             domain->name, db_path,

+                             &ctx->ldb_file);

+     if (ret != EOK) {

+         return ret;

+     }

+     DEBUG(5, ("DB File for %s: %s\n", domain->name, ctx->ldb_file));

+ 

+     ret = sysdb_ldb_connect(ctx, ctx->ldb_file, &ctx->ldb);

+     if (ret != EOK) {

+         DEBUG(1, ("sysdb_ldb_connect failed.\n"));

+         return ret;

+     }

+ 

+     tmp_ctx = talloc_new(ctx);

+     if (!tmp_ctx) {

+         return ENOMEM;

+     }

+ 

+     verdn = ldb_dn_new(tmp_ctx, ctx->ldb, "cn=sysdb");

+     if (!verdn) {

+         ret = EIO;

+         goto done;

+     }

+ 

+     ret = ldb_search(ctx->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) {

+             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(0, ("Wrong DB version (got %s expected %s)\n",

+                           version, SYSDB_VERSION));

+                 ret = EINVAL;

+                 goto done;

+             }

+ 

+             DEBUG(4, ("Upgrading DB [%s] from version: %s\n",

+                       domain->name, version));

+ 

+             if (strcmp(version, SYSDB_VERSION_0_3) == 0) {

+                 ret = sysdb_upgrade_03(ctx, &version);

+                 if (ret != EOK) {

+                     goto done;

+                 }

+             }

+ 

+             if (strcmp(version, SYSDB_VERSION_0_4) == 0) {

+                 ret = sysdb_upgrade_04(ctx, &version);

+                 if (ret != EOK) {

+                     goto done;

+                 }

+             }

+ 

+             if (strcmp(version, SYSDB_VERSION_0_5) == 0) {

+                 ret = sysdb_upgrade_05(ctx, &version);

+                 if (ret != EOK) {

+                     goto done;

+                 }

+             }

+ 

+             if (strcmp(version, SYSDB_VERSION_0_6) == 0) {

+                 ret = sysdb_upgrade_06(ctx, &version);

+                 if (ret != EOK) {

+                     goto done;

+                 }

+             }

+ 

+             if (strcmp(version, SYSDB_VERSION_0_7) == 0) {

+                 ret = sysdb_upgrade_07(ctx, &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(ctx->ldb);

+                 ret = sysdb_ldb_connect(ctx, ctx->ldb_file, &ctx->ldb);

+                 if (ret != EOK) {

+                     DEBUG(1, ("sysdb_ldb_connect failed.\n"));

+                 }

+                 goto done;

+             }

+         }

+ 

+         DEBUG(0,("Unknown DB version [%s], expected [%s] for domain %s!\n",

+                  version?version:"not found", SYSDB_VERSION, domain->name));

+         ret = EINVAL;

+         goto done;

+     }

+ 

+     /* cn=sysdb does not exists, means db is empty, populate */

+ 

+     base_ldif = SYSDB_BASE_LDIF;

+     while ((ldif = ldb_ldif_read_string(ctx->ldb, &base_ldif))) {

+         ret = ldb_add(ctx->ldb, ldif->msg);

+         if (ret != LDB_SUCCESS) {

+             DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!\n",

+                       ret, ldb_errstring(ctx->ldb), domain->name));

+             ret = EIO;

+             goto done;

+         }

+         ldb_ldif_read_free(ctx->ldb, ldif);

+     }

+ 

+     /* == create base domain object == */

+ 

+     msg = ldb_msg_new(tmp_ctx);

+     if (!msg) {

+         ret = ENOMEM;

+         goto done;

+     }

+     msg->dn = ldb_dn_new_fmt(msg, ctx->ldb, SYSDB_DOM_BASE, domain->name);

+     if (!msg->dn) {

+         ret = ENOMEM;

+         goto done;

+     }

+     ret = ldb_msg_add_fmt(msg, "cn", "%s", domain->name);

      if (ret != LDB_SUCCESS) {

          ret = EIO;

          goto done;
@@ -2005,3 +2405,219 @@

      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 *tmpctx = NULL;

+ 

+     tmpctx = talloc_new(NULL);

+     if (!tmpctx) {

+         return ENOMEM;

+     }

+ 

+     ret = sysdb_attrs_get_el(attrs,

+                              SYSDB_NAME,

+                              &sysdb_name_el);

+     if (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(1, ("Original DN is not available.\n"));

+         ret = EINVAL;

+         goto done;

+     } else if (orig_dn_el->num_values == 1) {

+         ret = sysdb_get_rdn(sysdb, tmpctx,

+                             (const char *) orig_dn_el->values[0].data,

+                             &rdn_attr,

+                             &rdn_val);

+         if (ret != EOK) {

+             DEBUG(1, ("Could not get rdn from [%s]\n",

+                       (const char *) orig_dn_el->values[0].data));

+             goto done;

+         }

+     } else {

+         DEBUG(1, ("Should not have more than one origDN\n"));

+         ret = EINVAL;

+         goto done;

+     }

+ 

+     /* First check whether the attribute name matches */

+     DEBUG(8, ("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(3, ("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(1, ("Cannot save entry. Unable to determine groupname\n"));

+         ret = EINVAL;

+         goto done;

+     }

+ 

+     ret = EOK;

+ 

+ done:

+     if (ret != EOK) {

+         DEBUG(1, ("Could not determine primary name: [%d][%s]\n",

+                   ret, strerror(ret)));

+     }

+     talloc_free(tmpctx);

+     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.

+  */

+ errno_t sysdb_attrs_get_aliases(TALLOC_CTX *mem_ctx,

+                                 struct sysdb_attrs *attrs,

+                                 const char *primary,

+                                 const char ***_aliases)

+ {

+     TALLOC_CTX *tmp_ctx = NULL;

+     struct ldb_message_element *sysdb_name_el;

+     size_t i, ai;

+     errno_t ret;

+     const char **aliases = NULL;

+     const char *name;

+ 

+     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 (sysdb_name_el->num_values == 0) {

+         ret = EINVAL;

+         goto done;

+     }

+ 

+     aliases = talloc_array(tmp_ctx, const char *,

+                            sysdb_name_el->num_values);

+     if (!aliases) {

+         ret = ENOMEM;

+         goto done;

+     }

+ 

+     ai = 0;

+     for (i=0; i < sysdb_name_el->num_values; i++) {

+         name = (const char *)sysdb_name_el->values[i].data;

+         if (strcmp(primary, name) != 0) {

+             aliases[ai] = name;

+             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(1, ("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;

+ }

file modified
+35 -5
@@ -46,6 +46,7 @@

  #define SYSDB_NETGROUP_CLASS "netgroup"

  

  #define SYSDB_NAME "name"

+ #define SYSDB_NAME_ALIAS "nameAlias"

  #define SYSDB_OBJECTCLASS "objectClass"

  

  #define SYSDB_NEXTID "nextID"
@@ -62,6 +63,7 @@

  

  #define SYSDB_MEMBER "member"

  #define SYSDB_MEMBERUID "memberUid"

+ #define SYSDB_POSIX "isPosix"

  

  #define SYSDB_DEFAULTGROUP "defaultGroup"

  #define SYSDB_GECOS "gecos"
@@ -105,15 +107,15 @@

  #define SYSDB_NC "objectclass="SYSDB_NETGROUP_CLASS

  #define SYSDB_MPGC "|("SYSDB_UC")("SYSDB_GC")"

  

- #define SYSDB_PWNAM_FILTER "(&("SYSDB_UC")("SYSDB_NAME"=%s))"

+ #define SYSDB_PWNAM_FILTER "(&("SYSDB_UC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))"

  #define SYSDB_PWUID_FILTER "(&("SYSDB_UC")("SYSDB_UIDNUM"=%lu))"

  #define SYSDB_PWENT_FILTER "("SYSDB_UC")"

  

- #define SYSDB_GRNAM_FILTER "(&("SYSDB_GC")("SYSDB_NAME"=%s))"

+ #define SYSDB_GRNAM_FILTER "(&("SYSDB_GC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))"

  #define SYSDB_GRNA2_FILTER "(&("SYSDB_UC")("SYSDB_MEMBEROF"=%s))"

  #define SYSDB_GRGID_FILTER "(&("SYSDB_GC")("SYSDB_GIDNUM"=%lu))"

  #define SYSDB_GRENT_FILTER "("SYSDB_GC")"

- #define SYSDB_GRNAM_MPG_FILTER "(&("SYSDB_MPGC")("SYSDB_NAME"=%s))"

+ #define SYSDB_GRNAM_MPG_FILTER "(&("SYSDB_MPGC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))"

  #define SYSDB_GRGID_MPG_FILTER "(&("SYSDB_MPGC")("SYSDB_GIDNUM"=%lu))"

  #define SYSDB_GRENT_MPG_FILTER "("SYSDB_MPGC")"

  
@@ -153,7 +155,7 @@

                             NULL}

  

  #define SYSDB_INITGR_ATTR SYSDB_MEMBEROF

- #define SYSDB_INITGR_ATTRS {SYSDB_GIDNUM, \

+ #define SYSDB_INITGR_ATTRS {SYSDB_GIDNUM, SYSDB_POSIX, \

                              SYSDB_DEFAULT_ATTRS, \

                              NULL}

  
@@ -194,12 +196,16 @@

                             const char *name, time_t value);

  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);

  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_uint32_t(struct sysdb_attrs *attrs, const char *name,

                               uint32_t *value);

  
@@ -215,11 +221,27 @@

                                      const char *domain,

                                      struct ldb_val *values,

                                      int num_values);

+ 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,

+                                 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);

  

  /* 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 *ctx, void *memctx,

+                       const char *_dn, char **_name, char **_val);

  struct ldb_dn *sysdb_user_dn(struct sysdb_ctx *ctx, void *memctx,

                               const char *domain, const char *name);

  struct ldb_dn *sysdb_group_dn(struct sysdb_ctx *ctx, void *memctx,
@@ -490,7 +512,8 @@

  int sysdb_add_incomplete_group(struct sysdb_ctx *ctx,

                                 struct sss_domain_info *domain,

                                 const char *name,

-                                gid_t gid);

+                                gid_t gid,

+                                const char *original_dn, bool posix);

  

  /* Add netgroup (only basic attrs and w/o checks) */

  int sysdb_add_basic_netgroup(struct sysdb_ctx *ctx,
@@ -719,4 +742,11 @@

                             enum sysdb_member_type type,

                             char **remove_attrs);

  

+ errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx,

+                                  struct sysdb_ctx *sysdb,

+                                  struct sss_domain_info *dom,

+                                  enum sysdb_member_type mtype,

+                                  const char *name,

+                                  char ***_direct_parents);

+ 

  #endif /* __SYS_DB_H__ */

file modified
+34 -18
@@ -60,7 +60,7 @@

      }

  

      errno = 0;

-     l = strtoll((const char *)v->data, NULL, 0);

+     l = strtoll((const char *)v->data, NULL, 10);

      if (errno) {

          return (uint32_t)-1;

      }
@@ -1047,6 +1047,7 @@

      uint32_t id;

      time_t now;

      int ret;

+     bool posix;

  

      if (domain->id_max != 0 && gid != 0 &&

          (gid < domain->id_min || gid > domain->id_max)) {
@@ -1095,22 +1096,6 @@

      ret = sysdb_add_basic_group(tmpctx, ctx, domain, name, gid);

      if (ret) goto done;

  

-     if (gid == 0) {

-         ret = sysdb_get_new_id(tmpctx, ctx, domain, &id);

-         if (ret) goto done;

- 

-         if (!attrs) {

-             attrs = sysdb_new_attrs(tmpctx);

-             if (!attrs) {

-                 ret = ENOMEM;

-                 goto done;

-             }

-         }

- 

-         ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, id);

-         if (ret) goto done;

-     }

- 

      if (!attrs) {

          attrs = sysdb_new_attrs(tmpctx);

          if (!attrs) {
@@ -1119,6 +1104,23 @@

          }

      }

  

+     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) goto done;

+     } else if (ret != EOK) {

+         goto done;

+     }

+ 

+     if (posix && gid == 0) {

+         ret = sysdb_get_new_id(tmpctx, ctx, domain, &id);

+         if (ret) goto done;

+ 

+         ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, id);

+         if (ret) goto done;

+     }

+ 

      now = time(NULL);

  

      ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now);
@@ -1147,7 +1149,9 @@

  int sysdb_add_incomplete_group(struct sysdb_ctx *ctx,

                                 struct sss_domain_info *domain,

                                 const char *name,

-                                gid_t gid)

+                                gid_t gid,

+                                const char *original_dn,

+                                bool posix)

  {

      TALLOC_CTX *tmpctx;

      time_t now;
@@ -1178,6 +1182,14 @@

                                   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;

+     }

+ 

      ret = sysdb_set_group_attr(tmpctx, ctx,

                                 domain, name, attrs, SYSDB_MOD_REP);

  
@@ -2840,6 +2852,10 @@

      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(8, ("Removing attribute [%s] from [%s]\n",

                    remove_attrs[i], name));

          lret = ldb_msg_add_empty(msg, remove_attrs[i],

file modified
+8 -1
@@ -23,13 +23,16 @@

  #ifndef __INT_SYS_DB_H__

  #define __INT_SYS_DB_H__

  

+ #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_5

+ #define SYSDB_VERSION SYSDB_VERSION_0_8

  

  #define SYSDB_BASE_LDIF \

       "dn: @ATTRIBUTES\n" \
@@ -37,6 +40,7 @@

       "cn: CASE_INSENSITIVE\n" \

       "dc: CASE_INSENSITIVE\n" \

       "dn: CASE_INSENSITIVE\n" \

+      "originalDN: CASE_INSENSITIVE\n" \

       "objectclass: CASE_INSENSITIVE\n" \

       "\n" \

       "dn: @INDEXLIST\n" \
@@ -48,7 +52,10 @@

       "@IDXATTR: uidNumber\n" \

       "@IDXATTR: gidNumber\n" \

       "@IDXATTR: lastUpdate\n" \

+      "@IDXATTR: dataExpireTimestamp\n" \

       "@IDXATTR: originalDN\n" \

+      "@IDXATTR: nameAlias\n" \

+      "@IDXONE: 1\n" \

       "\n" \

       "dn: @MODULES\n" \

       "@LIST: asq,memberof\n" \

file modified
+112 -4
@@ -63,7 +63,7 @@

  

      ret = ldb_search(ctx->ldb, tmpctx, &res, base_dn,

                       LDB_SCOPE_SUBTREE, attrs, SYSDB_PWNAM_FILTER,

-                      sanitized_name);

+                      sanitized_name, sanitized_name);

      if (ret) {

          ret = sysdb_error_to_errno(ret);

          goto done;
@@ -248,7 +248,7 @@

  

      ret = ldb_search(ctx->ldb, tmpctx, &res, base_dn,

                       LDB_SCOPE_SUBTREE, attrs, fmt_filter,

-                      sanitized_name);

+                      sanitized_name, sanitized_name);

      if (ret) {

          ret = sysdb_error_to_errno(ret);

          goto done;
@@ -358,7 +358,7 @@

      }

  

      ret = ldb_search(ctx->ldb, tmpctx, &res, base_dn,

-                      LDB_SCOPE_SUBTREE, attrs, fmt_filter);

+                      LDB_SCOPE_SUBTREE, attrs, "%s", fmt_filter);

      if (ret) {

          ret = sysdb_error_to_errno(ret);

          goto done;
@@ -512,7 +512,8 @@

  

      ret = ldb_search(ctx->ldb, tmpctx, &res, base_dn,

                       LDB_SCOPE_SUBTREE, attributes,

-                      SYSDB_PWNAM_FILTER, sanitized_name);

+                      SYSDB_PWNAM_FILTER, sanitized_name,

+                      sanitized_name);

      if (ret) {

          ret = sysdb_error_to_errno(ret);

          goto done;
@@ -888,3 +889,110 @@

      talloc_zfree(tmpctx);

      return ret;

  }

+ 

+ errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx,

+                                  struct sysdb_ctx *sysdb,

+                                  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(1, ("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 = ldb_dn_new_fmt(tmp_ctx, sysdb_ctx_get_ldb(sysdb),

+                             SYSDB_TMPL_GROUP_BASE, dom->name);

+     if (!basedn) {

+         ret = ENOMEM;

+         goto done;

+     }

+ 

+     DEBUG(8, ("searching sysdb with filter [%s]\n", member_filter));

+ 

+     ret = sysdb_search_entry(tmp_ctx, 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 && ret != ENOENT) {

+         DEBUG(2, ("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(1, ("A group with no name?\n"));

+             ret = EIO;

+             goto done;

+         }

+         pi++;

+     }

+     direct_parents[pi] = NULL;

+ 

+     DEBUG(7, ("%s is a member of %d sysdb groups\n",

+               name, direct_sysdb_count));

+     *_direct_parents = talloc_steal(mem_ctx, direct_parents);

+     ret = EOK;

+ done:

+     talloc_free(tmp_ctx);

+     return ret;

+ }

file modified
+30 -71
@@ -1,95 +1,54 @@

  [sssd]

  config_file_version = 2

- 

- # Number of times services should attempt to reconnect in the

- # event of a crash or restart before they give up

- reconnection_retries = 3

- 

- # If a back end is particularly slow you can raise this timeout here

- sbus_timeout = 30

  services = nss, pam

- 

  # SSSD will not start if you do not configure any domains.

  # Add new domain configurations as [domain/<NAME>] 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 = LOCAL,LDAP

+ ; domains = LDAP

  

  [nss]

- # The following prevents SSSD from searching for the root user/group in

- # all domains (you can add here a comma-separated list of system accounts that

- # are always going to be /etc/passwd users, or that you want to filter out).

- filter_groups = root

- filter_users = root

- reconnection_retries = 3

- 

- # The entry_cache_nowait_percentage indicates the percentage of the

- # entry_cache_timeout to wait before updating the cache out-of-band.

- # (NSS requests will still be returned from cache until the full

- # entry_cache_timeout). Setting this value to 0 turns this feature

- # off (default).

- ; entry_cache_nowait_percentage = 300

  

  [pam]

- reconnection_retries = 3

  

- # Example domain configurations

- # Note that enabling enumeration in the following configurations will have a

- # moderate performance impact while enumerations are actually running, and

- # may increase the time necessary to detect network disconnection.

- # Consequently, the default value for enumeration is FALSE.

- # Refer to the sssd.conf man page for full details.

- 

- # Example LOCAL domain that stores all users natively in the SSSD internal

- # directory. These local users and groups are not visible in /etc/passwd; it

- # now contains only root and system accounts.

- ; [domain/LOCAL]

- ; description = LOCAL Users domain

- ; id_provider = local

- ; enumerate = true

- ; min_id = 500

- ; max_id = 999

- 

- # Example native LDAP domain

- # ldap_schema can be set to "rfc2307", which uses the "memberuid" attribute

- # for group membership, or to "rfc2307bis", which uses the "member" attribute

- # to denote group membership. Changes to this setting affect only how we

- # determine the groups a user belongs to and will have no negative effect on

- # data about the user itself. If you do not know this value, ask an

- # administrator.

+ # 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

- ; ldap_tls_reqcert = demand

+ # 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

- ; enumerate = False

- ; entry_cache_timeout = 5400

- 

- # Example LDAP domain where the LDAP server is an Active Directory server.

  

+ # 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]

- ; description = LDAP domain with AD server

- ; enumerate = false

- ; min_id = 1000

- ;

  ; id_provider = ldap

- ; auth_provider = ldap

- ; ldap_uri = ldap://your.ad.server.com

+ ; auth_provider = krb5

+ ; chpass_provider = krb5

+ ;

+ ; ldap_uri = ldap://your.ad.example.com

+ ; ldap_search_base = dc=example,dc=com

  ; ldap_schema = rfc2307bis

- ; ldap_default_bind_dn = cn=Administrator,cn=Users,dc=example,dc=com

- ; ldap_default_authtok_type = password

- ; ldap_default_authtok = YOUR_PASSWORD

- ; ldap_user_object_class = person

- ; ldap_user_name = msSFU30Name

- ; ldap_user_uid_number = msSFU30UidNumber

- ; ldap_user_gid_number = msSFU30GidNumber

- ; ldap_user_home_directory = msSFU30HomeDirectory

- ; ldap_user_shell = msSFU30LoginShell

- ; ldap_user_principal = userPrincipalName

+ ; ldap_sasl_mech = GSSAPI

+ ; ldap_user_object_class = user

  ; ldap_group_object_class = group

- ; ldap_group_name = msSFU30Name

- ; ldap_group_gid_number = msSFU30GidNumber

- ; ldap_force_upper_case_realm = True

+ ; 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

file added
+11
@@ -0,0 +1,11 @@

+ PKG_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 

\ No newline at end of file

file modified
+1 -1
@@ -43,7 +43,7 @@

  SAVE_LIBS=$LIBS

  CFLAGS="$CFLAGS $OPENLDAP_CFLAGS"

  LIBS="$LIBS $OPENLDAP_LIBS"

- AC_CHECK_FUNCS([ldap_control_create])

+ AC_CHECK_FUNCS([ldap_control_create ldap_init_fd])

  AC_CHECK_MEMBERS([struct ldap_conncb.lc_arg],

                   [AC_RUN_IFELSE(

                     [AC_LANG_PROGRAM(

@@ -18,3 +18,6 @@

  )

  

  AM_CONDITIONAL(BUILD_ARES_DATA, test x$ares_data = x1)

+ 

+ dnl Check if this particular version of c-ares support the new TTL structures

+ AC_CHECK_TYPES([struct ares_addrttl, struct ares_addr6ttl], [], [], [#include <ares.h>])

@@ -0,0 +1,14 @@

+ AC_CHECK_HEADERS(unistr.h,

+     [AC_CHECK_LIB([unistring], [u8_strlen], [ UNISTRING_LIBS="-lunistring" ], [AC_MSG_ERROR([No usable libunistring library found])])],

+     [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])])],

+     [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])])],

+     [AC_MSG_ERROR([libunistring header files are not installed])]

+ ) 

\ No newline at end of file

file modified
+10 -1
@@ -1,8 +1,17 @@

  AC_PATH_PROG(NSUPDATE, nsupdate)

- AC_MSG_CHECKING(for 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_WARN([no. Will build without the 'realm' directive])

+   fi

+ 

  else

    AC_MSG_ERROR([no. nsupdate is not available])

  fi

file modified
+20
@@ -56,3 +56,23 @@

  ])

  

  

+ dnl Checks for a couple of functions we use that may not be defined

+ dnl in some older python versions used e.g. on RHEL5

+ 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_TYPE(Py_ssize_t,

+                   [ AC_DEFINE_UNQUOTED(HAVE_PY_SSIZE_T, 1, [Native Py_ssize_t type]) ],

+                   [],

+                   [[#include <Python.h>]])

+ 

+     AC_CHECK_FUNCS([PySet_New PySet_Add PyErr_NewExceptionWithDoc])

+     AC_CHECK_DECLS([PySet_Check, PyModule_AddIntMacro, PyUnicode_FromString], [], [], [[#include <Python.h>]])

+ 

+     CPPFLAGS="$save_CPPFLAGS"

+     LIBS="$save_LIBS"

+ ])

file modified
+28 -9
@@ -1,7 +1,7 @@

  /*

     SSSD memberof module

  

-    Copyright (C) Simo Sorce <idra@samba.org> 2008

+    Copyright (C) Simo Sorce <idra@samba.org> 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
@@ -17,6 +17,11 @@

     along with this program.  If not, see <http://www.gnu.org/licenses/>.

  */

  

+ /* Temporary workaround, will be fixed in ldb upstream soon */

+ #ifndef LDB_VERSION

+ #define LDB_VERSION "0.9.22"

+ #endif

+ 

  #include <string.h>

  #include "ldb_module.h"

  #include "util/util.h"
@@ -1156,6 +1161,7 @@

  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 void free_delop_contents(struct mbof_del_operation *delop);

  

  

  static int memberof_del(struct ldb_module *module, struct ldb_request *req)
@@ -1727,16 +1733,9 @@

  static int mbof_del_execute_cont(struct mbof_del_operation *delop)

  {

      struct mbof_del_ancestors_ctx *anc_ctx;

-     struct mbof_del_operation *parent;

-     struct mbof_del_ctx *del_ctx;

-     struct mbof_ctx *ctx;

      struct mbof_dn_array *new_list;

      int i;

  

-     del_ctx = delop->del_ctx;

-     parent = delop->parent;

-     ctx = del_ctx->ctx;

- 

      anc_ctx = talloc_zero(delop, struct mbof_del_ancestors_ctx);

      if (!anc_ctx) {

          return LDB_ERR_OPERATIONS_ERROR;
@@ -2184,6 +2183,8 @@

          return ret;

      }

  

+     free_delop_contents(delop);

+ 

      if (nextop) {

          return mbof_del_execute_op(nextop);

      }
@@ -2407,7 +2408,16 @@

      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 */

  
@@ -2729,6 +2739,7 @@

                          added->dns[j] = added->dns[j+1];

                      }

                      added->num--;

+                     i--;

                  }

              }

          }
@@ -3630,3 +3641,11 @@

      .modify = memberof_mod,

      .del = memberof_del,

  };

+ 

+ int ldb_init_module(const char *version)

+ {

+ #ifdef LDB_MODULE_CHECK_VERSION

+     LDB_MODULE_CHECK_VERSION(version);

+ #endif

+     return ldb_register_module(&ldb_memberof_module_ops);

+ }

file modified
+6 -6
@@ -134,8 +134,8 @@

  	if [ -z $$recursion ]; then \

  		for lang in $(LINGUAS); do \

  			if [ -d $$lang ]; then \

- 				sources=$$(ls $$lang/*.xml); \

- 				manpages=$$(echo $$sources | $(SED) 's/\.xml//'); \

+ 				sources=$$(ls -1 $$lang/*.xml); \

+ 				manpages=$$(echo $$sources | $(SED) 's/\.xml//g'); \

  				$(MAKE) recursion=1 man_MANS="$$manpages"; \

  			fi \

  		done \
@@ -146,8 +146,8 @@

  install-data-local-yes:

  	for lang in $(LINGUAS); do \

  		if [ -d $$lang ]; then \

- 			sources=$$(ls $$lang/*.xml); \

- 			manpages=$$(echo $$sources | $(SED) 's/\.xml//'); \

+ 			sources=$$(ls -1 $$lang/*.xml); \

+ 			manpages=$$(echo $$sources | $(SED) 's/\.xml//g'); \

  			$(MAKE) install-man \

  				mandir="$(mandir)/$$lang" \

  				man_MANS="$$manpages"; \
@@ -159,8 +159,8 @@

  uninstall-local-yes:

  	for lang in $(LINGUAS); do \

  		if [ -d $$lang ]; then \

- 			sources=$$(ls $$lang/*.xml); \

- 			manpages=$$(echo $$sources | $(SED) 's/\.xml//'); \

+ 			sources=$$(ls -1 $$lang/*.xml); \

+ 			manpages=$$(echo $$sources | $(SED) 's/\.xml//g'); \

  			$(MAKE) uninstall-man \

  				mandir="$(mandir)/$$lang" \

  				man_MANS="$$manpages"; \

file modified
+11
@@ -23,6 +23,9 @@

          <cmdsynopsis>

              <command>pam_sss.so</command>

              <arg choice='opt'>

+                 <replaceable>quiet</replaceable>

+             </arg>

+             <arg choice='opt'>

                  <replaceable>forward_pass</replaceable>

              </arg>

              <arg choice='opt'>
@@ -49,6 +52,14 @@

          <variablelist remap='IP'>

              <varlistentry>

                  <term>

+                     <option>quiet</option>

+                 </term>

+                 <listitem>

+                     <para>Suppress log messages for unknown users.</para>

+                 </listitem>

+             </varlistentry>

+             <varlistentry>

+                 <term>

                      <option>forward_pass</option>

                  </term>

                  <listitem>

file added
+4992
The added file is too large to be shown here, see it at: src/man/po/ar.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/as.po
file added
+6017
The added file is too large to be shown here, see it at: src/man/po/ast.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/bal.po
file added
+6017
The added file is too large to be shown here, see it at: src/man/po/bg.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/bn.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/bn_IN.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/ca.po
file modified
+825 -538
@@ -7,7 +7,7 @@

  msgstr ""

  "Project-Id-Version: sss_daemon 1.2.3\n"

  "Report-Msgid-Bugs-To: sssd-devel@redhat.com\n"

- "POT-Creation-Date: 2011-01-24 13:36-0500\n"

+ "POT-Creation-Date: 2011-10-18 13:34-0300\n"

  "PO-Revision-Date: 2010-10-25 10:46+0300\n"

  "Last-Translator: Automatically generated\n"

  "Language-Team: none\n"
@@ -59,7 +59,7 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sss_groupmod.8.xml:30 sssd-ldap.5.xml:21 pam_sss.8.xml:41

+ #: sss_groupmod.8.xml:30 sssd-ldap.5.xml:21 pam_sss.8.xml:44

  #: sssd_krb5_locator_plugin.8.xml:20 sssd-simple.5.xml:22 sssd-ipa.5.xml:21

  #: sssd.8.xml:29 sss_obfuscate.8.xml:30 sss_useradd.8.xml:30

  #: sssd-krb5.5.xml:21 sss_groupadd.8.xml:30 sss_userdel.8.xml:30
@@ -77,7 +77,7 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sss_groupmod.8.xml:39 pam_sss.8.xml:48 sssd.8.xml:42 sss_obfuscate.8.xml:59

+ #: sss_groupmod.8.xml:39 pam_sss.8.xml:51 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

  msgid "OPTIONS"
@@ -118,10 +118,10 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sss_groupmod.8.xml:72 sssd.conf.5.xml:1008 sssd-ldap.5.xml:1389

- #: pam_sss.8.xml:128 sssd_krb5_locator_plugin.8.xml:75 sssd-simple.5.xml:143

- #: sssd-ipa.5.xml:191 sssd.8.xml:166 sss_obfuscate.8.xml:104

- #: sss_useradd.8.xml:167 sssd-krb5.5.xml:424 sss_groupadd.8.xml:58

+ #: sss_groupmod.8.xml:72 sssd.conf.5.xml:1130 sssd-ldap.5.xml:1432

+ #: pam_sss.8.xml:139 sssd_krb5_locator_plugin.8.xml:75 sssd-simple.5.xml:143

+ #: sssd-ipa.5.xml:248 sssd.8.xml:166 sss_obfuscate.8.xml:103

+ #: sss_useradd.8.xml:167 sssd-krb5.5.xml:427 sss_groupadd.8.xml:58

  #: sss_userdel.8.xml:93 sss_groupdel.8.xml:46 sss_groupshow.8.xml:58

  #: sss_usermod.8.xml:138

  msgid "SEE ALSO"
@@ -241,7 +241,7 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><title>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><title>

- #: sssd.conf.5.xml:70 sssd.conf.5.xml:854

+ #: sssd.conf.5.xml:70 sssd.conf.5.xml:976

  msgid "Section parameters"

  msgstr ""

  
@@ -280,13 +280,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:93 sssd.conf.5.xml:234

+ #: sssd.conf.5.xml:93 sssd.conf.5.xml:254

  msgid "reconnection_retries (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:96 sssd.conf.5.xml:237

+ #: sssd.conf.5.xml:96 sssd.conf.5.xml:257

  msgid ""

  "Number of times services should attempt to reconnect in the event of a Data "

  "Provider crash or restart before they give up"
@@ -294,7 +294,7 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:101 sssd.conf.5.xml:242

+ #: sssd.conf.5.xml:101 sssd.conf.5.xml:262

  msgid "Default: 3"

  msgstr ""

  
@@ -415,6 +415,32 @@

  "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:189

+ msgid "krb5_rcache_dir (string)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:192

+ 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:196

+ 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:202

+ msgid ""

+ "Default: Distribution-specific and specified at build-time. "

+ "(__LIBKRB5_DEFAULTS__ if not configured)"

+ msgstr ""

+ 

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

  #: sssd.conf.5.xml:63

  msgid ""
@@ -428,13 +454,13 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd.conf.5.xml:195

+ #: sssd.conf.5.xml:215

  msgid "SERVICES SECTIONS"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:197

+ #: sssd.conf.5.xml:217

  msgid ""

  "Settings that can be used to configure different services are described in "

  "this section. They should reside in the [<replaceable>$NAME</replaceable>] "
@@ -444,25 +470,25 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><title>

  #. type: Content of: <reference><refentry><refsect1><refsect2><title>

- #: sssd.conf.5.xml:204

+ #: sssd.conf.5.xml:224

  msgid "General service configuration options"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

- #: sssd.conf.5.xml:206

+ #: sssd.conf.5.xml:226

  msgid "These options can be used to configure any service."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:210

+ #: sssd.conf.5.xml:230

  msgid "debug_level (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:213

+ #: sssd.conf.5.xml:233

  msgid ""

  "Sets the debug level for the service. The value can be in range from 0 (only "

  "critical messages) to 10 (very verbose)."
@@ -470,38 +496,38 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:218 sssd.conf.5.xml:312

+ #: sssd.conf.5.xml:238 sssd.conf.5.xml:332

  msgid "Default: 0"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:223 sssd.8.xml:58

+ #: sssd.conf.5.xml:243 sssd.8.xml:58

  msgid "debug_timestamps (bool)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:226 sssd.8.xml:61

+ #: sssd.conf.5.xml:246 sssd.8.xml:61

  msgid "Add a timestamp to the debug messages"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:229 sssd.conf.5.xml:353 sssd-ldap.5.xml:1015

- #: sssd-ldap.5.xml:1120 sssd-ipa.5.xml:155

+ #: sssd.conf.5.xml:249 sssd.conf.5.xml:373 sssd-ldap.5.xml:1058

+ #: sssd-ldap.5.xml:1163 sssd-ipa.5.xml:155

  msgid "Default: true"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:247

+ #: sssd.conf.5.xml:267

  msgid "command (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:250

+ #: sssd.conf.5.xml:270

  msgid ""

  "By default, the executable representing this service is called <command>sssd_"

  "${service_name}</command>.  This directive allows to change the executable "
@@ -511,32 +537,32 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:258

+ #: sssd.conf.5.xml:278

  msgid "Default: <command>sssd_${service_name}</command>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><title>

  #. type: Content of: <reference><refentry><refsect1><refsect2><title>

- #: sssd.conf.5.xml:266

+ #: sssd.conf.5.xml:286

  msgid "NSS configuration options"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

- #: sssd.conf.5.xml:268

+ #: sssd.conf.5.xml:288

  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>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:273

+ #: sssd.conf.5.xml:293

  msgid "enum_cache_timeout (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:276

+ #: sssd.conf.5.xml:296

  msgid ""

  "How many seconds should nss_sss cache enumerations (requests for info about "

  "all users)"
@@ -544,19 +570,19 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:280

+ #: sssd.conf.5.xml:300

  msgid "Default: 120"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:285

+ #: sssd.conf.5.xml:305

  msgid "entry_cache_nowait_percentage (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:288

+ #: sssd.conf.5.xml:308

  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 "
@@ -565,7 +591,7 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:294

+ #: sssd.conf.5.xml:314

  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 "
@@ -576,7 +602,7 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:304

+ #: sssd.conf.5.xml:324

  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 "
@@ -586,13 +612,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:317

+ #: sssd.conf.5.xml:337

  msgid "entry_negative_timeout (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:320

+ #: sssd.conf.5.xml:340

  msgid ""

  "Specifies for how many seconds nss_sss should cache negative cache hits "

  "(that is, queries for invalid database entries, like nonexistent ones)  "
@@ -601,18 +627,18 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:326 sssd-krb5.5.xml:223

+ #: sssd.conf.5.xml:346 sssd-krb5.5.xml:223

  msgid "Default: 15"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:331

+ #: sssd.conf.5.xml:351

  msgid "filter_users, filter_groups (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:334

+ #: sssd.conf.5.xml:354

  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-"
@@ -622,32 +648,179 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:341

+ #: sssd.conf.5.xml:361

  msgid "Default: root"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:346

+ #: sssd.conf.5.xml:366

  msgid "filter_users_in_groups (bool)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:349

+ #: sssd.conf.5.xml:369

  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:378

+ msgid "override_homedir (string)"

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:387 sssd-krb5.5.xml:166

+ msgid "%u"

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:388 sssd-krb5.5.xml:167

+ msgid "login name"

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:391 sssd-krb5.5.xml:170

+ msgid "%U"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:392

+ msgid "UID number"

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:395 sssd-krb5.5.xml:188

+ msgid "%d"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:396

+ msgid "domain name"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:399

+ msgid "%f"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:400

+ msgid "fully qualified user name (user@domain)"

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:403 sssd-krb5.5.xml:200

+ msgid "%%"

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:404 sssd-krb5.5.xml:201

+ msgid "a literal '%'"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:381

+ 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: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:410

+ msgid "This option can also be set per-domain."

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:415

+ msgid "allowed_shells (string)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:418

+ 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:421

+ 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:425

+ 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:430

+ 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:435

+ 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:438

+ 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:442

+ 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:447

+ msgid "vetoed_shells (string)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:450

+ 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:455

+ msgid "shell_fallback (string)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:458

+ 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:462

+ msgid "Default: /bin/sh"

+ msgstr ""

+ 

  # type: Content of: <reference><refentry><refsect1><refsect2><title>

  #. type: Content of: <reference><refentry><refsect1><refsect2><title>

- #: sssd.conf.5.xml:360

+ #: sssd.conf.5.xml:469

  msgid "PAM configuration options"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

- #: sssd.conf.5.xml:362

+ #: sssd.conf.5.xml:471

  msgid ""

  "These options can be used to configure the Pluggable Authentication Module "

  "(PAM) service."
@@ -655,13 +828,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:367

+ #: sssd.conf.5.xml:476

  msgid "offline_credentials_expiration (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:370

+ #: sssd.conf.5.xml:479

  msgid ""

  "If the authentication provider is offline, how long should we allow cached "

  "logins (in days since the last successful online login)."
@@ -669,19 +842,19 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:375 sssd.conf.5.xml:388

+ #: sssd.conf.5.xml:484 sssd.conf.5.xml:497

  msgid "Default: 0 (No limit)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:381

+ #: sssd.conf.5.xml:490

  msgid "offline_failed_login_attempts (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:384

+ #: sssd.conf.5.xml:493

  msgid ""

  "If the authentication provider is offline, how many failed login attempts "

  "are allowed."
@@ -689,13 +862,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:394

+ #: sssd.conf.5.xml:503

  msgid "offline_failed_login_delay (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:397

+ #: sssd.conf.5.xml:506

  msgid ""

  "The time in minutes which has to pass after offline_failed_login_attempts "

  "has been reached before a new login attempt is possible."
@@ -703,7 +876,7 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:402

+ #: sssd.conf.5.xml:511

  msgid ""

  "If set to 0 the user cannot authenticate offline if "

  "offline_failed_login_attempts has been reached. Only a successful online "
@@ -712,19 +885,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:408 sssd.conf.5.xml:461 sssd.conf.5.xml:793

+ #: sssd.conf.5.xml:517 sssd.conf.5.xml:570 sssd.conf.5.xml:906

  msgid "Default: 5"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:414

+ #: sssd.conf.5.xml:523

  msgid "pam_verbosity (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:417

+ #: sssd.conf.5.xml:526

  msgid ""

  "Controls what kind of messages are shown to the user during authentication. "

  "The higher the number to more messages are displayed."
@@ -732,47 +905,47 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:422

+ #: sssd.conf.5.xml:531

  msgid "Currently sssd supports the following values:"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:425

+ #: sssd.conf.5.xml:534

  msgid "<emphasis>0</emphasis>: do not show any message"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:428

+ #: sssd.conf.5.xml:537

  msgid "<emphasis>1</emphasis>: show only important messages"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:432

+ #: sssd.conf.5.xml:541

  msgid "<emphasis>2</emphasis>: show informational messages"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:435

+ #: sssd.conf.5.xml:544

  msgid "<emphasis>3</emphasis>: show all messages and debug information"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:439

+ #: sssd.conf.5.xml:548

  msgid "Default: 1"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:444

+ #: sssd.conf.5.xml:553

  msgid "pam_id_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:447

+ #: sssd.conf.5.xml:556

  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 "
@@ -780,7 +953,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:453

+ #: sssd.conf.5.xml:562

  msgid ""

  "A complete PAM conversation may perform multiple PAM requests, such as "

  "account management and session opening. This option controls (on a per-"
@@ -789,17 +962,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:467

+ #: sssd.conf.5.xml:576

  msgid "pam_pwd_expiration_warning (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:470

+ #: sssd.conf.5.xml:579

  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:473

+ #: sssd.conf.5.xml:582

  msgid ""

  "Please note that the backend server has to provide information about the "

  "expiration time of the password.  If this information is missing, sssd "
@@ -807,25 +980,25 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:479

+ #: sssd.conf.5.xml:588

  msgid "Default: 7"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd.conf.5.xml:488

+ #: sssd.conf.5.xml:597

  msgid "DOMAIN SECTIONS"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:495

+ #: sssd.conf.5.xml:604

  msgid "min_id,max_id (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:498

+ #: sssd.conf.5.xml:607

  msgid ""

  "UID and GID limits for the domain. If a domain contains an entry that is "

  "outside these limits, it is ignored."
@@ -833,7 +1006,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:503

+ #: sssd.conf.5.xml:612

  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-"
@@ -843,19 +1016,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:510

+ #: sssd.conf.5.xml:619

  msgid "Default: 1 for min_id, 0 (no limit) for max_id"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:516

+ #: sssd.conf.5.xml:625

  msgid "timeout (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:519

+ #: sssd.conf.5.xml:628

  msgid ""

  "Timeout in seconds between heartbeats for this domain.  This is used to "

  "ensure that the backend process is alive and capable of answering requests."
@@ -863,19 +1036,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:524

+ #: sssd.conf.5.xml:633

  msgid "Default: 10"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:530

+ #: sssd.conf.5.xml:639

  msgid "enumerate (bool)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:533

+ #: sssd.conf.5.xml:642

  msgid ""

  "Determines if a domain can be enumerated. This parameter can have one of the "

  "following values:"
@@ -883,25 +1056,25 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:537

+ #: sssd.conf.5.xml:646

  msgid "TRUE = Users and groups are enumerated"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:540

+ #: sssd.conf.5.xml:649

  msgid "FALSE = No enumerations for this domain"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:543 sssd.conf.5.xml:591 sssd.conf.5.xml:645

+ #: sssd.conf.5.xml:652 sssd.conf.5.xml:704 sssd.conf.5.xml:758

  msgid "Default: FALSE"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:546

+ #: sssd.conf.5.xml:655

  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 "
@@ -911,7 +1084,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:556

+ #: sssd.conf.5.xml:665

  msgid ""

  "While the first enumeration is running, requests for the complete user or "

  "group lists may return no results until it completes."
@@ -919,7 +1092,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:561

+ #: sssd.conf.5.xml:670

  msgid ""

  "Further, enabling enumeration may increase the time necessary to detect "

  "network disconnection, as longer timeouts are required to ensure that "
@@ -929,13 +1102,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:572

+ #: sssd.conf.5.xml:681

  msgid "entry_cache_timeout (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:575

+ #: sssd.conf.5.xml:684

  msgid ""

  "How many seconds should nss_sss consider entries valid before asking the "

  "backend again"
@@ -943,31 +1116,36 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:579

+ #: sssd.conf.5.xml:688

  msgid "Default: 5400"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:584

+ #: sssd.conf.5.xml:693

  msgid "cache_credentials (bool)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:587

+ #: sssd.conf.5.xml:696

  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:700

+ msgid "User credentials are stored in a SHA512 hash, not in plaintext"

+ msgstr ""

+ 

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:596

+ #: sssd.conf.5.xml:709

  msgid "account_cache_expiration (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:599

+ #: sssd.conf.5.xml:712

  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 "
@@ -977,55 +1155,55 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:606

+ #: sssd.conf.5.xml:719

  msgid "Default: 0 (unlimited)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:612

+ #: sssd.conf.5.xml:725

  msgid "id_provider (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:615

+ #: sssd.conf.5.xml:728

  msgid "The Data Provider identity backend to use for this domain."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:619

+ #: sssd.conf.5.xml:732

  msgid "Supported backends:"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:622

+ #: sssd.conf.5.xml:735

  msgid "proxy: Support a legacy NSS provider"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:625

+ #: sssd.conf.5.xml:738

  msgid "local: SSSD internal local provider"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:628

+ #: sssd.conf.5.xml:741

  msgid "ldap: LDAP provider"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:634

+ #: sssd.conf.5.xml:747

  msgid "use_fully_qualified_names (bool)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:637

+ #: sssd.conf.5.xml:750

  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, "
@@ -1035,13 +1213,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:650

+ #: sssd.conf.5.xml:763

  msgid "auth_provider (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:653

+ #: sssd.conf.5.xml:766

  msgid ""

  "The authentication provider used for the domain.  Supported auth providers "

  "are:"
@@ -1049,7 +1227,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:657

+ #: sssd.conf.5.xml:770

  msgid ""

  "<quote>ldap</quote> for native LDAP authentication. See <citerefentry> "

  "<refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</manvolnum> </"
@@ -1058,7 +1236,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:664

+ #: sssd.conf.5.xml:777

  msgid ""

  "<quote>krb5</quote> for Kerberos authentication. See <citerefentry> "

  "<refentrytitle>sssd-krb5</refentrytitle> <manvolnum>5</manvolnum> </"
@@ -1067,20 +1245,20 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:671

+ #: sssd.conf.5.xml:784

  msgid ""

  "<quote>proxy</quote> for relaying authentication to some other PAM target."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:674

+ #: sssd.conf.5.xml:787

  msgid "<quote>none</quote> disables authentication explicitly."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:677

+ #: sssd.conf.5.xml:790

  msgid ""

  "Default: <quote>id_provider</quote> is used if it is set and can handle "

  "authentication requests."
@@ -1088,13 +1266,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:683

+ #: sssd.conf.5.xml:796

  msgid "access_provider (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:686

+ #: sssd.conf.5.xml:799

  msgid ""

  "The access control provider used for the domain.  There are two built-in "

  "access providers (in addition to any included in installed backends)  "
@@ -1103,19 +1281,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:692

+ #: sssd.conf.5.xml:805

  msgid "<quote>permit</quote> always allow access."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:695

+ #: sssd.conf.5.xml:808

  msgid "<quote>deny</quote> always deny access."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:698

+ #: sssd.conf.5.xml:811

  msgid ""

  "<quote>simple</quote> access control based on access or deny lists. See "

  "<citerefentry> <refentrytitle>sssd-simple</refentrytitle> <manvolnum>5</"
@@ -1125,19 +1303,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:705

+ #: sssd.conf.5.xml:818

  msgid "Default: <quote>permit</quote>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:710

+ #: sssd.conf.5.xml:823

  msgid "chpass_provider (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:713

+ #: sssd.conf.5.xml:826

  msgid ""

  "The provider which should handle change password operations for the domain.  "

  "Supported change password providers are:"
@@ -1145,7 +1323,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:718

+ #: sssd.conf.5.xml:831

  msgid ""

  "<quote>ipa</quote> to change a password stored in an IPA server.  See "

  "<citerefentry> <refentrytitle>sssd-ipa</refentrytitle> <manvolnum>5</"
@@ -1154,7 +1332,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:726

+ #: sssd.conf.5.xml:839

  msgid ""

  "<quote>ldap</quote> to change a password stored in a LDAP server.  See "

  "<citerefentry> <refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</"
@@ -1163,7 +1341,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:734

+ #: sssd.conf.5.xml:847

  msgid ""

  "<quote>krb5</quote> to change the Kerberos password. See <citerefentry> "

  "<refentrytitle>sssd-krb5</refentrytitle> <manvolnum>5</manvolnum> </"
@@ -1172,20 +1350,20 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:742

+ #: sssd.conf.5.xml:855

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:746

+ #: sssd.conf.5.xml:859

  msgid "<quote>none</quote> disallows password changes explicitly."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:749

+ #: sssd.conf.5.xml:862

  msgid ""

  "Default: <quote>auth_provider</quote> is used if it is set and can handle "

  "change password requests."
@@ -1193,13 +1371,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:756

+ #: sssd.conf.5.xml:869

  msgid "lookup_family_order (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:759

+ #: sssd.conf.5.xml:872

  msgid ""

  "Provides the ability to select preferred address family to use when "

  "performing DNS lookups."
@@ -1207,49 +1385,49 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:763

+ #: sssd.conf.5.xml:876

  msgid "Supported values:"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:766

+ #: sssd.conf.5.xml:879

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:769

+ #: sssd.conf.5.xml:882

  msgid "ipv4_only: Only attempt to resolve hostnames to IPv4 addresses."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:772

+ #: sssd.conf.5.xml:885

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:775

+ #: sssd.conf.5.xml:888

  msgid "ipv6_only: Only attempt to resolve hostnames to IPv6 addresses."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:778

+ #: sssd.conf.5.xml:891

  msgid "Default: ipv4_first"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:784

+ #: sssd.conf.5.xml:897

  msgid "dns_resolver_timeout (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:787

+ #: sssd.conf.5.xml:900

  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, "
@@ -1258,13 +1436,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:799

+ #: sssd.conf.5.xml:912

  msgid "dns_discovery_domain (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:802

+ #: sssd.conf.5.xml:915

  msgid ""

  "If service discovery is used in the back end, specifies the domain part of "

  "the service discovery DNS query."
@@ -1272,12 +1450,22 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:806

+ #: sssd.conf.5.xml:919

  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:925

+ msgid "override_gid (integer)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:928

+ msgid "Override the primary GID value with the one specified."

+ msgstr ""

+ 

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:490

+ #: sssd.conf.5.xml:599

  msgid ""

  "These configuration options can be present in a domain configuration "

  "section, that is, in a section called <quote>[domain/<replaceable>NAME</"
@@ -1286,19 +1474,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:818

+ #: sssd.conf.5.xml:940

  msgid "proxy_pam_target (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:821

+ #: sssd.conf.5.xml:943

  msgid "The proxy target PAM proxies to."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:824

+ #: sssd.conf.5.xml:946

  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."
@@ -1306,13 +1494,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:832

+ #: sssd.conf.5.xml:954

  msgid "proxy_lib_name (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:835

+ #: sssd.conf.5.xml:957

  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), "
@@ -1320,7 +1508,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:814

+ #: sssd.conf.5.xml:936

  msgid ""

  "Options valid for proxy domains.  <placeholder type=\"variablelist\" id="

  "\"0\"/>"
@@ -1328,13 +1516,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><title>

  #. type: Content of: <reference><refentry><refsect1><refsect2><title>

- #: sssd.conf.5.xml:847

+ #: sssd.conf.5.xml:969

  msgid "The local domain section"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

- #: sssd.conf.5.xml:849

+ #: sssd.conf.5.xml:971

  msgid ""

  "This section contains settings for domain that stores users and groups in "

  "SSSD native database, that is, a domain that uses "
@@ -1343,31 +1531,31 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:856

+ #: sssd.conf.5.xml:978

  msgid "default_shell (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:859

+ #: sssd.conf.5.xml:981

  msgid "The default shell for users created with SSSD userspace tools."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:863

+ #: sssd.conf.5.xml:985

  msgid "Default: <filename>/bin/bash</filename>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:868

+ #: sssd.conf.5.xml:990

  msgid "base_directory (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:871

+ #: sssd.conf.5.xml:993

  msgid ""

  "The tools append the login name to <replaceable>base_directory</replaceable> "

  "and use that as the home directory."
@@ -1375,18 +1563,18 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:876

+ #: sssd.conf.5.xml:998

  msgid "Default: <filename>/home</filename>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:881

+ #: sssd.conf.5.xml:1003

  msgid "create_homedir (bool)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:884

+ #: sssd.conf.5.xml:1006

  msgid ""

  "Indicate if a home directory should be created by default for new users.  "

  "Can be overridden on command line."
@@ -1394,18 +1582,18 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:888 sssd.conf.5.xml:900

+ #: sssd.conf.5.xml:1010 sssd.conf.5.xml:1022

  msgid "Default: TRUE"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:893

+ #: sssd.conf.5.xml:1015

  msgid "remove_homedir (bool)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:896

+ #: sssd.conf.5.xml:1018

  msgid ""

  "Indicate if a home directory should be removed by default for deleted "

  "users.  Can be overridden on command line."
@@ -1413,13 +1601,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:905

+ #: sssd.conf.5.xml:1027

  msgid "homedir_umask (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:908

+ #: sssd.conf.5.xml:1030

  msgid ""

  "Used by <citerefentry> <refentrytitle>sss_useradd</refentrytitle> "

  "<manvolnum>8</manvolnum> </citerefentry> to specify the default permissions "
@@ -1428,19 +1616,19 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:916

+ #: sssd.conf.5.xml:1038

  msgid "Default: 077"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:921

+ #: sssd.conf.5.xml:1043

  msgid "skel_dir (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:924

+ #: sssd.conf.5.xml:1046

  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 "
@@ -1450,19 +1638,19 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:934

+ #: sssd.conf.5.xml:1056

  msgid "Default: <filename>/etc/skel</filename>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:939

+ #: sssd.conf.5.xml:1061

  msgid "mail_dir (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:942

+ #: sssd.conf.5.xml:1064

  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 "
@@ -1471,19 +1659,19 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:949

+ #: sssd.conf.5.xml:1071

  msgid "Default: <filename>/var/mail</filename>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:954

+ #: sssd.conf.5.xml:1076

  msgid "userdel_cmd (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:957

+ #: sssd.conf.5.xml:1079

  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 "
@@ -1492,20 +1680,20 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:963

+ #: sssd.conf.5.xml:1085

  msgid "Default: None, no command is run"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd.conf.5.xml:973 sssd-ldap.5.xml:1357 sssd-simple.5.xml:126

- #: sssd-ipa.5.xml:173 sssd-krb5.5.xml:405

+ #: sssd.conf.5.xml:1095 sssd-ldap.5.xml:1400 sssd-simple.5.xml:126

+ #: sssd-ipa.5.xml:230 sssd-krb5.5.xml:408

  msgid "EXAMPLE"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><programlisting>

  #. type: Content of: <reference><refentry><refsect1><para><programlisting>

- #: sssd.conf.5.xml:979

+ #: sssd.conf.5.xml:1101

  #, no-wrap

  msgid ""

  "[sssd]\n"
@@ -1535,7 +1723,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:975

+ #: sssd.conf.5.xml:1097

  msgid ""

  "The following example shows a typical SSSD config. It does not describe "

  "configuration of the domains themselves - refer to documentation on "
@@ -1545,7 +1733,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:1010

+ #: sssd.conf.5.xml:1132

  msgid ""

  "<citerefentry> <refentrytitle>sssd-ldap</refentrytitle><manvolnum>5</"

  "manvolnum> </citerefentry>, <citerefentry> <refentrytitle>sssd-krb5</"
@@ -1612,56 +1800,76 @@

  msgid "ldap_uri (string)"

  msgstr ""

  

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-ldap.5.xml:63

  msgid ""

- "Specifies the 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 not specified, "

- "service discovery is enabled. For more information, refer to the "

- "<quote>SERVICE DISCOVERY</quote> section."

+ "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 "

+ "not 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><term>

+ #. 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_chpass_uri (string)"

+ msgid "ldap[s]://&lt;host&gt;[:port]"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-ldap.5.xml:76

  msgid ""

- "Specifies the 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."

+ "For explicit IPv6 addresses, &lt;host&gt; 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 (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:83

+ #: 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:87

+ #: 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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:93

+ #: sssd-ldap.5.xml:105

  msgid "ldap_search_base (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:96

+ #: 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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:100

+ #: sssd-ldap.5.xml:112

  msgid ""

  "Default: If not set the value of the defaultNamingContext or namingContexts "

  "attribute from the RootDSE of the LDAP server is used. If "
@@ -1673,13 +1881,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:114

+ #: sssd-ldap.5.xml:126

  msgid "ldap_schema (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:117

+ #: sssd-ldap.5.xml:129

  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 "
@@ -1694,61 +1902,66 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:136

+ #: sssd-ldap.5.xml:148

  msgid "Default: rfc2307"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:142

+ #: sssd-ldap.5.xml:154

  msgid "ldap_default_bind_dn (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:145

+ #: sssd-ldap.5.xml:157

  msgid "The default bind DN to use for performing LDAP operations."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:152

+ #: sssd-ldap.5.xml:164

  msgid "ldap_default_authtok_type (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:155

+ #: sssd-ldap.5.xml:167

  msgid "The type of the authentication token of the default bind DN."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:159

+ #: sssd-ldap.5.xml:171

  msgid "The two mechanisms currently supported are:"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:162

+ #: sssd-ldap.5.xml:174

  msgid "password"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:165

+ #: sssd-ldap.5.xml:177

  msgid "obfuscated_password"

  msgstr ""

  

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:180

+ msgid "Default: password"

+ msgstr ""

+ 

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:171

+ #: sssd-ldap.5.xml:186

  msgid "ldap_default_authtok (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:174

+ #: sssd-ldap.5.xml:189

  msgid ""

  "The authentication token of the default bind DN.  Only clear text passwords "

  "are currently supported."
@@ -1756,157 +1969,157 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:181

+ #: sssd-ldap.5.xml:196

  msgid "ldap_user_object_class (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:184

+ #: sssd-ldap.5.xml:199

  msgid "The object class of a user entry in LDAP."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:187

+ #: sssd-ldap.5.xml:202

  msgid "Default: posixAccount"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:193

+ #: sssd-ldap.5.xml:208

  msgid "ldap_user_name (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:196

+ #: sssd-ldap.5.xml:211

  msgid "The LDAP attribute that corresponds to the user's login name."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:200

+ #: sssd-ldap.5.xml:215

  msgid "Default: uid"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:206

+ #: sssd-ldap.5.xml:221

  msgid "ldap_user_uid_number (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:209

+ #: sssd-ldap.5.xml:224

  msgid "The LDAP attribute that corresponds to the user's id."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:213

+ #: sssd-ldap.5.xml:228

  msgid "Default: uidNumber"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:219

+ #: sssd-ldap.5.xml:234

  msgid "ldap_user_gid_number (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:222

+ #: sssd-ldap.5.xml:237

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:226 sssd-ldap.5.xml:622

+ #: sssd-ldap.5.xml:241 sssd-ldap.5.xml:637

  msgid "Default: gidNumber"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:232

+ #: sssd-ldap.5.xml:247

  msgid "ldap_user_gecos (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:235

+ #: sssd-ldap.5.xml:250

  msgid "The LDAP attribute that corresponds to the user's gecos field."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:239

+ #: sssd-ldap.5.xml:254

  msgid "Default: gecos"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:245

+ #: sssd-ldap.5.xml:260

  msgid "ldap_user_home_directory (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:248

+ #: sssd-ldap.5.xml:263

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:252

+ #: sssd-ldap.5.xml:267

  msgid "Default: homeDirectory"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:258

+ #: sssd-ldap.5.xml:273

  msgid "ldap_user_shell (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:261

+ #: sssd-ldap.5.xml:276

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:265

+ #: sssd-ldap.5.xml:280

  msgid "Default: loginShell"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:271

+ #: sssd-ldap.5.xml:286

  msgid "ldap_user_uuid (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:274

+ #: sssd-ldap.5.xml:289

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:278 sssd-ldap.5.xml:648 sssd-ldap.5.xml:741

+ #: sssd-ldap.5.xml:293 sssd-ldap.5.xml:663 sssd-ldap.5.xml:756

  msgid "Default: nsUniqueId"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:284

+ #: sssd-ldap.5.xml:299

  msgid "ldap_user_modify_timestamp (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:287 sssd-ldap.5.xml:657 sssd-ldap.5.xml:750

+ #: sssd-ldap.5.xml:302 sssd-ldap.5.xml:672 sssd-ldap.5.xml:765

  msgid ""

  "The LDAP attribute that contains timestamp of the last modification of the "

  "parent object."
@@ -1914,19 +2127,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:291 sssd-ldap.5.xml:661 sssd-ldap.5.xml:754

+ #: sssd-ldap.5.xml:306 sssd-ldap.5.xml:676 sssd-ldap.5.xml:769

  msgid "Default: modifyTimestamp"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:297

+ #: sssd-ldap.5.xml:312

  msgid "ldap_user_shadow_last_change (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:300

+ #: sssd-ldap.5.xml:315

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> <refentrytitle>shadow</"
@@ -1936,19 +2149,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:310

+ #: sssd-ldap.5.xml:325

  msgid "Default: shadowLastChange"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:316

+ #: sssd-ldap.5.xml:331

  msgid "ldap_user_shadow_min (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:319

+ #: sssd-ldap.5.xml:334

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> <refentrytitle>shadow</"
@@ -1958,19 +2171,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:328

+ #: sssd-ldap.5.xml:343

  msgid "Default: shadowMin"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:334

+ #: sssd-ldap.5.xml:349

  msgid "ldap_user_shadow_max (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:337

+ #: sssd-ldap.5.xml:352

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> <refentrytitle>shadow</"
@@ -1980,19 +2193,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:346

+ #: sssd-ldap.5.xml:361

  msgid "Default: shadowMax"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:352

+ #: sssd-ldap.5.xml:367

  msgid "ldap_user_shadow_warning (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:355

+ #: sssd-ldap.5.xml:370

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> <refentrytitle>shadow</"
@@ -2002,19 +2215,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:365

+ #: sssd-ldap.5.xml:380

  msgid "Default: shadowWarning"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:371

+ #: sssd-ldap.5.xml:386

  msgid "ldap_user_shadow_inactive (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:374

+ #: sssd-ldap.5.xml:389

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> <refentrytitle>shadow</"
@@ -2024,18 +2237,18 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:384

+ #: sssd-ldap.5.xml:399

  msgid "Default: shadowInactive"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:390

+ #: sssd-ldap.5.xml:405

  msgid "ldap_user_shadow_expire (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:393

+ #: sssd-ldap.5.xml:408

  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 "
@@ -2045,19 +2258,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:403

+ #: sssd-ldap.5.xml:418

  msgid "Default: shadowExpire"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:409

+ #: sssd-ldap.5.xml:424

  msgid "ldap_user_krb_last_pwd_change (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:412

+ #: sssd-ldap.5.xml:427

  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 "
@@ -2066,19 +2279,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:418

+ #: sssd-ldap.5.xml:433

  msgid "Default: krbLastPwdChange"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:424

+ #: sssd-ldap.5.xml:439

  msgid "ldap_user_krb_password_expiration (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:427

+ #: sssd-ldap.5.xml:442

  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."
@@ -2086,70 +2299,70 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:433

+ #: sssd-ldap.5.xml:448

  msgid "Default: krbPasswordExpiration"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:439

+ #: sssd-ldap.5.xml:454

  msgid "ldap_user_ad_account_expires (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:442

+ #: sssd-ldap.5.xml:457

  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:447

+ #: sssd-ldap.5.xml:462

  msgid "Default: accountExpires"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:453

+ #: sssd-ldap.5.xml:468

  msgid "ldap_user_ad_user_account_control (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:456

+ #: sssd-ldap.5.xml:471

  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:461

+ #: sssd-ldap.5.xml:476

  msgid "Default: userAccountControl"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:467

+ #: sssd-ldap.5.xml:482

  msgid "ldap_ns_account_lock (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:470

+ #: sssd-ldap.5.xml:485

  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:475

+ #: sssd-ldap.5.xml:490

  msgid "Default: nsAccountLock"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:481

+ #: sssd-ldap.5.xml:496

  msgid "ldap_user_principal (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:484

+ #: sssd-ldap.5.xml:499

  msgid ""

  "The LDAP attribute that contains the user's Kerberos User Principal Name "

  "(UPN)."
@@ -2157,19 +2370,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:488

+ #: sssd-ldap.5.xml:503

  msgid "Default: krbPrincipalName"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:494

+ #: sssd-ldap.5.xml:509

  msgid "ldap_force_upper_case_realm (boolean)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:497

+ #: sssd-ldap.5.xml:512

  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 "
@@ -2179,20 +2392,20 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:504 sssd-ldap.5.xml:961 sssd-ipa.5.xml:115 sssd.8.xml:64

- #: sssd-krb5.5.xml:235 sssd-krb5.5.xml:266

+ #: sssd-ldap.5.xml:519 sssd-ldap.5.xml:990 sssd-ipa.5.xml:115 sssd.8.xml:64

+ #: sssd-krb5.5.xml:235 sssd-krb5.5.xml:269

  msgid "Default: false"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:510

+ #: sssd-ldap.5.xml:525

  msgid "ldap_enumeration_refresh_timeout (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:513

+ #: sssd-ldap.5.xml:528

  msgid ""

  "The LDAP attribute that contains how many seconds SSSD has to wait before "

  "refreshing its cache of enumerated records."
@@ -2200,19 +2413,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:518

+ #: sssd-ldap.5.xml:533

  msgid "Default: 300"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:524

+ #: sssd-ldap.5.xml:539

  msgid "ldap_purge_cache_timeout"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:527

+ #: sssd-ldap.5.xml:542

  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 "
@@ -2221,59 +2434,59 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:533

+ #: sssd-ldap.5.xml:548

  msgid "Setting this option to zero will disable the cache cleanup operation."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:537

+ #: sssd-ldap.5.xml:552

  msgid "Default: 10800 (12 hours)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:543

+ #: sssd-ldap.5.xml:558

  msgid "ldap_user_fullname (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:546

+ #: sssd-ldap.5.xml:561

  msgid "The LDAP attribute that corresponds to the user's full name."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:550 sssd-ldap.5.xml:609 sssd-ldap.5.xml:702

+ #: sssd-ldap.5.xml:565 sssd-ldap.5.xml:624 sssd-ldap.5.xml:717

  msgid "Default: cn"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:556

+ #: sssd-ldap.5.xml:571

  msgid "ldap_user_member_of (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:559

+ #: sssd-ldap.5.xml:574

  msgid "The LDAP attribute that lists the user's group memberships."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:563

+ #: sssd-ldap.5.xml:578

  msgid "Default: memberOf"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:569

+ #: sssd-ldap.5.xml:584

  msgid "ldap_user_authorized_service (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:572

+ #: sssd-ldap.5.xml:587

  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 "
@@ -2281,104 +2494,104 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:579

+ #: sssd-ldap.5.xml:594

  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:584

+ #: sssd-ldap.5.xml:599

  msgid "Default: authorizedService"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:590

+ #: sssd-ldap.5.xml:605

  msgid "ldap_group_object_class (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:593

+ #: sssd-ldap.5.xml:608

  msgid "The object class of a group entry in LDAP."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:596

+ #: sssd-ldap.5.xml:611

  msgid "Default: posixGroup"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:602

+ #: sssd-ldap.5.xml:617

  msgid "ldap_group_name (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:605

+ #: sssd-ldap.5.xml:620

  msgid "The LDAP attribute that corresponds to the group name."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:615

+ #: sssd-ldap.5.xml:630

  msgid "ldap_group_gid_number (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:618

+ #: sssd-ldap.5.xml:633

  msgid "The LDAP attribute that corresponds to the group's id."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:628

+ #: sssd-ldap.5.xml:643

  msgid "ldap_group_member (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:631

+ #: sssd-ldap.5.xml:646

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:635

+ #: sssd-ldap.5.xml:650

  msgid "Default: memberuid (rfc2307) / member (rfc2307bis)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:641

+ #: sssd-ldap.5.xml:656

  msgid "ldap_group_uuid (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:644

+ #: sssd-ldap.5.xml:659

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:654

+ #: sssd-ldap.5.xml:669

  msgid "ldap_group_modify_timestamp (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:667

+ #: sssd-ldap.5.xml:682

  msgid "ldap_group_nesting_level (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:670

+ #: sssd-ldap.5.xml:685

  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 "
@@ -2387,104 +2600,104 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:677

+ #: sssd-ldap.5.xml:692

  msgid "Default: 2"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:683

+ #: sssd-ldap.5.xml:698

  msgid "ldap_netgroup_object_class (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:686

+ #: sssd-ldap.5.xml:701

  msgid "The object class of a netgroup entry in LDAP."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:689

+ #: sssd-ldap.5.xml:704

  msgid "Default: nisNetgroup"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:695

+ #: sssd-ldap.5.xml:710

  msgid "ldap_netgroup_name (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:698

+ #: sssd-ldap.5.xml:713

  msgid "The LDAP attribute that corresponds to the netgroup name."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:708

+ #: sssd-ldap.5.xml:723

  msgid "ldap_netgroup_member (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:711

+ #: sssd-ldap.5.xml:726

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:715

+ #: sssd-ldap.5.xml:730

  msgid "Default: memberNisNetgroup"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:721

+ #: sssd-ldap.5.xml:736

  msgid "ldap_netgroup_triple (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:724

+ #: sssd-ldap.5.xml:739

  msgid ""

  "The LDAP attribute that contains the (host, user, domain) netgroup triples."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:728

+ #: sssd-ldap.5.xml:743

  msgid "Default: nisNetgroupTriple"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:734

+ #: sssd-ldap.5.xml:749

  msgid "ldap_netgroup_uuid (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:737

+ #: sssd-ldap.5.xml:752

  msgid ""

  "The LDAP attribute that contains the UUID/GUID of an LDAP netgroup object."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:747

+ #: sssd-ldap.5.xml:762

  msgid "ldap_netgroup_modify_timestamp (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:760

+ #: sssd-ldap.5.xml:775

  msgid "ldap_search_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:763

+ #: sssd-ldap.5.xml:778

  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 "
@@ -2492,7 +2705,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:769

+ #: sssd-ldap.5.xml:784

  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 "
@@ -2501,17 +2714,17 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:775 sssd-ldap.5.xml:817 sssd-ldap.5.xml:832

+ #: sssd-ldap.5.xml:790 sssd-ldap.5.xml:832 sssd-ldap.5.xml:847

  msgid "Default: 6"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:781

+ #: sssd-ldap.5.xml:796

  msgid "ldap_enumeration_search_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:784

+ #: sssd-ldap.5.xml:799

  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 "
@@ -2520,19 +2733,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:791

+ #: sssd-ldap.5.xml:806

  msgid "Default: 60"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:797

+ #: sssd-ldap.5.xml:812

  msgid "ldap_network_timeout (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:800

+ #: sssd-ldap.5.xml:815

  msgid ""

  "Specifies the timeout (in seconds) after which the <citerefentry> "

  "<refentrytitle>poll</refentrytitle> <manvolnum>2</manvolnum> </citerefentry>/"
@@ -2544,28 +2757,45 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:823

+ #: sssd-ldap.5.xml:838

  msgid "ldap_opt_timeout (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:826

+ #: sssd-ldap.5.xml:841

  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."

  msgstr ""

  

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #: sssd-ldap.5.xml:853

+ msgid "ldap_page_size (integer)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:856

+ 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:861

+ msgid "Default: 1000"

+ msgstr ""

+ 

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:838

+ #: sssd-ldap.5.xml:867

  msgid "ldap_tls_reqcert (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:841

+ #: sssd-ldap.5.xml:870

  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:"
@@ -2573,7 +2803,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:847

+ #: sssd-ldap.5.xml:876

  msgid ""

  "<emphasis>never</emphasis> = The client will not request or check any server "

  "certificate."
@@ -2581,7 +2811,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:851

+ #: sssd-ldap.5.xml:880

  msgid ""

  "<emphasis>allow</emphasis> = The server certificate is requested. If no "

  "certificate is provided, the session proceeds normally. If a bad certificate "
@@ -2590,7 +2820,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:858

+ #: sssd-ldap.5.xml:887

  msgid ""

  "<emphasis>try</emphasis> = The server certificate is requested. If no "

  "certificate is provided, the session proceeds normally. If a bad certificate "
@@ -2599,7 +2829,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:864

+ #: sssd-ldap.5.xml:893

  msgid ""

  "<emphasis>demand</emphasis> = The server certificate is requested. If no "

  "certificate is provided, or a bad certificate is provided, the session is "
@@ -2608,25 +2838,25 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:870

+ #: sssd-ldap.5.xml:899

  msgid "<emphasis>hard</emphasis> = Same as <quote>demand</quote>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:874

+ #: sssd-ldap.5.xml:903

  msgid "Default: hard"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:880

+ #: sssd-ldap.5.xml:909

  msgid "ldap_tls_cacert (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:883

+ #: sssd-ldap.5.xml:912

  msgid ""

  "Specifies the file that contains certificates for all of the Certificate "

  "Authorities that <command>sssd</command> will recognize."
@@ -2634,7 +2864,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:888 sssd-ldap.5.xml:906 sssd-ldap.5.xml:947

+ #: sssd-ldap.5.xml:917 sssd-ldap.5.xml:935 sssd-ldap.5.xml:976

  msgid ""

  "Default: use OpenLDAP defaults, typically in <filename>/etc/openldap/ldap."

  "conf</filename>"
@@ -2642,13 +2872,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:895

+ #: sssd-ldap.5.xml:924

  msgid "ldap_tls_cacertdir (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:898

+ #: sssd-ldap.5.xml:927

  msgid ""

  "Specifies the path of a directory that contains Certificate Authority "

  "certificates in separate individual files. Typically the file names need to "
@@ -2657,37 +2887,37 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:913

+ #: sssd-ldap.5.xml:942

  msgid "ldap_tls_cert (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:916

+ #: sssd-ldap.5.xml:945

  msgid "Specifies the file that contains the certificate for the client's key."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:920 sssd-ldap.5.xml:932 sssd-krb5.5.xml:356

+ #: sssd-ldap.5.xml:949 sssd-ldap.5.xml:961 sssd-krb5.5.xml:359

  msgid "Default: not set"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:926

+ #: sssd-ldap.5.xml:955

  msgid "ldap_tls_key (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:929

+ #: sssd-ldap.5.xml:958

  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:938

+ #: sssd-ldap.5.xml:967

  msgid "ldap_tls_cipher_suite (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:941

+ #: sssd-ldap.5.xml:970

  msgid ""

  "Specifies acceptable cipher suites.  Typically this is a colon sperated "

  "list.  See <citerefentry><refentrytitle>ldap.conf</refentrytitle> "
@@ -2696,13 +2926,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:954

+ #: sssd-ldap.5.xml:983

  msgid "ldap_id_use_start_tls (boolean)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:957

+ #: sssd-ldap.5.xml:986

  msgid ""

  "Specifies that the id_provider connection must also use <systemitem class="

  "\"protocol\">tls</systemitem> to protect the channel."
@@ -2710,13 +2940,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:967

+ #: sssd-ldap.5.xml:996

  msgid "ldap_sasl_mech (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:970

+ #: sssd-ldap.5.xml:999

  msgid ""

  "Specify the SASL mechanism to use.  Currently only GSSAPI is tested and "

  "supported."
@@ -2724,19 +2954,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:974 sssd-ldap.5.xml:1102

+ #: sssd-ldap.5.xml:1003 sssd-ldap.5.xml:1145

  msgid "Default: none"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:980

+ #: sssd-ldap.5.xml:1009

  msgid "ldap_sasl_authid (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:983

+ #: sssd-ldap.5.xml:1012

  msgid ""

  "Specify the SASL authorization id to use.  When GSSAPI is used, this "

  "represents the Kerberos principal used for authentication to the directory."
@@ -2744,37 +2974,54 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:988

+ #: sssd-ldap.5.xml:1017

  msgid "Default: host/machine.fqdn@REALM"

  msgstr ""

  

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #: sssd-ldap.5.xml:1023

+ msgid "ldap_sasl_canonicalize (boolean)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:1026

+ 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:1031

+ msgid "Default: false;"

+ msgstr ""

+ 

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:994

+ #: sssd-ldap.5.xml:1037

  msgid "ldap_krb5_keytab (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:997

+ #: sssd-ldap.5.xml:1040

  msgid "Specify the keytab to use when using SASL/GSSAPI."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1000

+ #: sssd-ldap.5.xml:1043

  msgid "Default: System keytab, normally <filename>/etc/krb5.keytab</filename>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1006

+ #: sssd-ldap.5.xml:1049

  msgid "ldap_krb5_init_creds (boolean)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1009

+ #: sssd-ldap.5.xml:1052

  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 "
@@ -2783,42 +3030,42 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1021

+ #: sssd-ldap.5.xml:1064

  msgid "ldap_krb5_ticket_lifetime (integer)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1024

+ #: sssd-ldap.5.xml:1067

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1028

+ #: sssd-ldap.5.xml:1071

  msgid "Default: 86400 (24 hours)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1034 sssd-krb5.5.xml:74

+ #: sssd-ldap.5.xml:1077 sssd-krb5.5.xml:74

  msgid "krb5_server (string)"

  msgstr ""

  

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1037 sssd-krb5.5.xml:77

+ #: sssd-ldap.5.xml:1080 sssd-krb5.5.xml:77

  msgid ""

- "Specifies the 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."

+ "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:1049 sssd-krb5.5.xml:89

+ #: sssd-ldap.5.xml:1092 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 "
@@ -2827,7 +3074,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1054 sssd-krb5.5.xml:94

+ #: sssd-ldap.5.xml:1097 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 "
@@ -2836,31 +3083,31 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1063 sssd-krb5.5.xml:103

+ #: sssd-ldap.5.xml:1106 sssd-ipa.5.xml:165 sssd-krb5.5.xml:103

  msgid "krb5_realm (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1066

+ #: sssd-ldap.5.xml:1109

  msgid "Specify the Kerberos REALM (for SASL/GSSAPI auth)."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1069

+ #: sssd-ldap.5.xml:1112

  msgid "Default: System defaults, see <filename>/etc/krb5.conf</filename>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1075

+ #: sssd-ldap.5.xml:1118

  msgid "ldap_pwd_policy (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1078

+ #: sssd-ldap.5.xml:1121

  msgid ""

  "Select the policy to evaluate the password expiration on the client side. "

  "The following values are allowed:"
@@ -2868,7 +3115,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1083

+ #: sssd-ldap.5.xml:1126

  msgid ""

  "<emphasis>none</emphasis> - No evaluation on the client side. This option "

  "cannot disable server-side password policies."
@@ -2876,7 +3123,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1088

+ #: sssd-ldap.5.xml:1131

  msgid ""

  "<emphasis>shadow</emphasis> - Use <citerefentry><refentrytitle>shadow</"

  "refentrytitle> <manvolnum>5</manvolnum></citerefentry> style attributes to "
@@ -2886,7 +3133,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1096

+ #: sssd-ldap.5.xml:1139

  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 "
@@ -2895,19 +3142,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1108

+ #: sssd-ldap.5.xml:1151

  msgid "ldap_referrals (boolean)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1111

+ #: sssd-ldap.5.xml:1154

  msgid "Specifies whether automatic referral chasing should be enabled."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1115

+ #: sssd-ldap.5.xml:1158

  msgid ""

  "Please note that sssd only supports referral chasing when it is compiled "

  "with OpenLDAP version 2.4.13 or higher."
@@ -2915,48 +3162,48 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1126

+ #: sssd-ldap.5.xml:1169

  msgid "ldap_dns_service_name (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1129

+ #: sssd-ldap.5.xml:1172

  msgid "Specifies the service name to use when service discovery is enabled."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1133

+ #: sssd-ldap.5.xml:1176

  msgid "Default: ldap"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1139

+ #: sssd-ldap.5.xml:1182

  msgid "ldap_chpass_dns_service_name (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1142

+ #: sssd-ldap.5.xml:1185

  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:1147

+ #: sssd-ldap.5.xml:1190

  msgid "Default: not set, i.e. service discovery is disabled"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1153

+ #: sssd-ldap.5.xml:1196

  msgid "ldap_access_filter (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1156

+ #: sssd-ldap.5.xml:1199

  msgid ""

  "If using access_provider = ldap, this option is mandatory. It specifies an "

  "LDAP search filter criteria that must be met for the user to be granted "
@@ -2967,13 +3214,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1166

+ #: sssd-ldap.5.xml:1209

  msgid "Example:"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><programlisting>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><programlisting>

- #: sssd-ldap.5.xml:1169

+ #: sssd-ldap.5.xml:1212

  #, no-wrap

  msgid ""

  "access_provider = ldap\n"
@@ -2983,7 +3230,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1173

+ #: sssd-ldap.5.xml:1216

  msgid ""

  "This example means that access to this host is restricted to members of the "

  "\"allowedusers\" group in ldap."
@@ -2991,7 +3238,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1178

+ #: sssd-ldap.5.xml:1221

  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 "
@@ -3001,24 +3248,24 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1186 sssd-ldap.5.xml:1227

+ #: sssd-ldap.5.xml:1229 sssd-ldap.5.xml:1270

  msgid "Default: Empty"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1192

+ #: sssd-ldap.5.xml:1235

  msgid "ldap_account_expire_policy (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1195

+ #: sssd-ldap.5.xml:1238

  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:1199

+ #: sssd-ldap.5.xml:1242

  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 "
@@ -3026,19 +3273,19 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1206

+ #: sssd-ldap.5.xml:1249

  msgid "The following values are allowed:"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1209

+ #: sssd-ldap.5.xml:1252

  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:1214

+ #: sssd-ldap.5.xml:1257

  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 "
@@ -3047,7 +3294,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1221

+ #: sssd-ldap.5.xml:1264

  msgid ""

  "<emphasis>rhds</emphasis>, <emphasis>ipa</emphasis>, <emphasis>389ds</"

  "emphasis>: use the value of ldap_ns_account_lock to check if access is "
@@ -3055,39 +3302,39 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1233

+ #: sssd-ldap.5.xml:1276

  msgid "ldap_access_order (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1236

+ #: sssd-ldap.5.xml:1279

  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:1240

+ #: sssd-ldap.5.xml:1283

  msgid "<emphasis>filter</emphasis>: use ldap_access_filter"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1243

+ #: sssd-ldap.5.xml:1286

  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:1247

+ #: sssd-ldap.5.xml:1290

  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:1252

+ #: sssd-ldap.5.xml:1295

  msgid "Default: filter"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1255

+ #: sssd-ldap.5.xml:1298

  msgid ""

  "Please note that it is a configuration error if a value is used more than "

  "once."
@@ -3095,13 +3342,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1262

+ #: sssd-ldap.5.xml:1305

  msgid "ldap_deref (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1265

+ #: sssd-ldap.5.xml:1308

  msgid ""

  "Specifies how alias dereferencing is done when performing a search. The "

  "following options are allowed:"
@@ -3109,13 +3356,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1270

+ #: sssd-ldap.5.xml:1313

  msgid "<emphasis>never</emphasis>: Aliases are never dereferenced."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1274

+ #: sssd-ldap.5.xml:1317

  msgid ""

  "<emphasis>searching</emphasis>: Aliases are dereferenced in subordinates of "

  "the base object, but not in locating the base object of the search."
@@ -3123,7 +3370,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1279

+ #: sssd-ldap.5.xml:1322

  msgid ""

  "<emphasis>finding</emphasis>: Aliases are only dereferenced when locating "

  "the base object of the search."
@@ -3131,7 +3378,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1284

+ #: sssd-ldap.5.xml:1327

  msgid ""

  "<emphasis>always</emphasis>: Aliases are dereferenced both in searching and "

  "in locating the base object of the search."
@@ -3139,7 +3386,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1289

+ #: sssd-ldap.5.xml:1332

  msgid ""

  "Default: Empty (this is handled as <emphasis>never</emphasis> by the LDAP "

  "client libraries)"
@@ -3157,55 +3404,55 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd-ldap.5.xml:1301

+ #: sssd-ldap.5.xml:1344

  msgid "ADVANCED OPTIONS"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1308

+ #: sssd-ldap.5.xml:1351

  msgid "ldap_netgroup_search_base (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1311

+ #: sssd-ldap.5.xml:1354

  msgid ""

  "An optional base DN to restrict netgroup searches to a specific subtree."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1315 sssd-ldap.5.xml:1329 sssd-ldap.5.xml:1343

+ #: sssd-ldap.5.xml:1358 sssd-ldap.5.xml:1372 sssd-ldap.5.xml:1386

  msgid "Default: the value of <emphasis>ldap_search_base</emphasis>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1322

+ #: sssd-ldap.5.xml:1365

  msgid "ldap_user_search_base (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1325

+ #: sssd-ldap.5.xml:1368

  msgid "An optional base DN to restrict user searches to a specific subtree."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1336

+ #: sssd-ldap.5.xml:1379

  msgid "ldap_group_search_base (string)"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1339

+ #: sssd-ldap.5.xml:1382

  msgid "An optional base DN to restrict group searches to a specific subtree."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1303

+ #: sssd-ldap.5.xml:1346

  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 "
@@ -3214,7 +3461,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1359

+ #: sssd-ldap.5.xml:1402

  msgid ""

  "The following example assumes that SSSD is correctly configured and LDAP is "

  "set to one of the domains in the <replaceable>[domains]</replaceable> "
@@ -3223,7 +3470,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><programlisting>

  #. type: Content of: <reference><refentry><refsect1><para><programlisting>

- #: sssd-ldap.5.xml:1365

+ #: sssd-ldap.5.xml:1408

  #, no-wrap

  msgid ""

  "    [domain/LDAP]\n"
@@ -3237,20 +3484,20 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1364 sssd-simple.5.xml:134 sssd-ipa.5.xml:181

- #: sssd-krb5.5.xml:414

+ #: sssd-ldap.5.xml:1407 sssd-simple.5.xml:134 sssd-ipa.5.xml:238

+ #: sssd-krb5.5.xml:417

  msgid "<placeholder type=\"programlisting\" id=\"0\"/>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd-ldap.5.xml:1378 sssd_krb5_locator_plugin.8.xml:61

+ #: sssd-ldap.5.xml:1421 sssd_krb5_locator_plugin.8.xml:61

  msgid "NOTES"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1380

+ #: sssd-ldap.5.xml:1423

  msgid ""

  "The descriptions of some of the configuration options in this manual page "

  "are based on the <citerefentry> <refentrytitle>ldap.conf</refentrytitle> "
@@ -3260,7 +3507,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1391

+ #: sssd-ldap.5.xml:1434

  msgid ""

  "<citerefentry> <refentrytitle>sssd.conf</refentrytitle><manvolnum>5</"

  "manvolnum> </citerefentry>, <citerefentry> <refentrytitle>sssd-krb5</"
@@ -3290,11 +3537,11 @@

  msgid "PAM module for SSSD"

  msgstr ""

  

- # type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis>

  #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis>

  #: pam_sss.8.xml:24

  msgid ""

- "<command>pam_sss.so</command> <arg choice='opt'> <replaceable>forward_pass</"

+ "<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> </"
@@ -3303,22 +3550,32 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:42

+ #: pam_sss.8.xml:45

  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:55

+ msgid "<option>quiet</option>"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

+ #: pam_sss.8.xml:58

+ msgid "Suppress log messages for unknown users."

+ msgstr ""

+ 

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: pam_sss.8.xml:52

+ #: pam_sss.8.xml:63

  msgid "<option>forward_pass</option>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:55

+ #: pam_sss.8.xml:66

  msgid ""

  "If <option>forward_pass</option> is set the entered password is put on the "

  "stack for other PAM modules to use."
@@ -3326,13 +3583,13 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: pam_sss.8.xml:62

+ #: pam_sss.8.xml:73

  msgid "<option>use_first_pass</option>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:65

+ #: pam_sss.8.xml:76

  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 "
@@ -3341,13 +3598,13 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: pam_sss.8.xml:73

+ #: pam_sss.8.xml:84

  msgid "<option>use_authtok</option>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:76

+ #: pam_sss.8.xml:87

  msgid ""

  "When password changing enforce the module to set the new password to the one "

  "provided by a previously stacked password module."
@@ -3355,13 +3612,13 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: pam_sss.8.xml:83

+ #: pam_sss.8.xml:94

  msgid "<option>retry=N</option>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:86

+ #: pam_sss.8.xml:97

  msgid ""

  "If specified the user is asked another N times for a password if "

  "authentication fails. Default is 0."
@@ -3369,7 +3626,7 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:88

+ #: pam_sss.8.xml:99

  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 "
@@ -3378,13 +3635,13 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: pam_sss.8.xml:99

+ #: pam_sss.8.xml:110

  msgid "MODULE TYPES PROVIDED"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:100

+ #: pam_sss.8.xml:111

  msgid ""

  "All module types (<option>account</option>, <option>auth</option>, "

  "<option>password</option> and <option>session</option>) are provided."
@@ -3392,13 +3649,13 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: pam_sss.8.xml:106

+ #: pam_sss.8.xml:117

  msgid "FILES"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:107

+ #: pam_sss.8.xml:118

  msgid ""

  "If a password reset by root fails, because the corresponding SSSD provider "

  "does not support password resets, an individual message can be displayed. "
@@ -3407,7 +3664,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:112

+ #: pam_sss.8.xml:123

  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> "
@@ -3420,7 +3677,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:122

+ #: pam_sss.8.xml:133

  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 "
@@ -3429,7 +3686,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:130

+ #: pam_sss.8.xml:141

  msgid ""

  "<citerefentry> <refentrytitle>sssd.conf</refentrytitle><manvolnum>8</"

  "manvolnum> </citerefentry>"
@@ -3707,15 +3964,14 @@

  msgid "ipa_server (string)"

  msgstr ""

  

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-ipa.5.xml:83

  msgid ""

- "The 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 the <quote>SERVICE DISCOVERY</quote> section."

+ "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 the <quote>SERVICE DISCOVERY</quote> section."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>
@@ -3803,9 +4059,74 @@

  "end."

  msgstr ""

  

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:168

+ 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:172

+ 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><term>

+ #: sssd-ipa.5.xml:179

+ msgid "ipa_hbac_refresh (integer)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:182

+ 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:189

+ msgid "Default: 5 (seconds)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #: sssd-ipa.5.xml:194

+ msgid "ipa_hbac_treat_deny_as (string)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:197

+ msgid ""

+ "This option specifies how to treat the deprecated DENY-type HBAC rules. As "

+ "of FreeIPA v2.1, DENY rules are no longer supported on the server. All users "

+ "of FreeIPA will need to migrate their rules to use only the ALLOW rules. The "

+ "client will support two modes of operation during this transition period:"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:206

+ msgid ""

+ "<emphasis>DENY_ALL</emphasis>: If any HBAC DENY rules are detected, all "

+ "users will be denied access."

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:211

+ msgid ""

+ "<emphasis>IGNORE</emphasis>: SSSD will ignore any DENY rules. Be very "

+ "careful with this option, as it may result in opening unintended access."

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:216

+ msgid "Default: DENY_ALL"

+ msgstr ""

+ 

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ipa.5.xml:175

+ #: sssd-ipa.5.xml:232

  msgid ""

  "The following example assumes that SSSD is correctly configured and example."

  "com is one of the domains in the <replaceable>[sssd]</replaceable> section. "
@@ -3814,7 +4135,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><programlisting>

  #. type: Content of: <reference><refentry><refsect1><para><programlisting>

- #: sssd-ipa.5.xml:182

+ #: sssd-ipa.5.xml:239

  #, no-wrap

  msgid ""

  "    [domain/example.com]\n"
@@ -3825,7 +4146,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ipa.5.xml:193

+ #: sssd-ipa.5.xml:250

  msgid ""

  "<citerefentry> <refentrytitle>sssd.conf</refentrytitle><manvolnum>5</"

  "manvolnum> </citerefentry>, <citerefentry> <refentrytitle>sssd-ldap</"
@@ -4053,10 +4374,10 @@

  #. type: Content of: <reference><refentry><refsect1><para>

  #: sss_obfuscate.8.xml:37

  msgid ""

- "The cleartext password can be specified as an argument to the program, 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 "

+ "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."
@@ -4064,7 +4385,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sss_obfuscate.8.xml:50

+ #: 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 "
@@ -4075,19 +4396,19 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: sss_obfuscate.8.xml:64

+ #: sss_obfuscate.8.xml:63

  msgid "<option>-s</option>,<option>--stdin</option>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: sss_obfuscate.8.xml:68

+ #: 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>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: sss_obfuscate.8.xml:75

+ #: sss_obfuscate.8.xml:74

  msgid ""

  "<option>-d</option>,<option>--domain</option> <replaceable>DOMAIN</"

  "replaceable>"
@@ -4095,7 +4416,7 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: sss_obfuscate.8.xml:80

+ #: sss_obfuscate.8.xml:79

  msgid ""

  "The SSSD domain to use the password in. The default name is <quote>default</"

  "quote>."
@@ -4103,26 +4424,26 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: sss_obfuscate.8.xml:87

+ #: 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>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: sss_obfuscate.8.xml:92

+ #: 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>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: sss_obfuscate.8.xml:96

+ #: sss_obfuscate.8.xml:95

  msgid "Default: <filename>/etc/sssd/sssd.conf</filename>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sss_obfuscate.8.xml:106

+ #: sss_obfuscate.8.xml:105

  msgid ""

  "<citerefentry> <refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</"

  "manvolnum> </citerefentry>"
@@ -4445,24 +4766,6 @@

  msgid "krb5_ccname_template (string)"

  msgstr ""

  

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:166

- msgid "%u"

- msgstr ""

- 

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:167

- msgid "login name"

- msgstr ""

- 

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:170

- msgid "%U"

- msgstr ""

- 

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

  #: sssd-krb5.5.xml:171
@@ -4505,12 +4808,6 @@

  msgid "home directory"

  msgstr ""

  

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:188

- msgid "%d"

- msgstr ""

- 

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

  #: sssd-krb5.5.xml:189
@@ -4529,18 +4826,6 @@

  msgid "the process ID of the sssd client"

  msgstr ""

  

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:200

- msgid "%%"

- msgstr ""

- 

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:201

- msgid "a literal '%'"

- msgstr ""

- 

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-krb5.5.xml:160

  msgid ""
@@ -4608,48 +4893,50 @@

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-krb5.5.xml:262

  msgid ""

- "Please note that this feature currently only available on a Linux platform."

+ "Please note that this feature currently only available on a Linux platform. "

+ "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:272

+ #: sssd-krb5.5.xml:275

  msgid "krb5_renewable_lifetime (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:275

+ #: sssd-krb5.5.xml:278

  msgid ""

  "Request a renewable ticket with a total lifetime given by an integer "

  "immediately followed by one of the following delimiters:"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:280 sssd-krb5.5.xml:316

+ #: sssd-krb5.5.xml:283 sssd-krb5.5.xml:319

  msgid "<emphasis>s</emphasis> seconds"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:283 sssd-krb5.5.xml:319

+ #: sssd-krb5.5.xml:286 sssd-krb5.5.xml:322

  msgid "<emphasis>m</emphasis> minutes"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:286 sssd-krb5.5.xml:322

+ #: sssd-krb5.5.xml:289 sssd-krb5.5.xml:325

  msgid "<emphasis>h</emphasis> hours"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:289 sssd-krb5.5.xml:325

+ #: sssd-krb5.5.xml:292 sssd-krb5.5.xml:328

  msgid "<emphasis>d</emphasis> days."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:292 sssd-krb5.5.xml:328

+ #: sssd-krb5.5.xml:295 sssd-krb5.5.xml:331

  msgid "If there is no delimiter <emphasis>s</emphasis> is assumed."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:296

+ #: sssd-krb5.5.xml:299

  msgid ""

  "Please note that it is not possible to mix units.  If you want to set the "

  "renewable lifetime to one and a half hours please use '90m' instead of "
@@ -4657,97 +4944,97 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:302

+ #: sssd-krb5.5.xml:305

  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:308

+ #: sssd-krb5.5.xml:311

  msgid "krb5_lifetime (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:311

+ #: sssd-krb5.5.xml:314

  msgid ""

  "Request ticket with a with a lifetime given by an integer immediately "

  "followed by one of the following delimiters:"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:332

+ #: sssd-krb5.5.xml:335

  msgid ""

  "Please note that it is not possible to mix units.  If you want 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:337

+ #: sssd-krb5.5.xml:340

  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:344

+ #: sssd-krb5.5.xml:347

  msgid "krb5_renew_interval (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:347

+ #: sssd-krb5.5.xml:350

  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."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:352

+ #: sssd-krb5.5.xml:355

  msgid "If this option is not set or 0 the automatic renewal is disabled."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:362

+ #: sssd-krb5.5.xml:365

  msgid "krb5_use_fast (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:365

+ #: sssd-krb5.5.xml:368

  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-krb5.5.xml:370

+ #: sssd-krb5.5.xml:373

  msgid ""

  "<emphasis>never</emphasis> use FAST, this is equivalent to not set this "

  "option at all."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:374

+ #: sssd-krb5.5.xml:377

  msgid ""

  "<emphasis>try</emphasis> to use FAST, if the server does not support fast "

  "continue without."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:378

+ #: sssd-krb5.5.xml:381

  msgid ""

  "<emphasis>demand</emphasis> to use FAST, fail if the server does not require "

  "fast."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:382

+ #: sssd-krb5.5.xml:385

  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:385

+ #: sssd-krb5.5.xml:388

  msgid "Please note that a keytab is required to use fast."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:388

+ #: sssd-krb5.5.xml:391

  msgid ""

  "Please note also that sssd supports fast only with MIT Kerberos version 1.8 "

  "and above. If sssd used used with an older version using this option is a "
@@ -4766,7 +5053,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-krb5.5.xml:407

+ #: sssd-krb5.5.xml:410

  msgid ""

  "The following example assumes that SSSD is correctly configured and FOO is "

  "one of the domains in the <replaceable>[sssd]</replaceable> section. This "
@@ -4776,7 +5063,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><programlisting>

  #. type: Content of: <reference><refentry><refsect1><para><programlisting>

- #: sssd-krb5.5.xml:415

+ #: sssd-krb5.5.xml:418

  #, no-wrap

  msgid ""

  "    [domain/FOO]\n"
@@ -4787,7 +5074,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-krb5.5.xml:426

+ #: sssd-krb5.5.xml:429

  msgid ""

  "<citerefentry> <refentrytitle>sssd.conf</refentrytitle><manvolnum>5</"

  "manvolnum> </citerefentry>, <citerefentry> <refentrytitle>sssd-ldap</"

file added
+4991
The added file is too large to be shown here, see it at: src/man/po/cs_CZ.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/da.po
file added
+4990
The added file is too large to be shown here, see it at: src/man/po/de.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/de_CH.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/el.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/en_GB.po
file added
+5086
The added file is too large to be shown here, see it at: src/man/po/es.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/et.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/fa.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/fa_IR.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/fi.po
file added
+4990
The added file is too large to be shown here, see it at: src/man/po/fr.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/gu.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/he.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/hi.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/hu.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/id.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/is.po
file added
+4990
The added file is too large to be shown here, see it at: src/man/po/it.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/ja.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/ja_JP.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/kn.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/ko.po
file added
+4993
The added file is too large to be shown here, see it at: src/man/po/lt.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/lt_LT.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/mai.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/ml.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/mr.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/nb.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/nds.po
file added
+5088
The added file is too large to be shown here, see it at: src/man/po/nl.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/nn.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/or.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/pa.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/pl.po
file modified
+1 -1
@@ -1,4 +1,4 @@

- [po4a_langs] cs uk

+ [po4a_langs] ar as bal bn_IN bn ca cs_CZ cs da de_CH de el en_GB es et fa_IR fa fi fr gu he hi hu id is it ja_JP ja kn ko lt_LT lt mai ml mr nb nds nl nn or pa pl pt_BR pt ro ru sk sl sq sr sv ta_IN ta te tr uk ur vi vi_VN zh_CN zh_HK zh_TW

  [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

file added
+4991
The added file is too large to be shown here, see it at: src/man/po/pt.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/pt_BR.po
file added
+4993
The added file is too large to be shown here, see it at: src/man/po/ro.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/ru.po
file added
+4990
The added file is too large to be shown here, see it at: src/man/po/sk.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/sl.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/sq.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/sr.po
file modified
+813 -521
@@ -6,9 +6,9 @@

  #, fuzzy

  msgid ""

  msgstr ""

- "Project-Id-Version: sssd-docs 1.5.1\n"

+ "Project-Id-Version: sssd-docs 1.5.16\n"

  "Report-Msgid-Bugs-To: sssd-devel@redhat.com\n"

- "POT-Creation-Date: 2011-01-24 13:36-0500\n"

+ "POT-Creation-Date: 2011-12-09 09:15-0500\n"

  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"

  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"

  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -46,7 +46,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sss_groupmod.8.xml:30 sssd-ldap.5.xml:21 pam_sss.8.xml:41 sssd_krb5_locator_plugin.8.xml:20 sssd-simple.5.xml:22 sssd-ipa.5.xml:21 sssd.8.xml:29 sss_obfuscate.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_groupmod.8.xml:30 sssd-ldap.5.xml:21 pam_sss.8.xml:44 sssd_krb5_locator_plugin.8.xml:20 sssd-simple.5.xml:22 sssd-ipa.5.xml:21 sssd.8.xml:29 sss_obfuscate.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

  msgid "DESCRIPTION"

  msgstr ""

  
@@ -58,7 +58,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sss_groupmod.8.xml:39 pam_sss.8.xml:48 sssd.8.xml:42 sss_obfuscate.8.xml:59 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_groupmod.8.xml:39 pam_sss.8.xml:51 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

  msgid "OPTIONS"

  msgstr ""

  
@@ -93,7 +93,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sss_groupmod.8.xml:72 sssd.conf.5.xml:1008 sssd-ldap.5.xml:1389 pam_sss.8.xml:128 sssd_krb5_locator_plugin.8.xml:75 sssd-simple.5.xml:143 sssd-ipa.5.xml:191 sssd.8.xml:166 sss_obfuscate.8.xml:104 sss_useradd.8.xml:167 sssd-krb5.5.xml:424 sss_groupadd.8.xml:58 sss_userdel.8.xml:93 sss_groupdel.8.xml:46 sss_groupshow.8.xml:58 sss_usermod.8.xml:138

+ #: sss_groupmod.8.xml:72 sssd.conf.5.xml:1130 sssd-ldap.5.xml:1432 pam_sss.8.xml:139 sssd_krb5_locator_plugin.8.xml:75 sssd-simple.5.xml:143 sssd-ipa.5.xml:248 sssd.8.xml:166 sss_obfuscate.8.xml:103 sss_useradd.8.xml:167 sssd-krb5.5.xml:427 sss_groupadd.8.xml:58 sss_userdel.8.xml:93 sss_groupdel.8.xml:46 sss_groupshow.8.xml:58 sss_usermod.8.xml:138

  msgid "SEE ALSO"

  msgstr ""

  
@@ -200,7 +200,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><title>

- #: sssd.conf.5.xml:70 sssd.conf.5.xml:854

+ #: sssd.conf.5.xml:70 sssd.conf.5.xml:976

  msgid "Section parameters"

  msgstr ""

  
@@ -232,19 +232,19 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:93 sssd.conf.5.xml:234

+ #: sssd.conf.5.xml:93 sssd.conf.5.xml:254

  msgid "reconnection_retries (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:96 sssd.conf.5.xml:237

+ #: sssd.conf.5.xml:96 sssd.conf.5.xml:257

  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:101 sssd.conf.5.xml:242

+ #: sssd.conf.5.xml:101 sssd.conf.5.xml:262

  msgid "Default: 3"

  msgstr ""

  
@@ -351,6 +351,32 @@

  "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:189

+ msgid "krb5_rcache_dir (string)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:192

+ 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:196

+ 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:202

+ msgid ""

+ "Default: Distribution-specific and specified at "

+ "build-time. (__LIBKRB5_DEFAULTS__ if not configured)"

+ msgstr ""

+ 

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

  #: sssd.conf.5.xml:63

  msgid ""
@@ -363,12 +389,12 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd.conf.5.xml:195

+ #: sssd.conf.5.xml:215

  msgid "SERVICES SECTIONS"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:197

+ #: sssd.conf.5.xml:217

  msgid ""

  "Settings that can be used to configure different services are described in "

  "this section. They should reside in the [<replaceable>$NAME</replaceable>] "
@@ -377,54 +403,54 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><title>

- #: sssd.conf.5.xml:204

+ #: sssd.conf.5.xml:224

  msgid "General service configuration options"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

- #: sssd.conf.5.xml:206

+ #: sssd.conf.5.xml:226

  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:210

+ #: sssd.conf.5.xml:230

  msgid "debug_level (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:213

+ #: sssd.conf.5.xml:233

  msgid ""

  "Sets the debug level for the service. The value can be in range from 0 (only "

  "critical messages) to 10 (very verbose)."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:218 sssd.conf.5.xml:312

+ #: sssd.conf.5.xml:238 sssd.conf.5.xml:332

  msgid "Default: 0"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:223 sssd.8.xml:58

+ #: sssd.conf.5.xml:243 sssd.8.xml:58

  msgid "debug_timestamps (bool)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:226 sssd.8.xml:61

+ #: sssd.conf.5.xml:246 sssd.8.xml:61

  msgid "Add a timestamp to the debug messages"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:229 sssd.conf.5.xml:353 sssd-ldap.5.xml:1015 sssd-ldap.5.xml:1120 sssd-ipa.5.xml:155

+ #: sssd.conf.5.xml:249 sssd.conf.5.xml:373 sssd-ldap.5.xml:1058 sssd-ldap.5.xml:1163 sssd-ipa.5.xml:155

  msgid "Default: true"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:247

+ #: sssd.conf.5.xml:267

  msgid "command (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:250

+ #: sssd.conf.5.xml:270

  msgid ""

  "By default, the executable representing this service is called "

  "<command>sssd_${service_name}</command>.  This directive allows to change "
@@ -433,46 +459,46 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:258

+ #: sssd.conf.5.xml:278

  msgid "Default: <command>sssd_${service_name}</command>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><title>

- #: sssd.conf.5.xml:266

+ #: sssd.conf.5.xml:286

  msgid "NSS configuration options"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

- #: sssd.conf.5.xml:268

+ #: sssd.conf.5.xml:288

  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:273

+ #: sssd.conf.5.xml:293

  msgid "enum_cache_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:276

+ #: sssd.conf.5.xml:296

  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:280

+ #: sssd.conf.5.xml:300

  msgid "Default: 120"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:285

+ #: sssd.conf.5.xml:305

  msgid "entry_cache_nowait_percentage (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:288

+ #: sssd.conf.5.xml:308

  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 "
@@ -480,7 +506,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:294

+ #: sssd.conf.5.xml:314

  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 "
@@ -490,7 +516,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:304

+ #: sssd.conf.5.xml:324

  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 "
@@ -499,12 +525,12 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:317

+ #: sssd.conf.5.xml:337

  msgid "entry_negative_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:320

+ #: sssd.conf.5.xml:340

  msgid ""

  "Specifies for how many seconds nss_sss should cache negative cache hits "

  "(that is, queries for invalid database entries, like nonexistent ones)  "
@@ -512,17 +538,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:326 sssd-krb5.5.xml:223

+ #: sssd.conf.5.xml:346 sssd-krb5.5.xml:223

  msgid "Default: 15"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:331

+ #: sssd.conf.5.xml:351

  msgid "filter_users, filter_groups (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:334

+ #: sssd.conf.5.xml:354

  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 "
@@ -531,75 +557,216 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:341

+ #: sssd.conf.5.xml:361

  msgid "Default: root"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:346

+ #: sssd.conf.5.xml:366

  msgid "filter_users_in_groups (bool)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:349

+ #: sssd.conf.5.xml:369

  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:378

+ msgid "override_homedir (string)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:387 sssd-krb5.5.xml:166

+ msgid "%u"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:388 sssd-krb5.5.xml:167

+ msgid "login name"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:391 sssd-krb5.5.xml:170

+ msgid "%U"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:392

+ msgid "UID number"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:395 sssd-krb5.5.xml:188

+ msgid "%d"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:396

+ msgid "domain name"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:399

+ msgid "%f"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:400

+ msgid "fully qualified user name (user@domain)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:403 sssd-krb5.5.xml:200

+ msgid "%%"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:404 sssd-krb5.5.xml:201

+ msgid "a literal '%'"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:381

+ 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: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:410

+ msgid "This option can also be set per-domain."

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:415

+ msgid "allowed_shells (string)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:418

+ 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:421

+ 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:425

+ 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:430

+ 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:435

+ 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:438

+ 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:442

+ 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:447

+ msgid "vetoed_shells (string)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:450

+ 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:455

+ msgid "shell_fallback (string)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:458

+ 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:462

+ msgid "Default: /bin/sh"

+ msgstr ""

+ 

  #. type: Content of: <reference><refentry><refsect1><refsect2><title>

- #: sssd.conf.5.xml:360

+ #: sssd.conf.5.xml:469

  msgid "PAM configuration options"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

- #: sssd.conf.5.xml:362

+ #: sssd.conf.5.xml:471

  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:367

+ #: sssd.conf.5.xml:476

  msgid "offline_credentials_expiration (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:370

+ #: sssd.conf.5.xml:479

  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:375 sssd.conf.5.xml:388

+ #: sssd.conf.5.xml:484 sssd.conf.5.xml:497

  msgid "Default: 0 (No limit)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:381

+ #: sssd.conf.5.xml:490

  msgid "offline_failed_login_attempts (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:384

+ #: sssd.conf.5.xml:493

  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:394

+ #: sssd.conf.5.xml:503

  msgid "offline_failed_login_delay (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:397

+ #: sssd.conf.5.xml:506

  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:402

+ #: sssd.conf.5.xml:511

  msgid ""

  "If set to 0 the user cannot authenticate offline if "

  "offline_failed_login_attempts has been reached. Only a successful online "
@@ -607,59 +774,59 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:408 sssd.conf.5.xml:461 sssd.conf.5.xml:793

+ #: sssd.conf.5.xml:517 sssd.conf.5.xml:570 sssd.conf.5.xml:906

  msgid "Default: 5"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:414

+ #: sssd.conf.5.xml:523

  msgid "pam_verbosity (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:417

+ #: sssd.conf.5.xml:526

  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:422

+ #: sssd.conf.5.xml:531

  msgid "Currently sssd supports the following values:"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:425

+ #: sssd.conf.5.xml:534

  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:428

+ #: sssd.conf.5.xml:537

  msgid "<emphasis>1</emphasis>: show only important messages"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:432

+ #: sssd.conf.5.xml:541

  msgid "<emphasis>2</emphasis>: show informational messages"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:435

+ #: sssd.conf.5.xml:544

  msgid "<emphasis>3</emphasis>: show all messages and debug information"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:439

+ #: sssd.conf.5.xml:548

  msgid "Default: 1"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:444

+ #: sssd.conf.5.xml:553

  msgid "pam_id_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:447

+ #: sssd.conf.5.xml:556

  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 "
@@ -667,7 +834,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:453

+ #: sssd.conf.5.xml:562

  msgid ""

  "A complete PAM conversation may perform multiple PAM requests, such as "

  "account management and session opening. This option controls (on a "
@@ -677,17 +844,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:467

+ #: sssd.conf.5.xml:576

  msgid "pam_pwd_expiration_warning (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:470

+ #: sssd.conf.5.xml:579

  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:473

+ #: sssd.conf.5.xml:582

  msgid ""

  "Please note that the backend server has to provide information about the "

  "expiration time of the password.  If this information is missing, sssd "
@@ -695,29 +862,29 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:479

+ #: sssd.conf.5.xml:588

  msgid "Default: 7"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd.conf.5.xml:488

+ #: sssd.conf.5.xml:597

  msgid "DOMAIN SECTIONS"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:495

+ #: sssd.conf.5.xml:604

  msgid "min_id,max_id (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:498

+ #: sssd.conf.5.xml:607

  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:503

+ #: sssd.conf.5.xml:612

  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 "
@@ -726,56 +893,56 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:510

+ #: sssd.conf.5.xml:619

  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:516

+ #: sssd.conf.5.xml:625

  msgid "timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:519

+ #: sssd.conf.5.xml:628

  msgid ""

  "Timeout in seconds between heartbeats for this domain.  This is used to "

  "ensure that the backend process is alive and capable of answering requests."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:524

+ #: sssd.conf.5.xml:633

  msgid "Default: 10"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:530

+ #: sssd.conf.5.xml:639

  msgid "enumerate (bool)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:533

+ #: sssd.conf.5.xml:642

  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:537

+ #: sssd.conf.5.xml:646

  msgid "TRUE = Users and groups are enumerated"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:540

+ #: sssd.conf.5.xml:649

  msgid "FALSE = No enumerations for this domain"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:543 sssd.conf.5.xml:591 sssd.conf.5.xml:645

+ #: sssd.conf.5.xml:652 sssd.conf.5.xml:704 sssd.conf.5.xml:758

  msgid "Default: FALSE"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:546

+ #: sssd.conf.5.xml:655

  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 "
@@ -785,14 +952,14 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:556

+ #: sssd.conf.5.xml:665

  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:561

+ #: sssd.conf.5.xml:670

  msgid ""

  "Further, enabling enumeration may increase the time necessary to detect "

  "network disconnection, as longer timeouts are required to ensure that "
@@ -801,39 +968,44 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:572

+ #: sssd.conf.5.xml:681

  msgid "entry_cache_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:575

+ #: sssd.conf.5.xml:684

  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:579

+ #: sssd.conf.5.xml:688

  msgid "Default: 5400"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:584

+ #: sssd.conf.5.xml:693

  msgid "cache_credentials (bool)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:587

+ #: sssd.conf.5.xml:696

  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:700

+ 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:596

+ #: sssd.conf.5.xml:709

  msgid "account_cache_expiration (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:599

+ #: sssd.conf.5.xml:712

  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 "
@@ -842,47 +1014,47 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:606

+ #: sssd.conf.5.xml:719

  msgid "Default: 0 (unlimited)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:612

+ #: sssd.conf.5.xml:725

  msgid "id_provider (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:615

+ #: sssd.conf.5.xml:728

  msgid "The Data Provider identity backend to use for this domain."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:619

+ #: sssd.conf.5.xml:732

  msgid "Supported backends:"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:622

+ #: sssd.conf.5.xml:735

  msgid "proxy: Support a legacy NSS provider"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:625

+ #: sssd.conf.5.xml:738

  msgid "local: SSSD internal local provider"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:628

+ #: sssd.conf.5.xml:741

  msgid "ldap: LDAP provider"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:634

+ #: sssd.conf.5.xml:747

  msgid "use_fully_qualified_names (bool)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:637

+ #: sssd.conf.5.xml:750

  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, "
@@ -891,19 +1063,19 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:650

+ #: sssd.conf.5.xml:763

  msgid "auth_provider (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:653

+ #: sssd.conf.5.xml:766

  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:657

+ #: sssd.conf.5.xml:770

  msgid ""

  "<quote>ldap</quote> for native LDAP authentication. See <citerefentry> "

  "<refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</manvolnum> "
@@ -911,7 +1083,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:664

+ #: sssd.conf.5.xml:777

  msgid ""

  "<quote>krb5</quote> for Kerberos authentication. See <citerefentry> "

  "<refentrytitle>sssd-krb5</refentrytitle> <manvolnum>5</manvolnum> "
@@ -919,29 +1091,29 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:671

+ #: sssd.conf.5.xml:784

  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:674

+ #: sssd.conf.5.xml:787

  msgid "<quote>none</quote> disables authentication explicitly."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:677

+ #: sssd.conf.5.xml:790

  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:683

+ #: sssd.conf.5.xml:796

  msgid "access_provider (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:686

+ #: sssd.conf.5.xml:799

  msgid ""

  "The access control provider used for the domain.  There are two built-in "

  "access providers (in addition to any included in installed backends)  "
@@ -949,17 +1121,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:692

+ #: sssd.conf.5.xml:805

  msgid "<quote>permit</quote> always allow access."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:695

+ #: sssd.conf.5.xml:808

  msgid "<quote>deny</quote> always deny access."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:698

+ #: sssd.conf.5.xml:811

  msgid ""

  "<quote>simple</quote> access control based on access or deny lists. See "

  "<citerefentry> <refentrytitle>sssd-simple</refentrytitle> "
@@ -968,24 +1140,24 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:705

+ #: sssd.conf.5.xml:818

  msgid "Default: <quote>permit</quote>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:710

+ #: sssd.conf.5.xml:823

  msgid "chpass_provider (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:713

+ #: sssd.conf.5.xml:826

  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:718

+ #: sssd.conf.5.xml:831

  msgid ""

  "<quote>ipa</quote> to change a password stored in an IPA server.  See "

  "<citerefentry> <refentrytitle>sssd-ipa</refentrytitle> "
@@ -994,7 +1166,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:726

+ #: sssd.conf.5.xml:839

  msgid ""

  "<quote>ldap</quote> to change a password stored in a LDAP server.  See "

  "<citerefentry> <refentrytitle>sssd-ldap</refentrytitle> "
@@ -1003,7 +1175,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:734

+ #: sssd.conf.5.xml:847

  msgid ""

  "<quote>krb5</quote> to change the Kerberos password. See <citerefentry> "

  "<refentrytitle>sssd-krb5</refentrytitle> <manvolnum>5</manvolnum> "
@@ -1011,71 +1183,71 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:742

+ #: sssd.conf.5.xml:855

  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:746

+ #: sssd.conf.5.xml:859

  msgid "<quote>none</quote> disallows password changes explicitly."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:749

+ #: sssd.conf.5.xml:862

  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:756

+ #: sssd.conf.5.xml:869

  msgid "lookup_family_order (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:759

+ #: sssd.conf.5.xml:872

  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:763

+ #: sssd.conf.5.xml:876

  msgid "Supported values:"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:766

+ #: sssd.conf.5.xml:879

  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:769

+ #: sssd.conf.5.xml:882

  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:772

+ #: sssd.conf.5.xml:885

  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:775

+ #: sssd.conf.5.xml:888

  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:778

+ #: sssd.conf.5.xml:891

  msgid "Default: ipv4_first"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:784

+ #: sssd.conf.5.xml:897

  msgid "dns_resolver_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:787

+ #: sssd.conf.5.xml:900

  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, "
@@ -1083,24 +1255,34 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:799

+ #: sssd.conf.5.xml:912

  msgid "dns_discovery_domain (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:802

+ #: sssd.conf.5.xml:915

  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:806

+ #: sssd.conf.5.xml:919

  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:925

+ msgid "override_gid (integer)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:928

+ msgid "Override the primary GID value with the one specified."

+ msgstr ""

+ 

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:490

+ #: sssd.conf.5.xml:599

  msgid ""

  "These configuration options can be present in a domain configuration "

  "section, that is, in a section called "
@@ -1109,29 +1291,29 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:818

+ #: sssd.conf.5.xml:940

  msgid "proxy_pam_target (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:821

+ #: sssd.conf.5.xml:943

  msgid "The proxy target PAM proxies to."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:824

+ #: sssd.conf.5.xml:946

  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:832

+ #: sssd.conf.5.xml:954

  msgid "proxy_lib_name (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:835

+ #: sssd.conf.5.xml:957

  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), "
@@ -1139,19 +1321,19 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:814

+ #: sssd.conf.5.xml:936

  msgid ""

  "Options valid for proxy domains.  <placeholder type=\"variablelist\" "

  "id=\"0\"/>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><title>

- #: sssd.conf.5.xml:847

+ #: sssd.conf.5.xml:969

  msgid "The local domain section"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

- #: sssd.conf.5.xml:849

+ #: sssd.conf.5.xml:971

  msgid ""

  "This section contains settings for domain that stores users and groups in "

  "SSSD native database, that is, a domain that uses "
@@ -1159,73 +1341,73 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:856

+ #: sssd.conf.5.xml:978

  msgid "default_shell (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:859

+ #: sssd.conf.5.xml:981

  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:863

+ #: sssd.conf.5.xml:985

  msgid "Default: <filename>/bin/bash</filename>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:868

+ #: sssd.conf.5.xml:990

  msgid "base_directory (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:871

+ #: sssd.conf.5.xml:993

  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:876

+ #: sssd.conf.5.xml:998

  msgid "Default: <filename>/home</filename>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:881

+ #: sssd.conf.5.xml:1003

  msgid "create_homedir (bool)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:884

+ #: sssd.conf.5.xml:1006

  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:888 sssd.conf.5.xml:900

+ #: sssd.conf.5.xml:1010 sssd.conf.5.xml:1022

  msgid "Default: TRUE"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:893

+ #: sssd.conf.5.xml:1015

  msgid "remove_homedir (bool)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:896

+ #: sssd.conf.5.xml:1018

  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:905

+ #: sssd.conf.5.xml:1027

  msgid "homedir_umask (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:908

+ #: sssd.conf.5.xml:1030

  msgid ""

  "Used by <citerefentry> <refentrytitle>sss_useradd</refentrytitle> "

  "<manvolnum>8</manvolnum> </citerefentry> to specify the default permissions "
@@ -1233,17 +1415,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:916

+ #: sssd.conf.5.xml:1038

  msgid "Default: 077"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:921

+ #: sssd.conf.5.xml:1043

  msgid "skel_dir (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:924

+ #: sssd.conf.5.xml:1046

  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 "
@@ -1252,17 +1434,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:934

+ #: sssd.conf.5.xml:1056

  msgid "Default: <filename>/etc/skel</filename>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:939

+ #: sssd.conf.5.xml:1061

  msgid "mail_dir (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:942

+ #: sssd.conf.5.xml:1064

  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 "
@@ -1270,17 +1452,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:949

+ #: sssd.conf.5.xml:1071

  msgid "Default: <filename>/var/mail</filename>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:954

+ #: sssd.conf.5.xml:1076

  msgid "userdel_cmd (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:957

+ #: sssd.conf.5.xml:1079

  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 "
@@ -1288,17 +1470,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:963

+ #: sssd.conf.5.xml:1085

  msgid "Default: None, no command is run"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd.conf.5.xml:973 sssd-ldap.5.xml:1357 sssd-simple.5.xml:126 sssd-ipa.5.xml:173 sssd-krb5.5.xml:405

+ #: sssd.conf.5.xml:1095 sssd-ldap.5.xml:1400 sssd-simple.5.xml:126 sssd-ipa.5.xml:230 sssd-krb5.5.xml:408

  msgid "EXAMPLE"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><programlisting>

- #: sssd.conf.5.xml:979

+ #: sssd.conf.5.xml:1101

  #, no-wrap

  msgid ""

  "[sssd]\n"
@@ -1328,7 +1510,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:975

+ #: sssd.conf.5.xml:1097

  msgid ""

  "The following example shows a typical SSSD config. It does not describe "

  "configuration of the domains themselves - refer to documentation on "
@@ -1337,7 +1519,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:1010

+ #: sssd.conf.5.xml:1132

  msgid ""

  "<citerefentry> "

  "<refentrytitle>sssd-ldap</refentrytitle><manvolnum>5</manvolnum> "
@@ -1406,49 +1588,69 @@

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-ldap.5.xml:63

  msgid ""

- "Specifies the 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 not specified, "

- "service discovery is enabled. For more information, refer to the "

- "<quote>SERVICE DISCOVERY</quote> section."

+ "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 not 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><term>

+ #. 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_chpass_uri (string)"

+ msgid "ldap[s]://&lt;host&gt;[:port]"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-ldap.5.xml:76

+ msgid "For explicit IPv6 addresses, &lt;host&gt; 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 (string)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:88

  msgid ""

- "Specifies the 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."

+ "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:83

+ #: 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:87

+ #: 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:93

+ #: 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:96

+ #: 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:100

+ #: sssd-ldap.5.xml:112

  msgid ""

  "Default: If not set the value of the defaultNamingContext or namingContexts "

  "attribute from the RootDSE of the LDAP server is used. If "
@@ -1459,12 +1661,12 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:114

+ #: sssd-ldap.5.xml:126

  msgid "ldap_schema (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:117

+ #: sssd-ldap.5.xml:129

  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 "
@@ -1478,201 +1680,206 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:136

+ #: sssd-ldap.5.xml:148

  msgid "Default: rfc2307"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:142

+ #: sssd-ldap.5.xml:154

  msgid "ldap_default_bind_dn (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:145

+ #: sssd-ldap.5.xml:157

  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:152

+ #: sssd-ldap.5.xml:164

  msgid "ldap_default_authtok_type (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:155

+ #: sssd-ldap.5.xml:167

  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:159

+ #: sssd-ldap.5.xml:171

  msgid "The two mechanisms currently supported are:"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:162

+ #: sssd-ldap.5.xml:174

  msgid "password"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:165

+ #: sssd-ldap.5.xml:177

  msgid "obfuscated_password"

  msgstr ""

  

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:180

+ msgid "Default: password"

+ msgstr ""

+ 

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:171

+ #: sssd-ldap.5.xml:186

  msgid "ldap_default_authtok (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:174

+ #: sssd-ldap.5.xml:189

  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:181

+ #: sssd-ldap.5.xml:196

  msgid "ldap_user_object_class (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:184

+ #: sssd-ldap.5.xml:199

  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:187

+ #: sssd-ldap.5.xml:202

  msgid "Default: posixAccount"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:193

+ #: sssd-ldap.5.xml:208

  msgid "ldap_user_name (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:196

+ #: sssd-ldap.5.xml:211

  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:200

+ #: sssd-ldap.5.xml:215

  msgid "Default: uid"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:206

+ #: sssd-ldap.5.xml:221

  msgid "ldap_user_uid_number (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:209

+ #: sssd-ldap.5.xml:224

  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:213

+ #: sssd-ldap.5.xml:228

  msgid "Default: uidNumber"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:219

+ #: sssd-ldap.5.xml:234

  msgid "ldap_user_gid_number (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:222

+ #: sssd-ldap.5.xml:237

  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:226 sssd-ldap.5.xml:622

+ #: sssd-ldap.5.xml:241 sssd-ldap.5.xml:637

  msgid "Default: gidNumber"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:232

+ #: sssd-ldap.5.xml:247

  msgid "ldap_user_gecos (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:235

+ #: sssd-ldap.5.xml:250

  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:239

+ #: sssd-ldap.5.xml:254

  msgid "Default: gecos"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:245

+ #: sssd-ldap.5.xml:260

  msgid "ldap_user_home_directory (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:248

+ #: sssd-ldap.5.xml:263

  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:252

+ #: sssd-ldap.5.xml:267

  msgid "Default: homeDirectory"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:258

+ #: sssd-ldap.5.xml:273

  msgid "ldap_user_shell (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:261

+ #: sssd-ldap.5.xml:276

  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:265

+ #: sssd-ldap.5.xml:280

  msgid "Default: loginShell"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:271

+ #: sssd-ldap.5.xml:286

  msgid "ldap_user_uuid (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:274

+ #: sssd-ldap.5.xml:289

  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:278 sssd-ldap.5.xml:648 sssd-ldap.5.xml:741

+ #: sssd-ldap.5.xml:293 sssd-ldap.5.xml:663 sssd-ldap.5.xml:756

  msgid "Default: nsUniqueId"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:284

+ #: sssd-ldap.5.xml:299

  msgid "ldap_user_modify_timestamp (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:287 sssd-ldap.5.xml:657 sssd-ldap.5.xml:750

+ #: sssd-ldap.5.xml:302 sssd-ldap.5.xml:672 sssd-ldap.5.xml:765

  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:291 sssd-ldap.5.xml:661 sssd-ldap.5.xml:754

+ #: sssd-ldap.5.xml:306 sssd-ldap.5.xml:676 sssd-ldap.5.xml:769

  msgid "Default: modifyTimestamp"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:297

+ #: sssd-ldap.5.xml:312

  msgid "ldap_user_shadow_last_change (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:300

+ #: sssd-ldap.5.xml:315

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> "
@@ -1681,17 +1888,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:310

+ #: sssd-ldap.5.xml:325

  msgid "Default: shadowLastChange"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:316

+ #: sssd-ldap.5.xml:331

  msgid "ldap_user_shadow_min (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:319

+ #: sssd-ldap.5.xml:334

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> "
@@ -1700,17 +1907,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:328

+ #: sssd-ldap.5.xml:343

  msgid "Default: shadowMin"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:334

+ #: sssd-ldap.5.xml:349

  msgid "ldap_user_shadow_max (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:337

+ #: sssd-ldap.5.xml:352

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> "
@@ -1719,17 +1926,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:346

+ #: sssd-ldap.5.xml:361

  msgid "Default: shadowMax"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:352

+ #: sssd-ldap.5.xml:367

  msgid "ldap_user_shadow_warning (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:355

+ #: sssd-ldap.5.xml:370

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> "
@@ -1738,17 +1945,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:365

+ #: sssd-ldap.5.xml:380

  msgid "Default: shadowWarning"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:371

+ #: sssd-ldap.5.xml:386

  msgid "ldap_user_shadow_inactive (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:374

+ #: sssd-ldap.5.xml:389

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> "
@@ -1757,17 +1964,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:384

+ #: sssd-ldap.5.xml:399

  msgid "Default: shadowInactive"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:390

+ #: sssd-ldap.5.xml:405

  msgid "ldap_user_shadow_expire (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:393

+ #: sssd-ldap.5.xml:408

  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 "
@@ -1777,17 +1984,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:403

+ #: sssd-ldap.5.xml:418

  msgid "Default: shadowExpire"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:409

+ #: sssd-ldap.5.xml:424

  msgid "ldap_user_krb_last_pwd_change (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:412

+ #: sssd-ldap.5.xml:427

  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 "
@@ -1795,102 +2002,102 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:418

+ #: sssd-ldap.5.xml:433

  msgid "Default: krbLastPwdChange"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:424

+ #: sssd-ldap.5.xml:439

  msgid "ldap_user_krb_password_expiration (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:427

+ #: sssd-ldap.5.xml:442

  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:433

+ #: sssd-ldap.5.xml:448

  msgid "Default: krbPasswordExpiration"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:439

+ #: sssd-ldap.5.xml:454

  msgid "ldap_user_ad_account_expires (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:442

+ #: sssd-ldap.5.xml:457

  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:447

+ #: sssd-ldap.5.xml:462

  msgid "Default: accountExpires"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:453

+ #: sssd-ldap.5.xml:468

  msgid "ldap_user_ad_user_account_control (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:456

+ #: sssd-ldap.5.xml:471

  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:461

+ #: sssd-ldap.5.xml:476

  msgid "Default: userAccountControl"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:467

+ #: sssd-ldap.5.xml:482

  msgid "ldap_ns_account_lock (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:470

+ #: sssd-ldap.5.xml:485

  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:475

+ #: sssd-ldap.5.xml:490

  msgid "Default: nsAccountLock"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:481

+ #: sssd-ldap.5.xml:496

  msgid "ldap_user_principal (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:484

+ #: sssd-ldap.5.xml:499

  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:488

+ #: sssd-ldap.5.xml:503

  msgid "Default: krbPrincipalName"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:494

+ #: sssd-ldap.5.xml:509

  msgid "ldap_force_upper_case_realm (boolean)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:497

+ #: sssd-ldap.5.xml:512

  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 "
@@ -1899,34 +2106,34 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:504 sssd-ldap.5.xml:961 sssd-ipa.5.xml:115 sssd.8.xml:64 sssd-krb5.5.xml:235 sssd-krb5.5.xml:266

+ #: sssd-ldap.5.xml:519 sssd-ldap.5.xml:990 sssd-ipa.5.xml:115 sssd.8.xml:64 sssd-krb5.5.xml:235 sssd-krb5.5.xml:269

  msgid "Default: false"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:510

+ #: sssd-ldap.5.xml:525

  msgid "ldap_enumeration_refresh_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:513

+ #: sssd-ldap.5.xml:528

  msgid ""

  "The LDAP attribute that contains how many seconds SSSD has to wait before "

  "refreshing its cache of enumerated records."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:518

+ #: sssd-ldap.5.xml:533

  msgid "Default: 300"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:524

+ #: sssd-ldap.5.xml:539

  msgid "ldap_purge_cache_timeout"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:527

+ #: sssd-ldap.5.xml:542

  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 "
@@ -1934,52 +2141,52 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:533

+ #: sssd-ldap.5.xml:548

  msgid "Setting this option to zero will disable the cache cleanup operation."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:537

+ #: sssd-ldap.5.xml:552

  msgid "Default: 10800 (12 hours)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:543

+ #: sssd-ldap.5.xml:558

  msgid "ldap_user_fullname (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:546

+ #: sssd-ldap.5.xml:561

  msgid "The LDAP attribute that corresponds to the user's full name."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:550 sssd-ldap.5.xml:609 sssd-ldap.5.xml:702

+ #: sssd-ldap.5.xml:565 sssd-ldap.5.xml:624 sssd-ldap.5.xml:717

  msgid "Default: cn"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:556

+ #: sssd-ldap.5.xml:571

  msgid "ldap_user_member_of (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:559

+ #: sssd-ldap.5.xml:574

  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:563

+ #: sssd-ldap.5.xml:578

  msgid "Default: memberOf"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:569

+ #: sssd-ldap.5.xml:584

  msgid "ldap_user_authorized_service (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:572

+ #: sssd-ldap.5.xml:587

  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 "
@@ -1987,89 +2194,89 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:579

+ #: sssd-ldap.5.xml:594

  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:584

+ #: sssd-ldap.5.xml:599

  msgid "Default: authorizedService"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:590

+ #: sssd-ldap.5.xml:605

  msgid "ldap_group_object_class (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:593

+ #: sssd-ldap.5.xml:608

  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:596

+ #: sssd-ldap.5.xml:611

  msgid "Default: posixGroup"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:602

+ #: sssd-ldap.5.xml:617

  msgid "ldap_group_name (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:605

+ #: sssd-ldap.5.xml:620

  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:615

+ #: sssd-ldap.5.xml:630

  msgid "ldap_group_gid_number (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:618

+ #: sssd-ldap.5.xml:633

  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:628

+ #: sssd-ldap.5.xml:643

  msgid "ldap_group_member (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:631

+ #: sssd-ldap.5.xml:646

  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:635

+ #: sssd-ldap.5.xml:650

  msgid "Default: memberuid (rfc2307) / member (rfc2307bis)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:641

+ #: sssd-ldap.5.xml:656

  msgid "ldap_group_uuid (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:644

+ #: sssd-ldap.5.xml:659

  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:654

+ #: sssd-ldap.5.xml:669

  msgid "ldap_group_modify_timestamp (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:667

+ #: sssd-ldap.5.xml:682

  msgid "ldap_group_nesting_level (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:670

+ #: sssd-ldap.5.xml:685

  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 "
@@ -2077,87 +2284,87 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:677

+ #: sssd-ldap.5.xml:692

  msgid "Default: 2"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:683

+ #: sssd-ldap.5.xml:698

  msgid "ldap_netgroup_object_class (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:686

+ #: sssd-ldap.5.xml:701

  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:689

+ #: sssd-ldap.5.xml:704

  msgid "Default: nisNetgroup"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:695

+ #: sssd-ldap.5.xml:710

  msgid "ldap_netgroup_name (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:698

+ #: sssd-ldap.5.xml:713

  msgid "The LDAP attribute that corresponds to the netgroup name."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:708

+ #: sssd-ldap.5.xml:723

  msgid "ldap_netgroup_member (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:711

+ #: sssd-ldap.5.xml:726

  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:715

+ #: sssd-ldap.5.xml:730

  msgid "Default: memberNisNetgroup"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:721

+ #: sssd-ldap.5.xml:736

  msgid "ldap_netgroup_triple (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:724

+ #: sssd-ldap.5.xml:739

  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:728

+ #: sssd-ldap.5.xml:743

  msgid "Default: nisNetgroupTriple"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:734

+ #: sssd-ldap.5.xml:749

  msgid "ldap_netgroup_uuid (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:737

+ #: sssd-ldap.5.xml:752

  msgid "The LDAP attribute that contains the UUID/GUID of an LDAP netgroup object."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:747

+ #: sssd-ldap.5.xml:762

  msgid "ldap_netgroup_modify_timestamp (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:760

+ #: sssd-ldap.5.xml:775

  msgid "ldap_search_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:763

+ #: sssd-ldap.5.xml:778

  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 "
@@ -2165,7 +2372,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:769

+ #: sssd-ldap.5.xml:784

  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 "
@@ -2173,17 +2380,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:775 sssd-ldap.5.xml:817 sssd-ldap.5.xml:832

+ #: sssd-ldap.5.xml:790 sssd-ldap.5.xml:832 sssd-ldap.5.xml:847

  msgid "Default: 6"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:781

+ #: sssd-ldap.5.xml:796

  msgid "ldap_enumeration_search_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:784

+ #: sssd-ldap.5.xml:799

  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 "
@@ -2191,17 +2398,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:791

+ #: sssd-ldap.5.xml:806

  msgid "Default: 60"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:797

+ #: sssd-ldap.5.xml:812

  msgid "ldap_network_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:800

+ #: sssd-ldap.5.xml:815

  msgid ""

  "Specifies the timeout (in seconds) after which the <citerefentry> "

  "<refentrytitle>poll</refentrytitle> <manvolnum>2</manvolnum> "
@@ -2212,12 +2419,12 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:823

+ #: sssd-ldap.5.xml:838

  msgid "ldap_opt_timeout (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:826

+ #: sssd-ldap.5.xml:841

  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 "
@@ -2225,26 +2432,43 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:838

+ #: sssd-ldap.5.xml:853

+ msgid "ldap_page_size (integer)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:856

+ 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:861

+ msgid "Default: 1000"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #: sssd-ldap.5.xml:867

  msgid "ldap_tls_reqcert (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:841

+ #: sssd-ldap.5.xml:870

  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:847

+ #: sssd-ldap.5.xml:876

  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:851

+ #: sssd-ldap.5.xml:880

  msgid ""

  "<emphasis>allow</emphasis> = The server certificate is requested. If no "

  "certificate is provided, the session proceeds normally. If a bad certificate "
@@ -2252,7 +2476,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:858

+ #: sssd-ldap.5.xml:887

  msgid ""

  "<emphasis>try</emphasis> = The server certificate is requested. If no "

  "certificate is provided, the session proceeds normally. If a bad certificate "
@@ -2260,7 +2484,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:864

+ #: sssd-ldap.5.xml:893

  msgid ""

  "<emphasis>demand</emphasis> = The server certificate is requested. If no "

  "certificate is provided, or a bad certificate is provided, the session is "
@@ -2268,41 +2492,41 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:870

+ #: sssd-ldap.5.xml:899

  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:874

+ #: sssd-ldap.5.xml:903

  msgid "Default: hard"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:880

+ #: sssd-ldap.5.xml:909

  msgid "ldap_tls_cacert (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:883

+ #: sssd-ldap.5.xml:912

  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:888 sssd-ldap.5.xml:906 sssd-ldap.5.xml:947

+ #: sssd-ldap.5.xml:917 sssd-ldap.5.xml:935 sssd-ldap.5.xml:976

  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:895

+ #: sssd-ldap.5.xml:924

  msgid "ldap_tls_cacertdir (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:898

+ #: sssd-ldap.5.xml:927

  msgid ""

  "Specifies the path of a directory that contains Certificate Authority "

  "certificates in separate individual files. Typically the file names need to "
@@ -2311,37 +2535,37 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:913

+ #: sssd-ldap.5.xml:942

  msgid "ldap_tls_cert (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:916

+ #: sssd-ldap.5.xml:945

  msgid "Specifies the file that contains the certificate for the client's key."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:920 sssd-ldap.5.xml:932 sssd-krb5.5.xml:356

+ #: sssd-ldap.5.xml:949 sssd-ldap.5.xml:961 sssd-krb5.5.xml:359

  msgid "Default: not set"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:926

+ #: sssd-ldap.5.xml:955

  msgid "ldap_tls_key (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:929

+ #: sssd-ldap.5.xml:958

  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:938

+ #: sssd-ldap.5.xml:967

  msgid "ldap_tls_cipher_suite (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:941

+ #: sssd-ldap.5.xml:970

  msgid ""

  "Specifies acceptable cipher suites.  Typically this is a colon sperated "

  "list.  See <citerefentry><refentrytitle>ldap.conf</refentrytitle> "
@@ -2349,73 +2573,90 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:954

+ #: sssd-ldap.5.xml:983

  msgid "ldap_id_use_start_tls (boolean)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:957

+ #: sssd-ldap.5.xml:986

  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:967

+ #: sssd-ldap.5.xml:996

  msgid "ldap_sasl_mech (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:970

+ #: sssd-ldap.5.xml:999

  msgid ""

  "Specify the SASL mechanism to use.  Currently only GSSAPI is tested and "

  "supported."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:974 sssd-ldap.5.xml:1102

+ #: sssd-ldap.5.xml:1003 sssd-ldap.5.xml:1145

  msgid "Default: none"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:980

+ #: sssd-ldap.5.xml:1009

  msgid "ldap_sasl_authid (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:983

+ #: sssd-ldap.5.xml:1012

  msgid ""

  "Specify the SASL authorization id to use.  When GSSAPI is used, this "

  "represents the Kerberos principal used for authentication to the directory."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:988

+ #: sssd-ldap.5.xml:1017

  msgid "Default: host/machine.fqdn@REALM"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:994

+ #: sssd-ldap.5.xml:1023

+ msgid "ldap_sasl_canonicalize (boolean)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:1026

+ 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:1031

+ msgid "Default: false;"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #: sssd-ldap.5.xml:1037

  msgid "ldap_krb5_keytab (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:997

+ #: sssd-ldap.5.xml:1040

  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:1000

+ #: sssd-ldap.5.xml:1043

  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:1006

+ #: sssd-ldap.5.xml:1049

  msgid "ldap_krb5_init_creds (boolean)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1009

+ #: sssd-ldap.5.xml:1052

  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 "
@@ -2423,38 +2664,39 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1021

+ #: sssd-ldap.5.xml:1064

  msgid "ldap_krb5_ticket_lifetime (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1024

+ #: sssd-ldap.5.xml:1067

  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:1028

+ #: sssd-ldap.5.xml:1071

  msgid "Default: 86400 (24 hours)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1034 sssd-krb5.5.xml:74

+ #: sssd-ldap.5.xml:1077 sssd-krb5.5.xml:74

  msgid "krb5_server (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1037 sssd-krb5.5.xml:77

+ #: sssd-ldap.5.xml:1080 sssd-krb5.5.xml:77

  msgid ""

- "Specifies the 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."

+ "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:1049 sssd-krb5.5.xml:89

+ #: sssd-ldap.5.xml:1092 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 "
@@ -2462,7 +2704,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1054 sssd-krb5.5.xml:94

+ #: sssd-ldap.5.xml:1097 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 "
@@ -2471,41 +2713,41 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1063 sssd-krb5.5.xml:103

+ #: sssd-ldap.5.xml:1106 sssd-ipa.5.xml:165 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:1066

+ #: sssd-ldap.5.xml:1109

  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:1069

+ #: sssd-ldap.5.xml:1112

  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:1075

+ #: sssd-ldap.5.xml:1118

  msgid "ldap_pwd_policy (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1078

+ #: sssd-ldap.5.xml:1121

  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:1083

+ #: sssd-ldap.5.xml:1126

  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:1088

+ #: sssd-ldap.5.xml:1131

  msgid ""

  "<emphasis>shadow</emphasis> - Use "

  "<citerefentry><refentrytitle>shadow</refentrytitle> "
@@ -2515,7 +2757,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1096

+ #: sssd-ldap.5.xml:1139

  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 "
@@ -2523,61 +2765,61 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1108

+ #: sssd-ldap.5.xml:1151

  msgid "ldap_referrals (boolean)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1111

+ #: sssd-ldap.5.xml:1154

  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:1115

+ #: sssd-ldap.5.xml:1158

  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><term>

- #: sssd-ldap.5.xml:1126

+ #: sssd-ldap.5.xml:1169

  msgid "ldap_dns_service_name (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1129

+ #: sssd-ldap.5.xml:1172

  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:1133

+ #: sssd-ldap.5.xml:1176

  msgid "Default: ldap"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1139

+ #: sssd-ldap.5.xml:1182

  msgid "ldap_chpass_dns_service_name (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1142

+ #: sssd-ldap.5.xml:1185

  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:1147

+ #: sssd-ldap.5.xml:1190

  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:1153

+ #: sssd-ldap.5.xml:1196

  msgid "ldap_access_filter (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1156

+ #: sssd-ldap.5.xml:1199

  msgid ""

  "If using access_provider = ldap, this option is mandatory. It specifies an "

  "LDAP search filter criteria that must be met for the user to be granted "
@@ -2587,12 +2829,12 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1166

+ #: sssd-ldap.5.xml:1209

  msgid "Example:"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><programlisting>

- #: sssd-ldap.5.xml:1169

+ #: sssd-ldap.5.xml:1212

  #, no-wrap

  msgid ""

  "access_provider = ldap\n"
@@ -2601,14 +2843,14 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1173

+ #: sssd-ldap.5.xml:1216

  msgid ""

  "This example means that access to this host is restricted to members of the "

  "\"allowedusers\" group in ldap."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1178

+ #: sssd-ldap.5.xml:1221

  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 "
@@ -2617,24 +2859,24 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1186 sssd-ldap.5.xml:1227

+ #: sssd-ldap.5.xml:1229 sssd-ldap.5.xml:1270

  msgid "Default: Empty"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1192

+ #: sssd-ldap.5.xml:1235

  msgid "ldap_account_expire_policy (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1195

+ #: sssd-ldap.5.xml:1238

  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:1199

+ #: sssd-ldap.5.xml:1242

  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 "
@@ -2642,19 +2884,19 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1206

+ #: sssd-ldap.5.xml:1249

  msgid "The following values are allowed:"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1209

+ #: sssd-ldap.5.xml:1252

  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:1214

+ #: sssd-ldap.5.xml:1257

  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 "
@@ -2663,7 +2905,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1221

+ #: sssd-ldap.5.xml:1264

  msgid ""

  "<emphasis>rhds</emphasis>, <emphasis>ipa</emphasis>, "

  "<emphasis>389ds</emphasis>: use the value of ldap_ns_account_lock to check "
@@ -2671,84 +2913,84 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1233

+ #: sssd-ldap.5.xml:1276

  msgid "ldap_access_order (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1236

+ #: sssd-ldap.5.xml:1279

  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:1240

+ #: sssd-ldap.5.xml:1283

  msgid "<emphasis>filter</emphasis>: use ldap_access_filter"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1243

+ #: sssd-ldap.5.xml:1286

  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:1247

+ #: sssd-ldap.5.xml:1290

  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:1252

+ #: sssd-ldap.5.xml:1295

  msgid "Default: filter"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1255

+ #: sssd-ldap.5.xml:1298

  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:1262

+ #: sssd-ldap.5.xml:1305

  msgid "ldap_deref (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1265

+ #: sssd-ldap.5.xml:1308

  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:1270

+ #: sssd-ldap.5.xml:1313

  msgid "<emphasis>never</emphasis>: Aliases are never dereferenced."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1274

+ #: sssd-ldap.5.xml:1317

  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:1279

+ #: sssd-ldap.5.xml:1322

  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:1284

+ #: sssd-ldap.5.xml:1327

  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:1289

+ #: sssd-ldap.5.xml:1332

  msgid ""

  "Default: Empty (this is handled as <emphasis>never</emphasis> by the LDAP "

  "client libraries)"
@@ -2765,47 +3007,47 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd-ldap.5.xml:1301

+ #: sssd-ldap.5.xml:1344

  msgid "ADVANCED OPTIONS"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1308

+ #: sssd-ldap.5.xml:1351

  msgid "ldap_netgroup_search_base (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1311

+ #: sssd-ldap.5.xml:1354

  msgid "An optional base DN to restrict netgroup searches to a specific subtree."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1315 sssd-ldap.5.xml:1329 sssd-ldap.5.xml:1343

+ #: sssd-ldap.5.xml:1358 sssd-ldap.5.xml:1372 sssd-ldap.5.xml:1386

  msgid "Default: the value of <emphasis>ldap_search_base</emphasis>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1322

+ #: sssd-ldap.5.xml:1365

  msgid "ldap_user_search_base (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1325

+ #: sssd-ldap.5.xml:1368

  msgid "An optional base DN to restrict user searches to a specific subtree."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1336

+ #: sssd-ldap.5.xml:1379

  msgid "ldap_group_search_base (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1339

+ #: sssd-ldap.5.xml:1382

  msgid "An optional base DN to restrict group searches to a specific subtree."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1303

+ #: sssd-ldap.5.xml:1346

  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 "
@@ -2813,7 +3055,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1359

+ #: sssd-ldap.5.xml:1402

  msgid ""

  "The following example assumes that SSSD is correctly configured and LDAP is "

  "set to one of the domains in the <replaceable>[domains]</replaceable> "
@@ -2821,7 +3063,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><programlisting>

- #: sssd-ldap.5.xml:1365

+ #: sssd-ldap.5.xml:1408

  #, no-wrap

  msgid ""

  "    [domain/LDAP]\n"
@@ -2835,17 +3077,17 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1364 sssd-simple.5.xml:134 sssd-ipa.5.xml:181 sssd-krb5.5.xml:414

+ #: sssd-ldap.5.xml:1407 sssd-simple.5.xml:134 sssd-ipa.5.xml:238 sssd-krb5.5.xml:417

  msgid "<placeholder type=\"programlisting\" id=\"0\"/>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd-ldap.5.xml:1378 sssd_krb5_locator_plugin.8.xml:61

+ #: sssd-ldap.5.xml:1421 sssd_krb5_locator_plugin.8.xml:61

  msgid "NOTES"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1380

+ #: sssd-ldap.5.xml:1423

  msgid ""

  "The descriptions of some of the configuration options in this manual page "

  "are based on the <citerefentry> <refentrytitle>ldap.conf</refentrytitle> "
@@ -2854,7 +3096,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1391

+ #: sssd-ldap.5.xml:1434

  msgid ""

  "<citerefentry> "

  "<refentrytitle>sssd.conf</refentrytitle><manvolnum>5</manvolnum> "
@@ -2885,6 +3127,7 @@

  #: 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'> "
@@ -2892,7 +3135,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:42

+ #: pam_sss.8.xml:45

  msgid ""

  "<command>pam_sss.so</command> is the PAM interface to the System Security "

  "Services daemon (SSSD). Errors and results are logged through "
@@ -2900,24 +3143,34 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: pam_sss.8.xml:52

+ #: pam_sss.8.xml:55

+ msgid "<option>quiet</option>"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

+ #: pam_sss.8.xml:58

+ msgid "Suppress log messages for unknown users."

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

+ #: pam_sss.8.xml:63

  msgid "<option>forward_pass</option>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:55

+ #: pam_sss.8.xml:66

  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:62

+ #: pam_sss.8.xml:73

  msgid "<option>use_first_pass</option>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:65

+ #: pam_sss.8.xml:76

  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 "
@@ -2926,31 +3179,31 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: pam_sss.8.xml:73

+ #: pam_sss.8.xml:84

  msgid "<option>use_authtok</option>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:76

+ #: pam_sss.8.xml:87

  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:83

+ #: pam_sss.8.xml:94

  msgid "<option>retry=N</option>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:86

+ #: pam_sss.8.xml:97

  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:88

+ #: pam_sss.8.xml:99

  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 "
@@ -2958,24 +3211,24 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><title>

- #: pam_sss.8.xml:99

+ #: pam_sss.8.xml:110

  msgid "MODULE TYPES PROVIDED"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:100

+ #: pam_sss.8.xml:111

  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:106

+ #: pam_sss.8.xml:117

  msgid "FILES"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:107

+ #: pam_sss.8.xml:118

  msgid ""

  "If a password reset by root fails, because the corresponding SSSD provider "

  "does not support password resets, an individual message can be "
@@ -2984,7 +3237,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:112

+ #: pam_sss.8.xml:123

  msgid ""

  "The message is read from the file "

  "<filename>pam_sss_pw_reset_message.LOC</filename> where LOC stands for a "
@@ -2997,7 +3250,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:122

+ #: pam_sss.8.xml:133

  msgid ""

  "These files are searched in the directory "

  "<filename>/etc/sssd/customize/DOMAIN_NAME/</filename>. If no matching file "
@@ -3005,7 +3258,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:130

+ #: pam_sss.8.xml:141

  msgid ""

  "<citerefentry> "

  "<refentrytitle>sssd.conf</refentrytitle><manvolnum>8</manvolnum> "
@@ -3272,11 +3525,12 @@

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-ipa.5.xml:83

  msgid ""

- "The 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 the <quote>SERVICE DISCOVERY</quote> section."

+ "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 the <quote>SERVICE DISCOVERY</quote> "

+ "section."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>
@@ -3354,8 +3608,73 @@

  "end."

  msgstr ""

  

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:168

+ 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:172

+ 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><term>

+ #: sssd-ipa.5.xml:179

+ msgid "ipa_hbac_refresh (integer)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:182

+ 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:189

+ msgid "Default: 5 (seconds)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #: sssd-ipa.5.xml:194

+ msgid "ipa_hbac_treat_deny_as (string)"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:197

+ msgid ""

+ "This option specifies how to treat the deprecated DENY-type HBAC rules. As "

+ "of FreeIPA v2.1, DENY rules are no longer supported on the server. All users "

+ "of FreeIPA will need to migrate their rules to use only the ALLOW rules. The "

+ "client will support two modes of operation during this transition period:"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:206

+ msgid ""

+ "<emphasis>DENY_ALL</emphasis>: If any HBAC DENY rules are detected, all "

+ "users will be denied access."

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:211

+ msgid ""

+ "<emphasis>IGNORE</emphasis>: SSSD will ignore any DENY rules. Be very "

+ "careful with this option, as it may result in opening unintended access."

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:216

+ msgid "Default: DENY_ALL"

+ msgstr ""

+ 

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ipa.5.xml:175

+ #: sssd-ipa.5.xml:232

  msgid ""

  "The following example assumes that SSSD is correctly configured and "

  "example.com is one of the domains in the <replaceable>[sssd]</replaceable> "
@@ -3363,7 +3682,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><programlisting>

- #: sssd-ipa.5.xml:182

+ #: sssd-ipa.5.xml:239

  #, no-wrap

  msgid ""

  "    [domain/example.com]\n"
@@ -3373,7 +3692,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ipa.5.xml:193

+ #: sssd-ipa.5.xml:250

  msgid ""

  "<citerefentry> "

  "<refentrytitle>sssd.conf</refentrytitle><manvolnum>5</manvolnum> "
@@ -3580,17 +3899,17 @@

  #. type: Content of: <reference><refentry><refsect1><para>

  #: sss_obfuscate.8.xml:37

  msgid ""

- "The cleartext password can be specified as an argument to the program, 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 "

+ "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:50

+ #: 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 "
@@ -3600,46 +3919,46 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: sss_obfuscate.8.xml:64

+ #: 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:68

+ #: 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:75

+ #: sss_obfuscate.8.xml:74

  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:80

+ #: 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:87

+ #: 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:92

+ #: 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:96

+ #: sss_obfuscate.8.xml:95

  msgid "Default: <filename>/etc/sssd/sssd.conf</filename>"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sss_obfuscate.8.xml:106

+ #: sss_obfuscate.8.xml:105

  msgid ""

  "<citerefentry> <refentrytitle>sssd-ldap</refentrytitle> "

  "<manvolnum>5</manvolnum> </citerefentry>"
@@ -3928,21 +4247,6 @@

  msgid "krb5_ccname_template (string)"

  msgstr ""

  

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:166

- msgid "%u"

- msgstr ""

- 

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:167

- msgid "login name"

- msgstr ""

- 

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:170

- msgid "%U"

- msgstr ""

- 

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

  #: sssd-krb5.5.xml:171

  msgid "login UID"
@@ -3978,11 +4282,6 @@

  msgid "home directory"

  msgstr ""

  

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:188

- msgid "%d"

- msgstr ""

- 

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

  #: sssd-krb5.5.xml:189

  msgid "value of krb5ccache_dir"
@@ -3998,16 +4297,6 @@

  msgid "the process ID of the sssd client"

  msgstr ""

  

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:200

- msgid "%%"

- msgstr ""

- 

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:201

- msgid "a literal '%'"

- msgstr ""

- 

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-krb5.5.xml:160

  msgid ""
@@ -4066,48 +4355,51 @@

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-krb5.5.xml:262

- msgid "Please note that this feature currently only available on a Linux platform."

+ msgid ""

+ "Please note that this feature currently only available on a Linux "

+ "platform. 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:272

+ #: sssd-krb5.5.xml:275

  msgid "krb5_renewable_lifetime (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:275

+ #: sssd-krb5.5.xml:278

  msgid ""

  "Request a renewable ticket with a total lifetime given by an integer "

  "immediately followed by one of the following delimiters:"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:280 sssd-krb5.5.xml:316

+ #: sssd-krb5.5.xml:283 sssd-krb5.5.xml:319

  msgid "<emphasis>s</emphasis> seconds"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:283 sssd-krb5.5.xml:319

+ #: sssd-krb5.5.xml:286 sssd-krb5.5.xml:322

  msgid "<emphasis>m</emphasis> minutes"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:286 sssd-krb5.5.xml:322

+ #: sssd-krb5.5.xml:289 sssd-krb5.5.xml:325

  msgid "<emphasis>h</emphasis> hours"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:289 sssd-krb5.5.xml:325

+ #: sssd-krb5.5.xml:292 sssd-krb5.5.xml:328

  msgid "<emphasis>d</emphasis> days."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:292 sssd-krb5.5.xml:328

+ #: sssd-krb5.5.xml:295 sssd-krb5.5.xml:331

  msgid "If there is no delimiter <emphasis>s</emphasis> is assumed."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:296

+ #: sssd-krb5.5.xml:299

  msgid ""

  "Please note that it is not possible to mix units.  If you want to set the "

  "renewable lifetime to one and a half hours please use '90m' instead of "
@@ -4115,96 +4407,96 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:302

+ #: sssd-krb5.5.xml:305

  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:308

+ #: sssd-krb5.5.xml:311

  msgid "krb5_lifetime (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:311

+ #: sssd-krb5.5.xml:314

  msgid ""

  "Request ticket with a with a lifetime given by an integer immediately "

  "followed by one of the following delimiters:"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:332

+ #: sssd-krb5.5.xml:335

  msgid ""

  "Please note that it is not possible to mix units.  If you want 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:337

+ #: sssd-krb5.5.xml:340

  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:344

+ #: sssd-krb5.5.xml:347

  msgid "krb5_renew_interval (integer)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:347

+ #: sssd-krb5.5.xml:350

  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."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:352

+ #: sssd-krb5.5.xml:355

  msgid "If this option is not set or 0 the automatic renewal is disabled."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:362

+ #: sssd-krb5.5.xml:365

  msgid "krb5_use_fast (string)"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:365

+ #: sssd-krb5.5.xml:368

  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-krb5.5.xml:370

+ #: sssd-krb5.5.xml:373

  msgid ""

  "<emphasis>never</emphasis> use FAST, this is equivalent to not set this "

  "option at all."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:374

+ #: sssd-krb5.5.xml:377

  msgid ""

  "<emphasis>try</emphasis> to use FAST, if the server does not support fast "

  "continue without."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:378

+ #: sssd-krb5.5.xml:381

  msgid ""

  "<emphasis>demand</emphasis> to use FAST, fail if the server does not require "

  "fast."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:382

+ #: sssd-krb5.5.xml:385

  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:385

+ #: sssd-krb5.5.xml:388

  msgid "Please note that a keytab is required to use fast."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:388

+ #: sssd-krb5.5.xml:391

  msgid ""

  "Please note also that sssd supports fast only with MIT Kerberos version 1.8 "

  "and above. If sssd used used with an older version using this option is a "
@@ -4222,7 +4514,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-krb5.5.xml:407

+ #: sssd-krb5.5.xml:410

  msgid ""

  "The following example assumes that SSSD is correctly configured and FOO is "

  "one of the domains in the <replaceable>[sssd]</replaceable> section. This "
@@ -4231,7 +4523,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><programlisting>

- #: sssd-krb5.5.xml:415

+ #: sssd-krb5.5.xml:418

  #, no-wrap

  msgid ""

  "    [domain/FOO]\n"
@@ -4241,7 +4533,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-krb5.5.xml:426

+ #: sssd-krb5.5.xml:429

  msgid ""

  "<citerefentry> "

  "<refentrytitle>sssd.conf</refentrytitle><manvolnum>5</manvolnum> "

file added
+4992
The added file is too large to be shown here, see it at: src/man/po/sv.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/ta.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/ta_IN.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/te.po
file added
+6017
The added file is too large to be shown here, see it at: src/man/po/tg.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/tr.po
file modified
+892 -538
@@ -6,7 +6,7 @@

  msgstr ""

  "Project-Id-Version: sssd-docs 1.5.0\n"

  "Report-Msgid-Bugs-To: sssd-devel@redhat.com\n"

- "POT-Creation-Date: 2011-01-24 13:36-0500\n"

+ "POT-Creation-Date: 2011-10-18 13:34-0300\n"

  "PO-Revision-Date: 2011-01-25 20:56+0200\n"

  "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"

  "Language-Team: Ukrainian <translation@linux.org.ua>\n"
@@ -62,7 +62,7 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sss_groupmod.8.xml:30 sssd-ldap.5.xml:21 pam_sss.8.xml:41

+ #: sss_groupmod.8.xml:30 sssd-ldap.5.xml:21 pam_sss.8.xml:44

  #: sssd_krb5_locator_plugin.8.xml:20 sssd-simple.5.xml:22 sssd-ipa.5.xml:21

  #: sssd.8.xml:29 sss_obfuscate.8.xml:30 sss_useradd.8.xml:30

  #: sssd-krb5.5.xml:21 sss_groupadd.8.xml:30 sss_userdel.8.xml:30
@@ -82,7 +82,7 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sss_groupmod.8.xml:39 pam_sss.8.xml:48 sssd.8.xml:42 sss_obfuscate.8.xml:59

+ #: sss_groupmod.8.xml:39 pam_sss.8.xml:51 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

  msgid "OPTIONS"
@@ -132,10 +132,10 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sss_groupmod.8.xml:72 sssd.conf.5.xml:1008 sssd-ldap.5.xml:1389

- #: pam_sss.8.xml:128 sssd_krb5_locator_plugin.8.xml:75 sssd-simple.5.xml:143

- #: sssd-ipa.5.xml:191 sssd.8.xml:166 sss_obfuscate.8.xml:104

- #: sss_useradd.8.xml:167 sssd-krb5.5.xml:424 sss_groupadd.8.xml:58

+ #: sss_groupmod.8.xml:72 sssd.conf.5.xml:1130 sssd-ldap.5.xml:1432

+ #: pam_sss.8.xml:139 sssd_krb5_locator_plugin.8.xml:75 sssd-simple.5.xml:143

+ #: sssd-ipa.5.xml:248 sssd.8.xml:166 sss_obfuscate.8.xml:103

+ #: sss_useradd.8.xml:167 sssd-krb5.5.xml:427 sss_groupadd.8.xml:58

  #: sss_userdel.8.xml:93 sss_groupdel.8.xml:46 sss_groupshow.8.xml:58

  #: sss_usermod.8.xml:138

  msgid "SEE ALSO"
@@ -282,7 +282,7 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><title>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><title>

- #: sssd.conf.5.xml:70 sssd.conf.5.xml:854

+ #: sssd.conf.5.xml:70 sssd.conf.5.xml:976

  msgid "Section parameters"

  msgstr "Параметри розділу"

  
@@ -325,13 +325,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:93 sssd.conf.5.xml:234

+ #: sssd.conf.5.xml:93 sssd.conf.5.xml:254

  msgid "reconnection_retries (integer)"

  msgstr "reconnection_retries (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:96 sssd.conf.5.xml:237

+ #: sssd.conf.5.xml:96 sssd.conf.5.xml:257

  msgid ""

  "Number of times services should attempt to reconnect in the event of a Data "

  "Provider crash or restart before they give up"
@@ -342,7 +342,7 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:101 sssd.conf.5.xml:242

+ #: sssd.conf.5.xml:101 sssd.conf.5.xml:262

  msgid "Default: 3"

  msgstr "Типове значення: 3"

  
@@ -494,6 +494,35 @@

  "недоступний. На цих платформах завжди використовуватиметься безпосереднє "

  "опитування файла."

  

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:189

+ #, fuzzy

+ #| msgid "krb5_ccachedir (string)"

+ msgid "krb5_rcache_dir (string)"

+ msgstr "krb5_ccachedir (рядок)"

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:192

+ 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:196

+ 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:202

+ msgid ""

+ "Default: Distribution-specific and specified at build-time. "

+ "(__LIBKRB5_DEFAULTS__ if not configured)"

+ msgstr ""

+ 

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

  #: sssd.conf.5.xml:63

  msgid ""
@@ -512,13 +541,13 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd.conf.5.xml:195

+ #: sssd.conf.5.xml:215

  msgid "SERVICES SECTIONS"

  msgstr "РОЗДІЛИ СЛУЖБ"

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:197

+ #: sssd.conf.5.xml:217

  msgid ""

  "Settings that can be used to configure different services are described in "

  "this section. They should reside in the [<replaceable>$NAME</replaceable>] "
@@ -532,25 +561,25 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><title>

  #. type: Content of: <reference><refentry><refsect1><refsect2><title>

- #: sssd.conf.5.xml:204

+ #: sssd.conf.5.xml:224

  msgid "General service configuration options"

  msgstr "Загальні параметри налаштування служб"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

- #: sssd.conf.5.xml:206

+ #: sssd.conf.5.xml:226

  msgid "These options can be used to configure any service."

  msgstr "Цими параметрами можна скористатися для налаштування будь-яких служб."

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:210

+ #: sssd.conf.5.xml:230

  msgid "debug_level (integer)"

  msgstr "debug_level (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:213

+ #: sssd.conf.5.xml:233

  msgid ""

  "Sets the debug level for the service. The value can be in range from 0 (only "

  "critical messages) to 10 (very verbose)."
@@ -561,38 +590,38 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:218 sssd.conf.5.xml:312

+ #: sssd.conf.5.xml:238 sssd.conf.5.xml:332

  msgid "Default: 0"

  msgstr "Типове значення: 0"

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:223 sssd.8.xml:58

+ #: sssd.conf.5.xml:243 sssd.8.xml:58

  msgid "debug_timestamps (bool)"

  msgstr "debug_timestamps (булеве значення)"

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:226 sssd.8.xml:61

+ #: sssd.conf.5.xml:246 sssd.8.xml:61

  msgid "Add a timestamp to the debug messages"

  msgstr "Додати часову позначку до діагностичних повідомлень."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:229 sssd.conf.5.xml:353 sssd-ldap.5.xml:1015

- #: sssd-ldap.5.xml:1120 sssd-ipa.5.xml:155

+ #: sssd.conf.5.xml:249 sssd.conf.5.xml:373 sssd-ldap.5.xml:1058

+ #: sssd-ldap.5.xml:1163 sssd-ipa.5.xml:155

  msgid "Default: true"

  msgstr "Типове значення: true"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:247

+ #: sssd.conf.5.xml:267

  msgid "command (string)"

  msgstr "command (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:250

+ #: sssd.conf.5.xml:270

  msgid ""

  "By default, the executable representing this service is called <command>sssd_"

  "${service_name}</command>.  This directive allows to change the executable "
@@ -605,19 +634,19 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:258

+ #: sssd.conf.5.xml:278

  msgid "Default: <command>sssd_${service_name}</command>"

  msgstr "Типове значення: <command>sssd_${назва_служби}</command>"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><title>

  #. type: Content of: <reference><refentry><refsect1><refsect2><title>

- #: sssd.conf.5.xml:266

+ #: sssd.conf.5.xml:286

  msgid "NSS configuration options"

  msgstr "Параметри налаштування NSS"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

- #: sssd.conf.5.xml:268

+ #: sssd.conf.5.xml:288

  msgid ""

  "These options can be used to configure the Name Service Switch (NSS) service."

  msgstr ""
@@ -626,13 +655,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:273

+ #: sssd.conf.5.xml:293

  msgid "enum_cache_timeout (integer)"

  msgstr "enum_cache_timeout (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:276

+ #: sssd.conf.5.xml:296

  msgid ""

  "How many seconds should nss_sss cache enumerations (requests for info about "

  "all users)"
@@ -642,19 +671,19 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:280

+ #: sssd.conf.5.xml:300

  msgid "Default: 120"

  msgstr "Типове значення: 120"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:285

+ #: sssd.conf.5.xml:305

  msgid "entry_cache_nowait_percentage (integer)"

  msgstr "entry_cache_nowait_percentage (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:288

+ #: sssd.conf.5.xml:308

  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 "
@@ -663,7 +692,7 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:294

+ #: sssd.conf.5.xml:314

  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 "
@@ -674,7 +703,7 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:304

+ #: sssd.conf.5.xml:324

  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 "
@@ -684,13 +713,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:317

+ #: sssd.conf.5.xml:337

  msgid "entry_negative_timeout (integer)"

  msgstr "entry_negative_timeout (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:320

+ #: sssd.conf.5.xml:340

  msgid ""

  "Specifies for how many seconds nss_sss should cache negative cache hits "

  "(that is, queries for invalid database entries, like nonexistent ones)  "
@@ -699,18 +728,18 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:326 sssd-krb5.5.xml:223

+ #: sssd.conf.5.xml:346 sssd-krb5.5.xml:223

  msgid "Default: 15"

  msgstr "Типове значення: 15"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:331

+ #: sssd.conf.5.xml:351

  msgid "filter_users, filter_groups (string)"

  msgstr "filter_users, filter_groups (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:334

+ #: sssd.conf.5.xml:354

  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-"
@@ -720,34 +749,204 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:341

+ #: sssd.conf.5.xml:361

  msgid "Default: root"

  msgstr "Типове значення: root"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:346

+ #: sssd.conf.5.xml:366

  msgid "filter_users_in_groups (bool)"

  msgstr "filter_users_in_groups (булеве значення)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:349

+ #: sssd.conf.5.xml:369

  msgid ""

  "If you want filtered user still be group members set this option to false."

  msgstr ""

  "Якщо ви хочете, щоб фільтровані користувачі залишалися учасниками груп, "

  "встановіть для цього параметра значення «false»."

  

+ # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:378

+ #, fuzzy

+ #| msgid "userdel_cmd (string)"

+ msgid "override_homedir (string)"

+ msgstr "userdel_cmd (рядок)"

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:387 sssd-krb5.5.xml:166

+ msgid "%u"

+ msgstr "%u"

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:388 sssd-krb5.5.xml:167

+ msgid "login name"

+ msgstr "ім'я користувача"

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:391 sssd-krb5.5.xml:170

+ msgid "%U"

+ msgstr "%U"

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:392

+ msgid "UID number"

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:395 sssd-krb5.5.xml:188

+ msgid "%d"

+ msgstr "%d"

+ 

+ # type: Content of: <refsect1><refsect2><title>

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:396

+ #, fuzzy

+ #| msgid "The domain name"

+ msgid "domain name"

+ msgstr "Назва домену"

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:399

+ msgid "%f"

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:400

+ #, fuzzy

+ #| msgid "use_fully_qualified_names (bool)"

+ msgid "fully qualified user name (user@domain)"

+ msgstr "use_fully_qualified_names (булеве значення)"

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:403 sssd-krb5.5.xml:200

+ msgid "%%"

+ msgstr "%%"

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:404 sssd-krb5.5.xml:201

+ msgid "a literal '%'"

+ msgstr "символ відсотків («%»)"

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:381

+ 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: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:410

+ msgid "This option can also be set per-domain."

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:415

+ #, fuzzy

+ #| msgid "default_shell (string)"

+ msgid "allowed_shells (string)"

+ msgstr "default_shell (рядок)"

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:418

+ 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:421

+ 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:425

+ 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:430

+ 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:435

+ 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:438

+ 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:442

+ #, fuzzy

+ #| msgid "Default: not set, i.e. FAST is not used."

+ msgid "Default: Not set. The user shell is automatically used."

+ msgstr "Типове значення: не встановлено, тобто FAST не використовується."

+ 

+ # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:447

+ #, fuzzy

+ #| msgid "default_shell (string)"

+ msgid "vetoed_shells (string)"

+ msgstr "default_shell (рядок)"

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:450

+ msgid "Replace any instance of these shells with the shell_fallback"

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:455

+ #, fuzzy

+ #| msgid "userdel_cmd (string)"

+ msgid "shell_fallback (string)"

+ msgstr "userdel_cmd (рядок)"

+ 

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:458

+ msgid ""

+ "The default shell to use if an allowed shell is not installed on the machine."

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:462

+ #, fuzzy

+ #| msgid "Default: cn"

+ msgid "Default: /bin/sh"

+ msgstr "Типове значення: cn"

+ 

  # type: Content of: <reference><refentry><refsect1><refsect2><title>

  #. type: Content of: <reference><refentry><refsect1><refsect2><title>

- #: sssd.conf.5.xml:360

+ #: sssd.conf.5.xml:469

  msgid "PAM configuration options"

  msgstr "Параметри налаштування PAM"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

- #: sssd.conf.5.xml:362

+ #: sssd.conf.5.xml:471

  msgid ""

  "These options can be used to configure the Pluggable Authentication Module "

  "(PAM) service."
@@ -757,13 +956,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:367

+ #: sssd.conf.5.xml:476

  msgid "offline_credentials_expiration (integer)"

  msgstr "offline_credentials_expiration (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:370

+ #: sssd.conf.5.xml:479

  msgid ""

  "If the authentication provider is offline, how long should we allow cached "

  "logins (in days since the last successful online login)."
@@ -771,19 +970,19 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:375 sssd.conf.5.xml:388

+ #: sssd.conf.5.xml:484 sssd.conf.5.xml:497

  msgid "Default: 0 (No limit)"

  msgstr "Типове значення: 0 (без обмежень)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:381

+ #: sssd.conf.5.xml:490

  msgid "offline_failed_login_attempts (integer)"

  msgstr "offline_failed_login_attempts (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:384

+ #: sssd.conf.5.xml:493

  msgid ""

  "If the authentication provider is offline, how many failed login attempts "

  "are allowed."
@@ -791,13 +990,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:394

+ #: sssd.conf.5.xml:503

  msgid "offline_failed_login_delay (integer)"

  msgstr "offline_failed_login_delay (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:397

+ #: sssd.conf.5.xml:506

  msgid ""

  "The time in minutes which has to pass after offline_failed_login_attempts "

  "has been reached before a new login attempt is possible."
@@ -805,7 +1004,7 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:402

+ #: sssd.conf.5.xml:511

  msgid ""

  "If set to 0 the user cannot authenticate offline if "

  "offline_failed_login_attempts has been reached. Only a successful online "
@@ -814,19 +1013,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:408 sssd.conf.5.xml:461 sssd.conf.5.xml:793

+ #: sssd.conf.5.xml:517 sssd.conf.5.xml:570 sssd.conf.5.xml:906

  msgid "Default: 5"

  msgstr "Типове значення: 5"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:414

+ #: sssd.conf.5.xml:523

  msgid "pam_verbosity (integer)"

  msgstr "pam_verbosity (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:417

+ #: sssd.conf.5.xml:526

  msgid ""

  "Controls what kind of messages are shown to the user during authentication. "

  "The higher the number to more messages are displayed."
@@ -834,49 +1033,49 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:422

+ #: sssd.conf.5.xml:531

  msgid "Currently sssd supports the following values:"

  msgstr "У поточній версії sssd передбачено підтримку таких значень:"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:425

+ #: sssd.conf.5.xml:534

  msgid "<emphasis>0</emphasis>: do not show any message"

  msgstr "<emphasis>0</emphasis>: не показувати жодних повідомлень"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:428

+ #: sssd.conf.5.xml:537

  msgid "<emphasis>1</emphasis>: show only important messages"

  msgstr "<emphasis>1</emphasis>: показувати лише важливі повідомлення"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:432

+ #: sssd.conf.5.xml:541

  msgid "<emphasis>2</emphasis>: show informational messages"

  msgstr "<emphasis>2</emphasis>: показувати всі інформаційні повідомлення"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:435

+ #: sssd.conf.5.xml:544

  msgid "<emphasis>3</emphasis>: show all messages and debug information"

  msgstr ""

  "<emphasis>3</emphasis>: показувати всі повідомлення та діагностичні дані"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:439

+ #: sssd.conf.5.xml:548

  msgid "Default: 1"

  msgstr "Типове значення: 1"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:444

+ #: sssd.conf.5.xml:553

  msgid "pam_id_timeout (integer)"

  msgstr "pam_id_timeout (ціле число)"

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:447

+ #: sssd.conf.5.xml:556

  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 "
@@ -884,7 +1083,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:453

+ #: sssd.conf.5.xml:562

  msgid ""

  "A complete PAM conversation may perform multiple PAM requests, such as "

  "account management and session opening. This option controls (on a per-"
@@ -894,17 +1093,17 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:467

+ #: sssd.conf.5.xml:576

  msgid "pam_pwd_expiration_warning (integer)"

  msgstr "pam_pwd_expiration_warning (ціле число)"

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:470

+ #: sssd.conf.5.xml:579

  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:473

+ #: sssd.conf.5.xml:582

  msgid ""

  "Please note that the backend server has to provide information about the "

  "expiration time of the password.  If this information is missing, sssd "
@@ -913,25 +1112,25 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:479

+ #: sssd.conf.5.xml:588

  msgid "Default: 7"

  msgstr "Типове значення: 7"

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd.conf.5.xml:488

+ #: sssd.conf.5.xml:597

  msgid "DOMAIN SECTIONS"

  msgstr "РОЗДІЛИ ДОМЕНІВ"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:495

+ #: sssd.conf.5.xml:604

  msgid "min_id,max_id (integer)"

  msgstr "min_id,max_id (ціле значення)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:498

+ #: sssd.conf.5.xml:607

  msgid ""

  "UID and GID limits for the domain. If a domain contains an entry that is "

  "outside these limits, it is ignored."
@@ -939,7 +1138,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:503

+ #: sssd.conf.5.xml:612

  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-"
@@ -949,19 +1148,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:510

+ #: sssd.conf.5.xml:619

  msgid "Default: 1 for min_id, 0 (no limit) for max_id"

  msgstr "Типові значення: 1 для min_id, 0 (без обмежень) для max_id"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:516

+ #: sssd.conf.5.xml:625

  msgid "timeout (integer)"

  msgstr "timeout (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:519

+ #: sssd.conf.5.xml:628

  msgid ""

  "Timeout in seconds between heartbeats for this domain.  This is used to "

  "ensure that the backend process is alive and capable of answering requests."
@@ -969,19 +1168,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:524

+ #: sssd.conf.5.xml:633

  msgid "Default: 10"

  msgstr "Типове значення: 10"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:530

+ #: sssd.conf.5.xml:639

  msgid "enumerate (bool)"

  msgstr "enumerate (булеве значення)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:533

+ #: sssd.conf.5.xml:642

  msgid ""

  "Determines if a domain can be enumerated. This parameter can have one of the "

  "following values:"
@@ -989,25 +1188,25 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:537

+ #: sssd.conf.5.xml:646

  msgid "TRUE = Users and groups are enumerated"

  msgstr "TRUE = користувачі і групи нумеруються"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:540

+ #: sssd.conf.5.xml:649

  msgid "FALSE = No enumerations for this domain"

  msgstr "FALSE = не використовувати нумерацію для цього домену"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:543 sssd.conf.5.xml:591 sssd.conf.5.xml:645

+ #: sssd.conf.5.xml:652 sssd.conf.5.xml:704 sssd.conf.5.xml:758

  msgid "Default: FALSE"

  msgstr "Типове значення: FALSE"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:546

+ #: sssd.conf.5.xml:655

  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 "
@@ -1017,7 +1216,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:556

+ #: sssd.conf.5.xml:665

  msgid ""

  "While the first enumeration is running, requests for the complete user or "

  "group lists may return no results until it completes."
@@ -1025,7 +1224,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:561

+ #: sssd.conf.5.xml:670

  msgid ""

  "Further, enabling enumeration may increase the time necessary to detect "

  "network disconnection, as longer timeouts are required to ensure that "
@@ -1035,13 +1234,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:572

+ #: sssd.conf.5.xml:681

  msgid "entry_cache_timeout (integer)"

  msgstr "entry_cache_timeout (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:575

+ #: sssd.conf.5.xml:684

  msgid ""

  "How many seconds should nss_sss consider entries valid before asking the "

  "backend again"
@@ -1049,31 +1248,36 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:579

+ #: sssd.conf.5.xml:688

  msgid "Default: 5400"

  msgstr "Типове значення: 5400"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:584

+ #: sssd.conf.5.xml:693

  msgid "cache_credentials (bool)"

  msgstr "cache_credentials (булеве значення)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:587

+ #: sssd.conf.5.xml:696

  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:700

+ msgid "User credentials are stored in a SHA512 hash, not in plaintext"

+ msgstr ""

+ 

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:596

+ #: sssd.conf.5.xml:709

  msgid "account_cache_expiration (integer)"

  msgstr "account_cache_expiration (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:599

+ #: sssd.conf.5.xml:712

  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 "
@@ -1083,55 +1287,55 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:606

+ #: sssd.conf.5.xml:719

  msgid "Default: 0 (unlimited)"

  msgstr "Типове значення: 0 (без обмежень)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:612

+ #: sssd.conf.5.xml:725

  msgid "id_provider (string)"

  msgstr "id_provider (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:615

+ #: sssd.conf.5.xml:728

  msgid "The Data Provider identity backend to use for this domain."

  msgstr "Модуль надання даних щодо профілів користувачів для цього домену."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:619

+ #: sssd.conf.5.xml:732

  msgid "Supported backends:"

  msgstr "Підтримувані модулі:"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:622

+ #: sssd.conf.5.xml:735

  msgid "proxy: Support a legacy NSS provider"

  msgstr "proxy: підтримка застарілого модуля надання даних NSS"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:625

+ #: sssd.conf.5.xml:738

  msgid "local: SSSD internal local provider"

  msgstr "local: вбудований модуль надання локальних даних SSSD"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:628

+ #: sssd.conf.5.xml:741

  msgid "ldap: LDAP provider"

  msgstr "ldap: модуль надання даних LDAP"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:634

+ #: sssd.conf.5.xml:747

  msgid "use_fully_qualified_names (bool)"

  msgstr "use_fully_qualified_names (булеве значення)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:637

+ #: sssd.conf.5.xml:750

  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, "
@@ -1141,13 +1345,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:650

+ #: sssd.conf.5.xml:763

  msgid "auth_provider (string)"

  msgstr "auth_provider (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:653

+ #: sssd.conf.5.xml:766

  msgid ""

  "The authentication provider used for the domain.  Supported auth providers "

  "are:"
@@ -1157,7 +1361,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:657

+ #: sssd.conf.5.xml:770

  msgid ""

  "<quote>ldap</quote> for native LDAP authentication. See <citerefentry> "

  "<refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</manvolnum> </"
@@ -1170,7 +1374,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:664

+ #: sssd.conf.5.xml:777

  msgid ""

  "<quote>krb5</quote> for Kerberos authentication. See <citerefentry> "

  "<refentrytitle>sssd-krb5</refentrytitle> <manvolnum>5</manvolnum> </"
@@ -1183,20 +1387,20 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:671

+ #: sssd.conf.5.xml:784

  msgid ""

  "<quote>proxy</quote> for relaying authentication to some other PAM target."

  msgstr "<quote>proxy</quote> — трансльоване розпізнавання у іншій системі PAM."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:674

+ #: sssd.conf.5.xml:787

  msgid "<quote>none</quote> disables authentication explicitly."

  msgstr "<quote>none</quote> — вимкнути розпізнавання повністю."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:677

+ #: sssd.conf.5.xml:790

  msgid ""

  "Default: <quote>id_provider</quote> is used if it is set and can handle "

  "authentication requests."
@@ -1206,13 +1410,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:683

+ #: sssd.conf.5.xml:796

  msgid "access_provider (string)"

  msgstr "access_provider (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:686

+ #: sssd.conf.5.xml:799

  msgid ""

  "The access control provider used for the domain.  There are two built-in "

  "access providers (in addition to any included in installed backends)  "
@@ -1221,19 +1425,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:692

+ #: sssd.conf.5.xml:805

  msgid "<quote>permit</quote> always allow access."

  msgstr "<quote>permit</quote> — завжди дозволяти доступ."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:695

+ #: sssd.conf.5.xml:808

  msgid "<quote>deny</quote> always deny access."

  msgstr "<quote>deny</quote> — завжди забороняти доступ."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:698

+ #: sssd.conf.5.xml:811

  msgid ""

  "<quote>simple</quote> access control based on access or deny lists. See "

  "<citerefentry> <refentrytitle>sssd-simple</refentrytitle> <manvolnum>5</"
@@ -1243,19 +1447,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:705

+ #: sssd.conf.5.xml:818

  msgid "Default: <quote>permit</quote>"

  msgstr "Типове значення: <quote>permit</quote>"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:710

+ #: sssd.conf.5.xml:823

  msgid "chpass_provider (string)"

  msgstr "chpass_provider (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:713

+ #: sssd.conf.5.xml:826

  msgid ""

  "The provider which should handle change password operations for the domain.  "

  "Supported change password providers are:"
@@ -1263,7 +1467,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:718

+ #: sssd.conf.5.xml:831

  msgid ""

  "<quote>ipa</quote> to change a password stored in an IPA server.  See "

  "<citerefentry> <refentrytitle>sssd-ipa</refentrytitle> <manvolnum>5</"
@@ -1276,7 +1480,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:726

+ #: sssd.conf.5.xml:839

  msgid ""

  "<quote>ldap</quote> to change a password stored in a LDAP server.  See "

  "<citerefentry> <refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</"
@@ -1289,7 +1493,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:734

+ #: sssd.conf.5.xml:847

  msgid ""

  "<quote>krb5</quote> to change the Kerberos password. See <citerefentry> "

  "<refentrytitle>sssd-krb5</refentrytitle> <manvolnum>5</manvolnum> </"
@@ -1302,20 +1506,20 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:742

+ #: sssd.conf.5.xml:855

  msgid ""

  "<quote>proxy</quote> for relaying password changes to some other PAM target."

  msgstr "<quote>proxy</quote> — трансльована зміна пароля у іншій системі PAM."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:746

+ #: sssd.conf.5.xml:859

  msgid "<quote>none</quote> disallows password changes explicitly."

  msgstr "<quote>none</quote> — явно вимкнути можливість зміни пароля."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:749

+ #: sssd.conf.5.xml:862

  msgid ""

  "Default: <quote>auth_provider</quote> is used if it is set and can handle "

  "change password requests."
@@ -1323,13 +1527,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:756

+ #: sssd.conf.5.xml:869

  msgid "lookup_family_order (string)"

  msgstr "lookup_family_order (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:759

+ #: sssd.conf.5.xml:872

  msgid ""

  "Provides the ability to select preferred address family to use when "

  "performing DNS lookups."
@@ -1339,13 +1543,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:763

+ #: sssd.conf.5.xml:876

  msgid "Supported values:"

  msgstr "Передбачено підтримку таких значень:"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:766

+ #: sssd.conf.5.xml:879

  msgid "ipv4_first: Try looking up IPv4 address, if that fails, try IPv6"

  msgstr ""

  "ipv4_first: спробувати визначити адресу у форматі IPv4, у разі невдачі "
@@ -1353,14 +1557,14 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:769

+ #: sssd.conf.5.xml:882

  msgid "ipv4_only: Only attempt to resolve hostnames to IPv4 addresses."

  msgstr ""

  "ipv4_only: намагатися визначити назви вузлів лише у форматі адрес IPv4."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:772

+ #: sssd.conf.5.xml:885

  msgid "ipv6_first: Try looking up IPv6 address, if that fails, try IPv4"

  msgstr ""

  "ipv6_first: спробувати визначити адресу у форматі IPv6, у разі невдачі "
@@ -1368,26 +1572,26 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:775

+ #: sssd.conf.5.xml:888

  msgid "ipv6_only: Only attempt to resolve hostnames to IPv6 addresses."

  msgstr ""

  "ipv6_only: намагатися визначити назви вузлів лише у форматі адрес IPv6."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:778

+ #: sssd.conf.5.xml:891

  msgid "Default: ipv4_first"

  msgstr "Типове значення: ipv4_first"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:784

+ #: sssd.conf.5.xml:897

  msgid "dns_resolver_timeout (integer)"

  msgstr "dns_resolver_timeout (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:787

+ #: sssd.conf.5.xml:900

  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, "
@@ -1396,13 +1600,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:799

+ #: sssd.conf.5.xml:912

  msgid "dns_discovery_domain (string)"

  msgstr "dns_discovery_domain (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:802

+ #: sssd.conf.5.xml:915

  msgid ""

  "If service discovery is used in the back end, specifies the domain part of "

  "the service discovery DNS query."
@@ -1410,13 +1614,26 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:806

+ #: sssd.conf.5.xml:919

  msgid "Default: Use the domain part of machine's hostname"

  msgstr ""

  "Типова поведінка: використовувати назву домену з назви вузла комп’ютера."

  

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #: sssd.conf.5.xml:925

+ #, fuzzy

+ #| msgid "min_id,max_id (integer)"

+ msgid "override_gid (integer)"

+ msgstr "min_id,max_id (ціле значення)"

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd.conf.5.xml:928

+ msgid "Override the primary GID value with the one specified."

+ msgstr ""

+ 

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:490

+ #: sssd.conf.5.xml:599

  msgid ""

  "These configuration options can be present in a domain configuration "

  "section, that is, in a section called <quote>[domain/<replaceable>NAME</"
@@ -1425,19 +1642,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:818

+ #: sssd.conf.5.xml:940

  msgid "proxy_pam_target (string)"

  msgstr "proxy_pam_target (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:821

+ #: sssd.conf.5.xml:943

  msgid "The proxy target PAM proxies to."

  msgstr "Комп’ютер, для якого виконує проксі-сервер PAM."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:824

+ #: sssd.conf.5.xml:946

  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."
@@ -1445,13 +1662,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:832

+ #: sssd.conf.5.xml:954

  msgid "proxy_lib_name (string)"

  msgstr "proxy_lib_name (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:835

+ #: sssd.conf.5.xml:957

  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), "
@@ -1459,7 +1676,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:814

+ #: sssd.conf.5.xml:936

  msgid ""

  "Options valid for proxy domains.  <placeholder type=\"variablelist\" id="

  "\"0\"/>"
@@ -1469,13 +1686,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><title>

  #. type: Content of: <reference><refentry><refsect1><refsect2><title>

- #: sssd.conf.5.xml:847

+ #: sssd.conf.5.xml:969

  msgid "The local domain section"

  msgstr "Розділ локального домену"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><para>

- #: sssd.conf.5.xml:849

+ #: sssd.conf.5.xml:971

  msgid ""

  "This section contains settings for domain that stores users and groups in "

  "SSSD native database, that is, a domain that uses "
@@ -1484,13 +1701,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:856

+ #: sssd.conf.5.xml:978

  msgid "default_shell (string)"

  msgstr "default_shell (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:859

+ #: sssd.conf.5.xml:981

  msgid "The default shell for users created with SSSD userspace tools."

  msgstr ""

  "Типова оболонка для записів користувачів, створених за допомогою "
@@ -1498,19 +1715,19 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:863

+ #: sssd.conf.5.xml:985

  msgid "Default: <filename>/bin/bash</filename>"

  msgstr "Типове значення: <filename>/bin/bash</filename>"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:868

+ #: sssd.conf.5.xml:990

  msgid "base_directory (string)"

  msgstr "base_directory (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:871

+ #: sssd.conf.5.xml:993

  msgid ""

  "The tools append the login name to <replaceable>base_directory</replaceable> "

  "and use that as the home directory."
@@ -1518,18 +1735,18 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:876

+ #: sssd.conf.5.xml:998

  msgid "Default: <filename>/home</filename>"

  msgstr "Типове значення: <filename>/home</filename>"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:881

+ #: sssd.conf.5.xml:1003

  msgid "create_homedir (bool)"

  msgstr "create_homedir (булеве значення)"

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:884

+ #: sssd.conf.5.xml:1006

  msgid ""

  "Indicate if a home directory should be created by default for new users.  "

  "Can be overridden on command line."
@@ -1537,18 +1754,18 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:888 sssd.conf.5.xml:900

+ #: sssd.conf.5.xml:1010 sssd.conf.5.xml:1022

  msgid "Default: TRUE"

  msgstr "Типове значення: TRUE"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:893

+ #: sssd.conf.5.xml:1015

  msgid "remove_homedir (bool)"

  msgstr "remove_homedir (булівське значення)"

  

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:896

+ #: sssd.conf.5.xml:1018

  msgid ""

  "Indicate if a home directory should be removed by default for deleted "

  "users.  Can be overridden on command line."
@@ -1556,13 +1773,13 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:905

+ #: sssd.conf.5.xml:1027

  msgid "homedir_umask (integer)"

  msgstr "homedir_umask (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:908

+ #: sssd.conf.5.xml:1030

  msgid ""

  "Used by <citerefentry> <refentrytitle>sss_useradd</refentrytitle> "

  "<manvolnum>8</manvolnum> </citerefentry> to specify the default permissions "
@@ -1574,19 +1791,19 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:916

+ #: sssd.conf.5.xml:1038

  msgid "Default: 077"

  msgstr "Типове значення: 077"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:921

+ #: sssd.conf.5.xml:1043

  msgid "skel_dir (string)"

  msgstr "skel_dir (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:924

+ #: sssd.conf.5.xml:1046

  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 "
@@ -1596,19 +1813,19 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:934

+ #: sssd.conf.5.xml:1056

  msgid "Default: <filename>/etc/skel</filename>"

  msgstr "Типове значення: <filename>/etc/skel</filename>"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:939

+ #: sssd.conf.5.xml:1061

  msgid "mail_dir (string)"

  msgstr "mail_dir (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:942

+ #: sssd.conf.5.xml:1064

  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 "
@@ -1617,19 +1834,19 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:949

+ #: sssd.conf.5.xml:1071

  msgid "Default: <filename>/var/mail</filename>"

  msgstr "Типове значення: <filename>/var/mail</filename>"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term>

- #: sssd.conf.5.xml:954

+ #: sssd.conf.5.xml:1076

  msgid "userdel_cmd (string)"

  msgstr "userdel_cmd (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:957

+ #: sssd.conf.5.xml:1079

  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 "
@@ -1638,20 +1855,20 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

- #: sssd.conf.5.xml:963

+ #: sssd.conf.5.xml:1085

  msgid "Default: None, no command is run"

  msgstr "Типове значення: None, не виконувати жодних команд"

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd.conf.5.xml:973 sssd-ldap.5.xml:1357 sssd-simple.5.xml:126

- #: sssd-ipa.5.xml:173 sssd-krb5.5.xml:405

+ #: sssd.conf.5.xml:1095 sssd-ldap.5.xml:1400 sssd-simple.5.xml:126

+ #: sssd-ipa.5.xml:230 sssd-krb5.5.xml:408

  msgid "EXAMPLE"

  msgstr "ПРИКЛАД"

  

  # type: Content of: <reference><refentry><refsect1><para><programlisting>

  #. type: Content of: <reference><refentry><refsect1><para><programlisting>

- #: sssd.conf.5.xml:979

+ #: sssd.conf.5.xml:1101

  #, no-wrap

  msgid ""

  "[sssd]\n"
@@ -1705,7 +1922,7 @@

  "enumerate = False\n"

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:975

+ #: sssd.conf.5.xml:1097

  msgid ""

  "The following example shows a typical SSSD config. It does not describe "

  "configuration of the domains themselves - refer to documentation on "
@@ -1715,7 +1932,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd.conf.5.xml:1010

+ #: sssd.conf.5.xml:1132

  msgid ""

  "<citerefentry> <refentrytitle>sssd-ldap</refentrytitle><manvolnum>5</"

  "manvolnum> </citerefentry>, <citerefentry> <refentrytitle>sssd-krb5</"
@@ -1796,53 +2013,73 @@

  msgid "ldap_uri (string)"

  msgstr "ldap_uri (рядок)"

  

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-ldap.5.xml:63

  msgid ""

- "Specifies the 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 not specified, "

- "service discovery is enabled. For more information, refer to the "

- "<quote>SERVICE DISCOVERY</quote> section."

+ "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 "

+ "not 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]://&lt;host&gt;[:port]"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:76

+ msgid ""

+ "For explicit IPv6 addresses, &lt;host&gt; 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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:73

+ #: sssd-ldap.5.xml:85

  msgid "ldap_chpass_uri (string)"

  msgstr "ldap_chpass_uri (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:76

+ #: sssd-ldap.5.xml:88

  msgid ""

- "Specifies the 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."

+ "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:83

+ #: sssd-ldap.5.xml:95

  msgid "To enable service discovery ldap_chpass_dns_service_name must be set."

  msgstr ""

  "Для того, щоб уможливити визначення служб, слід встановити значення "

  "параметра ldap_chpass_dns_service_name."

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:87

+ #: sssd-ldap.5.xml:99

  msgid "Default: empty, i.e. ldap_uri is used."

  msgstr "Типове значення: порожнє, тобто використовується ldap_uri."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:93

+ #: sssd-ldap.5.xml:105

  msgid "ldap_search_base (string)"

  msgstr "ldap_search_base (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:96

+ #: sssd-ldap.5.xml:108

  msgid "The default base DN to use for performing LDAP user operations."

  msgstr ""

  "Типова базова назва домену, яку слід використовувати для виконання дій від "
@@ -1850,7 +2087,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:100

+ #: sssd-ldap.5.xml:112

  msgid ""

  "Default: If not set the value of the defaultNamingContext or namingContexts "

  "attribute from the RootDSE of the LDAP server is used. If "
@@ -1862,13 +2099,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:114

+ #: sssd-ldap.5.xml:126

  msgid "ldap_schema (string)"

  msgstr "ldap_schema (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:117

+ #: sssd-ldap.5.xml:129

  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 "
@@ -1883,19 +2120,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:136

+ #: sssd-ldap.5.xml:148

  msgid "Default: rfc2307"

  msgstr "Типове значення: rfc2307"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:142

+ #: sssd-ldap.5.xml:154

  msgid "ldap_default_bind_dn (string)"

  msgstr "ldap_default_bind_dn (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:145

+ #: sssd-ldap.5.xml:157

  msgid "The default bind DN to use for performing LDAP operations."

  msgstr ""

  "Типова назва домену прив’язки, яку слід використовувати для виконання дій "
@@ -1903,43 +2140,51 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:152

+ #: sssd-ldap.5.xml:164

  msgid "ldap_default_authtok_type (string)"

  msgstr "ldap_default_authtok_type (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:155

+ #: sssd-ldap.5.xml:167

  msgid "The type of the authentication token of the default bind DN."

  msgstr "Тип розпізнавання для типової назви сервера прив’язки."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:159

+ #: sssd-ldap.5.xml:171

  msgid "The two mechanisms currently supported are:"

  msgstr "У поточній версії передбачено підтримку двох механізмів:"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:162

+ #: sssd-ldap.5.xml:174

  msgid "password"

  msgstr "password"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:165

+ #: sssd-ldap.5.xml:177

  msgid "obfuscated_password"

  msgstr "obfuscated_password"

  

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:180

+ #, fuzzy

+ #| msgid "Default: hard"

+ msgid "Default: password"

+ msgstr "Типове значення: hard"

+ 

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:171

+ #: sssd-ldap.5.xml:186

  msgid "ldap_default_authtok (string)"

  msgstr "ldap_default_authtok (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:174

+ #: sssd-ldap.5.xml:189

  msgid ""

  "The authentication token of the default bind DN.  Only clear text passwords "

  "are currently supported."
@@ -1949,157 +2194,157 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:181

+ #: sssd-ldap.5.xml:196

  msgid "ldap_user_object_class (string)"

  msgstr "ldap_user_object_class (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:184

+ #: sssd-ldap.5.xml:199

  msgid "The object class of a user entry in LDAP."

  msgstr "Клас об’єктів запису користувача у LDAP."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:187

+ #: sssd-ldap.5.xml:202

  msgid "Default: posixAccount"

  msgstr "Типове значення: posixAccount"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:193

+ #: sssd-ldap.5.xml:208

  msgid "ldap_user_name (string)"

  msgstr "ldap_user_name (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:196

+ #: sssd-ldap.5.xml:211

  msgid "The LDAP attribute that corresponds to the user's login name."

  msgstr "Атрибут LDAP, що відповідає назві облікового запису користувача."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:200

+ #: sssd-ldap.5.xml:215

  msgid "Default: uid"

  msgstr "Типове значення: uid"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:206

+ #: sssd-ldap.5.xml:221

  msgid "ldap_user_uid_number (string)"

  msgstr "ldap_user_uid_number (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:209

+ #: sssd-ldap.5.xml:224

  msgid "The LDAP attribute that corresponds to the user's id."

  msgstr "Атрибут LDAP, що відповідає ідентифікатору користувача."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:213

+ #: sssd-ldap.5.xml:228

  msgid "Default: uidNumber"

  msgstr "Типове значення: uidNumber"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:219

+ #: sssd-ldap.5.xml:234

  msgid "ldap_user_gid_number (string)"

  msgstr "ldap_user_gid_number (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:222

+ #: sssd-ldap.5.xml:237

  msgid "The LDAP attribute that corresponds to the user's primary group id."

  msgstr "Атрибут LDAP, що відповідає ідентифікатору основної групи користувача."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:226 sssd-ldap.5.xml:622

+ #: sssd-ldap.5.xml:241 sssd-ldap.5.xml:637

  msgid "Default: gidNumber"

  msgstr "Типове значення: gidNumber"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:232

+ #: sssd-ldap.5.xml:247

  msgid "ldap_user_gecos (string)"

  msgstr "ldap_user_gecos (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:235

+ #: sssd-ldap.5.xml:250

  msgid "The LDAP attribute that corresponds to the user's gecos field."

  msgstr "Атрибут LDAP, що відповідає полю gecos користувача."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:239

+ #: sssd-ldap.5.xml:254

  msgid "Default: gecos"

  msgstr "Типове значення: gecos"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:245

+ #: sssd-ldap.5.xml:260

  msgid "ldap_user_home_directory (string)"

  msgstr "ldap_user_home_directory (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:248

+ #: sssd-ldap.5.xml:263

  msgid "The LDAP attribute that contains the name of the user's home directory."

  msgstr "Атрибут LDAP, що містить назву домашнього каталогу користувача."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:252

+ #: sssd-ldap.5.xml:267

  msgid "Default: homeDirectory"

  msgstr "Типове значення: homeDirectory"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:258

+ #: sssd-ldap.5.xml:273

  msgid "ldap_user_shell (string)"

  msgstr "ldap_user_shell (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:261

+ #: sssd-ldap.5.xml:276

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:265

+ #: sssd-ldap.5.xml:280

  msgid "Default: loginShell"

  msgstr "Типове значення: loginShell"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:271

+ #: sssd-ldap.5.xml:286

  msgid "ldap_user_uuid (string)"

  msgstr "ldap_user_uuid (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:274

+ #: sssd-ldap.5.xml:289

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:278 sssd-ldap.5.xml:648 sssd-ldap.5.xml:741

+ #: sssd-ldap.5.xml:293 sssd-ldap.5.xml:663 sssd-ldap.5.xml:756

  msgid "Default: nsUniqueId"

  msgstr "Типове значення: nsUniqueId"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:284

+ #: sssd-ldap.5.xml:299

  msgid "ldap_user_modify_timestamp (string)"

  msgstr "ldap_user_modify_timestamp (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:287 sssd-ldap.5.xml:657 sssd-ldap.5.xml:750

+ #: sssd-ldap.5.xml:302 sssd-ldap.5.xml:672 sssd-ldap.5.xml:765

  msgid ""

  "The LDAP attribute that contains timestamp of the last modification of the "

  "parent object."
@@ -2107,19 +2352,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:291 sssd-ldap.5.xml:661 sssd-ldap.5.xml:754

+ #: sssd-ldap.5.xml:306 sssd-ldap.5.xml:676 sssd-ldap.5.xml:769

  msgid "Default: modifyTimestamp"

  msgstr "Типове значення: modifyTimestamp"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:297

+ #: sssd-ldap.5.xml:312

  msgid "ldap_user_shadow_last_change (string)"

  msgstr "ldap_user_shadow_last_change (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:300

+ #: sssd-ldap.5.xml:315

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> <refentrytitle>shadow</"
@@ -2129,19 +2374,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:310

+ #: sssd-ldap.5.xml:325

  msgid "Default: shadowLastChange"

  msgstr "Типове значення: shadowLastChange"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:316

+ #: sssd-ldap.5.xml:331

  msgid "ldap_user_shadow_min (string)"

  msgstr "ldap_user_shadow_min (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:319

+ #: sssd-ldap.5.xml:334

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> <refentrytitle>shadow</"
@@ -2151,19 +2396,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:328

+ #: sssd-ldap.5.xml:343

  msgid "Default: shadowMin"

  msgstr "Типове значення: shadowMin"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:334

+ #: sssd-ldap.5.xml:349

  msgid "ldap_user_shadow_max (string)"

  msgstr "ldap_user_shadow_max (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:337

+ #: sssd-ldap.5.xml:352

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> <refentrytitle>shadow</"
@@ -2173,19 +2418,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:346

+ #: sssd-ldap.5.xml:361

  msgid "Default: shadowMax"

  msgstr "Типове значення: shadowMax"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:352

+ #: sssd-ldap.5.xml:367

  msgid "ldap_user_shadow_warning (string)"

  msgstr "ldap_user_shadow_warning (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:355

+ #: sssd-ldap.5.xml:370

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> <refentrytitle>shadow</"
@@ -2195,19 +2440,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:365

+ #: sssd-ldap.5.xml:380

  msgid "Default: shadowWarning"

  msgstr "Типове значення: shadowWarning"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:371

+ #: sssd-ldap.5.xml:386

  msgid "ldap_user_shadow_inactive (string)"

  msgstr "ldap_user_shadow_inactive (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:374

+ #: sssd-ldap.5.xml:389

  msgid ""

  "When using ldap_pwd_policy=shadow, this parameter contains the name of an "

  "LDAP attribute corresponding to its <citerefentry> <refentrytitle>shadow</"
@@ -2217,18 +2462,18 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:384

+ #: sssd-ldap.5.xml:399

  msgid "Default: shadowInactive"

  msgstr "Типове значення: shadowInactive"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:390

+ #: sssd-ldap.5.xml:405

  msgid "ldap_user_shadow_expire (string)"

  msgstr "ldap_user_shadow_expire (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:393

+ #: sssd-ldap.5.xml:408

  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 "
@@ -2238,19 +2483,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:403

+ #: sssd-ldap.5.xml:418

  msgid "Default: shadowExpire"

  msgstr "Типове значення: shadowExpire"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:409

+ #: sssd-ldap.5.xml:424

  msgid "ldap_user_krb_last_pwd_change (string)"

  msgstr "ldap_user_krb_last_pwd_change (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:412

+ #: sssd-ldap.5.xml:427

  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 "
@@ -2259,19 +2504,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:418

+ #: sssd-ldap.5.xml:433

  msgid "Default: krbLastPwdChange"

  msgstr "Типове значення: krbLastPwdChange"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:424

+ #: sssd-ldap.5.xml:439

  msgid "ldap_user_krb_password_expiration (string)"

  msgstr "ldap_user_krb_password_expiration (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:427

+ #: sssd-ldap.5.xml:442

  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."
@@ -2279,18 +2524,18 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:433

+ #: sssd-ldap.5.xml:448

  msgid "Default: krbPasswordExpiration"

  msgstr "Типове значення: krbPasswordExpiration"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:439

+ #: sssd-ldap.5.xml:454

  msgid "ldap_user_ad_account_expires (string)"

  msgstr "ldap_user_ad_account_expires (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:442

+ #: sssd-ldap.5.xml:457

  msgid ""

  "When using ldap_account_expire_policy=ad, this parameter contains the name "

  "of an LDAP attribute storing the expiration time of the account."
@@ -2298,18 +2543,18 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:447

+ #: sssd-ldap.5.xml:462

  msgid "Default: accountExpires"

  msgstr "Типове значення: accountExpires"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:453

+ #: sssd-ldap.5.xml:468

  msgid "ldap_user_ad_user_account_control (string)"

  msgstr "ldap_user_ad_user_account_control (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:456

+ #: sssd-ldap.5.xml:471

  msgid ""

  "When using ldap_account_expire_policy=ad, this parameter contains the name "

  "of an LDAP attribute storing the user account control bit field."
@@ -2317,18 +2562,18 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:461

+ #: sssd-ldap.5.xml:476

  msgid "Default: userAccountControl"

  msgstr "Типове значення: userAccountControl"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:467

+ #: sssd-ldap.5.xml:482

  msgid "ldap_ns_account_lock (string)"

  msgstr "ldap_ns_account_lock (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:470

+ #: sssd-ldap.5.xml:485

  msgid ""

  "When using ldap_account_expire_policy=rhds or equivalent, this parameter "

  "determines if access is allowed or not."
@@ -2336,19 +2581,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:475

+ #: sssd-ldap.5.xml:490

  msgid "Default: nsAccountLock"

  msgstr "Типове значення: nsAccountLock"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:481

+ #: sssd-ldap.5.xml:496

  msgid "ldap_user_principal (string)"

  msgstr "ldap_user_principal (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:484

+ #: sssd-ldap.5.xml:499

  msgid ""

  "The LDAP attribute that contains the user's Kerberos User Principal Name "

  "(UPN)."
@@ -2356,19 +2601,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:488

+ #: sssd-ldap.5.xml:503

  msgid "Default: krbPrincipalName"

  msgstr "Типове значення: krbPrincipalName"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:494

+ #: sssd-ldap.5.xml:509

  msgid "ldap_force_upper_case_realm (boolean)"

  msgstr "ldap_force_upper_case_realm (булеве значення)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:497

+ #: sssd-ldap.5.xml:512

  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 "
@@ -2378,20 +2623,20 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:504 sssd-ldap.5.xml:961 sssd-ipa.5.xml:115 sssd.8.xml:64

- #: sssd-krb5.5.xml:235 sssd-krb5.5.xml:266

+ #: sssd-ldap.5.xml:519 sssd-ldap.5.xml:990 sssd-ipa.5.xml:115 sssd.8.xml:64

+ #: sssd-krb5.5.xml:235 sssd-krb5.5.xml:269

  msgid "Default: false"

  msgstr "Типове значення: false"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:510

+ #: sssd-ldap.5.xml:525

  msgid "ldap_enumeration_refresh_timeout (integer)"

  msgstr "ldap_enumeration_refresh_timeout (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:513

+ #: sssd-ldap.5.xml:528

  msgid ""

  "The LDAP attribute that contains how many seconds SSSD has to wait before "

  "refreshing its cache of enumerated records."
@@ -2399,19 +2644,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:518

+ #: sssd-ldap.5.xml:533

  msgid "Default: 300"

  msgstr "Типове значення: 300"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:524

+ #: sssd-ldap.5.xml:539

  msgid "ldap_purge_cache_timeout"

  msgstr "ldap_purge_cache_timeout"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:527

+ #: sssd-ldap.5.xml:542

  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 "
@@ -2420,60 +2665,60 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:533

+ #: sssd-ldap.5.xml:548

  msgid "Setting this option to zero will disable the cache cleanup operation."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:537

+ #: sssd-ldap.5.xml:552

  msgid "Default: 10800 (12 hours)"

  msgstr "Типове значення: 10800 (12 годин)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:543

+ #: sssd-ldap.5.xml:558

  msgid "ldap_user_fullname (string)"

  msgstr "ldap_user_fullname (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:546

+ #: sssd-ldap.5.xml:561

  msgid "The LDAP attribute that corresponds to the user's full name."

  msgstr "Атрибут LDAP, що відповідає повному імені користувача."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:550 sssd-ldap.5.xml:609 sssd-ldap.5.xml:702

+ #: sssd-ldap.5.xml:565 sssd-ldap.5.xml:624 sssd-ldap.5.xml:717

  msgid "Default: cn"

  msgstr "Типове значення: cn"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:556

+ #: sssd-ldap.5.xml:571

  msgid "ldap_user_member_of (string)"

  msgstr "ldap_user_member_of (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:559

+ #: sssd-ldap.5.xml:574

  msgid "The LDAP attribute that lists the user's group memberships."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:563

+ #: sssd-ldap.5.xml:578

  msgid "Default: memberOf"

  msgstr "Типове значення: memberOf"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:569

+ #: sssd-ldap.5.xml:584

  msgid "ldap_user_authorized_service (string)"

  msgstr "ldap_user_authorized_service (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:572

+ #: sssd-ldap.5.xml:587

  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 "
@@ -2481,104 +2726,104 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:579

+ #: sssd-ldap.5.xml:594

  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:584

+ #: sssd-ldap.5.xml:599

  msgid "Default: authorizedService"

  msgstr "Типове значення: authorizedService"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:590

+ #: sssd-ldap.5.xml:605

  msgid "ldap_group_object_class (string)"

  msgstr "ldap_group_object_class (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:593

+ #: sssd-ldap.5.xml:608

  msgid "The object class of a group entry in LDAP."

  msgstr "Клас об’єктів запису групи у LDAP."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:596

+ #: sssd-ldap.5.xml:611

  msgid "Default: posixGroup"

  msgstr "Типове значення: posixGroup"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:602

+ #: sssd-ldap.5.xml:617

  msgid "ldap_group_name (string)"

  msgstr "ldap_group_name (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:605

+ #: sssd-ldap.5.xml:620

  msgid "The LDAP attribute that corresponds to the group name."

  msgstr "Атрибут LDAP, що відповідає назві групи."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:615

+ #: sssd-ldap.5.xml:630

  msgid "ldap_group_gid_number (string)"

  msgstr "ldap_group_gid_number (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:618

+ #: sssd-ldap.5.xml:633

  msgid "The LDAP attribute that corresponds to the group's id."

  msgstr "Атрибут LDAP, що відповідає ідентифікатору групи."

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:628

+ #: sssd-ldap.5.xml:643

  msgid "ldap_group_member (string)"

  msgstr "ldap_group_member (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:631

+ #: sssd-ldap.5.xml:646

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:635

+ #: sssd-ldap.5.xml:650

  msgid "Default: memberuid (rfc2307) / member (rfc2307bis)"

  msgstr "Типове значення: memberuid (rfc2307) / member (rfc2307bis)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:641

+ #: sssd-ldap.5.xml:656

  msgid "ldap_group_uuid (string)"

  msgstr "ldap_group_uuid (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:644

+ #: sssd-ldap.5.xml:659

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:654

+ #: sssd-ldap.5.xml:669

  msgid "ldap_group_modify_timestamp (string)"

  msgstr "ldap_group_modify_timestamp (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:667

+ #: sssd-ldap.5.xml:682

  msgid "ldap_group_nesting_level (integer)"

  msgstr "ldap_group_nesting_level (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:670

+ #: sssd-ldap.5.xml:685

  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 "
@@ -2587,104 +2832,104 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:677

+ #: sssd-ldap.5.xml:692

  msgid "Default: 2"

  msgstr "Типове значення: 2"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:683

+ #: sssd-ldap.5.xml:698

  msgid "ldap_netgroup_object_class (string)"

  msgstr "ldap_netgroup_object_class (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:686

+ #: sssd-ldap.5.xml:701

  msgid "The object class of a netgroup entry in LDAP."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:689

+ #: sssd-ldap.5.xml:704

  msgid "Default: nisNetgroup"

  msgstr "Типове значення: nisNetgroup"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:695

+ #: sssd-ldap.5.xml:710

  msgid "ldap_netgroup_name (string)"

  msgstr "ldap_netgroup_name (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:698

+ #: sssd-ldap.5.xml:713

  msgid "The LDAP attribute that corresponds to the netgroup name."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:708

+ #: sssd-ldap.5.xml:723

  msgid "ldap_netgroup_member (string)"

  msgstr "ldap_netgroup_member (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:711

+ #: sssd-ldap.5.xml:726

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:715

+ #: sssd-ldap.5.xml:730

  msgid "Default: memberNisNetgroup"

  msgstr "Типове значення: memberNisNetgroup"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:721

+ #: sssd-ldap.5.xml:736

  msgid "ldap_netgroup_triple (string)"

  msgstr "ldap_netgroup_triple (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:724

+ #: sssd-ldap.5.xml:739

  msgid ""

  "The LDAP attribute that contains the (host, user, domain) netgroup triples."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:728

+ #: sssd-ldap.5.xml:743

  msgid "Default: nisNetgroupTriple"

  msgstr "Типове значення: nisNetgroupTriple"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:734

+ #: sssd-ldap.5.xml:749

  msgid "ldap_netgroup_uuid (string)"

  msgstr "ldap_netgroup_uuid (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:737

+ #: sssd-ldap.5.xml:752

  msgid ""

  "The LDAP attribute that contains the UUID/GUID of an LDAP netgroup object."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:747

+ #: sssd-ldap.5.xml:762

  msgid "ldap_netgroup_modify_timestamp (string)"

  msgstr "ldap_netgroup_modify_timestamp (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:760

+ #: sssd-ldap.5.xml:775

  msgid "ldap_search_timeout (integer)"

  msgstr "ldap_search_timeout (ціле число)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:763

+ #: sssd-ldap.5.xml:778

  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 "
@@ -2692,7 +2937,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:769

+ #: sssd-ldap.5.xml:784

  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 "
@@ -2701,18 +2946,18 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:775 sssd-ldap.5.xml:817 sssd-ldap.5.xml:832

+ #: sssd-ldap.5.xml:790 sssd-ldap.5.xml:832 sssd-ldap.5.xml:847

  msgid "Default: 6"

  msgstr "Типове значення: 6"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:781

+ #: sssd-ldap.5.xml:796

  msgid "ldap_enumeration_search_timeout (integer)"

  msgstr "ldap_enumeration_search_timeout (ціле число)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:784

+ #: sssd-ldap.5.xml:799

  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 "
@@ -2721,19 +2966,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:791

+ #: sssd-ldap.5.xml:806

  msgid "Default: 60"

  msgstr "Типове значення: 60"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:797

+ #: sssd-ldap.5.xml:812

  msgid "ldap_network_timeout (integer)"

  msgstr "ldap_network_timeout (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:800

+ #: sssd-ldap.5.xml:815

  msgid ""

  "Specifies the timeout (in seconds) after which the <citerefentry> "

  "<refentrytitle>poll</refentrytitle> <manvolnum>2</manvolnum> </citerefentry>/"
@@ -2745,13 +2990,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:823

+ #: sssd-ldap.5.xml:838

  msgid "ldap_opt_timeout (integer)"

  msgstr "ldap_opt_timeout (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:826

+ #: sssd-ldap.5.xml:841

  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 "
@@ -2760,13 +3005,36 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:838

+ #: sssd-ldap.5.xml:853

+ #, fuzzy

+ #| msgid "ldap_opt_timeout (integer)"

+ msgid "ldap_page_size (integer)"

+ msgstr "ldap_opt_timeout (ціле число)"

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:856

+ 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>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:861

+ #, fuzzy

+ #| msgid "Default: 10"

+ msgid "Default: 1000"

+ msgstr "Типове значення: 10"

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #: sssd-ldap.5.xml:867

  msgid "ldap_tls_reqcert (string)"

  msgstr "ldap_tls_reqcert (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:841

+ #: sssd-ldap.5.xml:870

  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:"
@@ -2774,7 +3042,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:847

+ #: sssd-ldap.5.xml:876

  msgid ""

  "<emphasis>never</emphasis> = The client will not request or check any server "

  "certificate."
@@ -2782,7 +3050,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:851

+ #: sssd-ldap.5.xml:880

  msgid ""

  "<emphasis>allow</emphasis> = The server certificate is requested. If no "

  "certificate is provided, the session proceeds normally. If a bad certificate "
@@ -2791,7 +3059,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:858

+ #: sssd-ldap.5.xml:887

  msgid ""

  "<emphasis>try</emphasis> = The server certificate is requested. If no "

  "certificate is provided, the session proceeds normally. If a bad certificate "
@@ -2800,7 +3068,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:864

+ #: sssd-ldap.5.xml:893

  msgid ""

  "<emphasis>demand</emphasis> = The server certificate is requested. If no "

  "certificate is provided, or a bad certificate is provided, the session is "
@@ -2809,25 +3077,25 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:870

+ #: sssd-ldap.5.xml:899

  msgid "<emphasis>hard</emphasis> = Same as <quote>demand</quote>"

  msgstr "<emphasis>hard</emphasis> = те саме, що і <quote>demand</quote>"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:874

+ #: sssd-ldap.5.xml:903

  msgid "Default: hard"

  msgstr "Типове значення: hard"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:880

+ #: sssd-ldap.5.xml:909

  msgid "ldap_tls_cacert (string)"

  msgstr "ldap_tls_cacert (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:883

+ #: sssd-ldap.5.xml:912

  msgid ""

  "Specifies the file that contains certificates for all of the Certificate "

  "Authorities that <command>sssd</command> will recognize."
@@ -2835,7 +3103,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:888 sssd-ldap.5.xml:906 sssd-ldap.5.xml:947

+ #: sssd-ldap.5.xml:917 sssd-ldap.5.xml:935 sssd-ldap.5.xml:976

  msgid ""

  "Default: use OpenLDAP defaults, typically in <filename>/etc/openldap/ldap."

  "conf</filename>"
@@ -2843,13 +3111,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:895

+ #: sssd-ldap.5.xml:924

  msgid "ldap_tls_cacertdir (string)"

  msgstr "ldap_tls_cacertdir (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:898

+ #: sssd-ldap.5.xml:927

  msgid ""

  "Specifies the path of a directory that contains Certificate Authority "

  "certificates in separate individual files. Typically the file names need to "
@@ -2859,41 +3127,41 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:913

+ #: sssd-ldap.5.xml:942

  msgid "ldap_tls_cert (string)"

  msgstr "ldap_tls_cert (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:916

+ #: sssd-ldap.5.xml:945

  msgid "Specifies the file that contains the certificate for the client's key."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:920 sssd-ldap.5.xml:932 sssd-krb5.5.xml:356

+ #: sssd-ldap.5.xml:949 sssd-ldap.5.xml:961 sssd-krb5.5.xml:359

  msgid "Default: not set"

  msgstr "Типове значення: not set"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:926

+ #: sssd-ldap.5.xml:955

  msgid "ldap_tls_key (string)"

  msgstr "ldap_tls_key (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:929

+ #: sssd-ldap.5.xml:958

  msgid "Specifies the file that contains the client's key."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:938

+ #: sssd-ldap.5.xml:967

  msgid "ldap_tls_cipher_suite (string)"

  msgstr "ldap_tls_cipher_suite (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:941

+ #: sssd-ldap.5.xml:970

  msgid ""

  "Specifies acceptable cipher suites.  Typically this is a colon sperated "

  "list.  See <citerefentry><refentrytitle>ldap.conf</refentrytitle> "
@@ -2902,13 +3170,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:954

+ #: sssd-ldap.5.xml:983

  msgid "ldap_id_use_start_tls (boolean)"

  msgstr "ldap_id_use_start_tls (булеве значення)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:957

+ #: sssd-ldap.5.xml:986

  msgid ""

  "Specifies that the id_provider connection must also use <systemitem class="

  "\"protocol\">tls</systemitem> to protect the channel."
@@ -2916,13 +3184,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:967

+ #: sssd-ldap.5.xml:996

  msgid "ldap_sasl_mech (string)"

  msgstr "ldap_sasl_mech (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:970

+ #: sssd-ldap.5.xml:999

  msgid ""

  "Specify the SASL mechanism to use.  Currently only GSSAPI is tested and "

  "supported."
@@ -2930,19 +3198,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:974 sssd-ldap.5.xml:1102

+ #: sssd-ldap.5.xml:1003 sssd-ldap.5.xml:1145

  msgid "Default: none"

  msgstr "Типове значення: none"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:980

+ #: sssd-ldap.5.xml:1009

  msgid "ldap_sasl_authid (string)"

  msgstr "ldap_sasl_authid (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:983

+ #: sssd-ldap.5.xml:1012

  msgid ""

  "Specify the SASL authorization id to use.  When GSSAPI is used, this "

  "represents the Kerberos principal used for authentication to the directory."
@@ -2950,37 +3218,60 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:988

+ #: sssd-ldap.5.xml:1017

  msgid "Default: host/machine.fqdn@REALM"

  msgstr "Типове значення: вузол/комп’ютер.fqdn@ОБЛАСТЬ"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:994

+ #: sssd-ldap.5.xml:1023

+ #, fuzzy

+ #| msgid "ldap_krb5_init_creds (boolean)"

+ msgid "ldap_sasl_canonicalize (boolean)"

+ msgstr "ldap_krb5_init_creds (булеве значення)"

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:1026

+ 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>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ldap.5.xml:1031

+ #, fuzzy

+ #| msgid "Default: false"

+ msgid "Default: false;"

+ msgstr "Типове значення: false"

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #: sssd-ldap.5.xml:1037

  msgid "ldap_krb5_keytab (string)"

  msgstr "ldap_krb5_keytab (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:997

+ #: sssd-ldap.5.xml:1040

  msgid "Specify the keytab to use when using SASL/GSSAPI."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1000

+ #: sssd-ldap.5.xml:1043

  msgid "Default: System keytab, normally <filename>/etc/krb5.keytab</filename>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1006

+ #: sssd-ldap.5.xml:1049

  msgid "ldap_krb5_init_creds (boolean)"

  msgstr "ldap_krb5_init_creds (булеве значення)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1009

+ #: sssd-ldap.5.xml:1052

  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 "
@@ -2989,42 +3280,42 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1021

+ #: sssd-ldap.5.xml:1064

  msgid "ldap_krb5_ticket_lifetime (integer)"

  msgstr "ldap_krb5_ticket_lifetime (ціле число)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1024

+ #: sssd-ldap.5.xml:1067

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1028

+ #: sssd-ldap.5.xml:1071

  msgid "Default: 86400 (24 hours)"

  msgstr "Типове значення: 86400 (24 години)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1034 sssd-krb5.5.xml:74

+ #: sssd-ldap.5.xml:1077 sssd-krb5.5.xml:74

  msgid "krb5_server (string)"

  msgstr "krb5_server (рядок)"

  

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1037 sssd-krb5.5.xml:77

+ #: sssd-ldap.5.xml:1080 sssd-krb5.5.xml:77

  msgid ""

- "Specifies the 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."

+ "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:1049 sssd-krb5.5.xml:89

+ #: sssd-ldap.5.xml:1092 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 "
@@ -3033,7 +3324,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1054 sssd-krb5.5.xml:94

+ #: sssd-ldap.5.xml:1097 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 "
@@ -3042,19 +3333,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1063 sssd-krb5.5.xml:103

+ #: sssd-ldap.5.xml:1106 sssd-ipa.5.xml:165 sssd-krb5.5.xml:103

  msgid "krb5_realm (string)"

  msgstr "krb5_realm (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1066

+ #: sssd-ldap.5.xml:1109

  msgid "Specify the Kerberos REALM (for SASL/GSSAPI auth)."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1069

+ #: sssd-ldap.5.xml:1112

  msgid "Default: System defaults, see <filename>/etc/krb5.conf</filename>"

  msgstr ""

  "Типове значення: типове значення системи, див. <filename>/etc/krb5.conf</"
@@ -3062,13 +3353,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1075

+ #: sssd-ldap.5.xml:1118

  msgid "ldap_pwd_policy (string)"

  msgstr "ldap_pwd_policy (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1078

+ #: sssd-ldap.5.xml:1121

  msgid ""

  "Select the policy to evaluate the password expiration on the client side. "

  "The following values are allowed:"
@@ -3076,7 +3367,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1083

+ #: sssd-ldap.5.xml:1126

  msgid ""

  "<emphasis>none</emphasis> - No evaluation on the client side. This option "

  "cannot disable server-side password policies."
@@ -3084,7 +3375,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1088

+ #: sssd-ldap.5.xml:1131

  msgid ""

  "<emphasis>shadow</emphasis> - Use <citerefentry><refentrytitle>shadow</"

  "refentrytitle> <manvolnum>5</manvolnum></citerefentry> style attributes to "
@@ -3094,7 +3385,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1096

+ #: sssd-ldap.5.xml:1139

  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 "
@@ -3103,19 +3394,19 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1108

+ #: sssd-ldap.5.xml:1151

  msgid "ldap_referrals (boolean)"

  msgstr "ldap_referrals (булеве значення)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1111

+ #: sssd-ldap.5.xml:1154

  msgid "Specifies whether automatic referral chasing should be enabled."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1115

+ #: sssd-ldap.5.xml:1158

  msgid ""

  "Please note that sssd only supports referral chasing when it is compiled "

  "with OpenLDAP version 2.4.13 or higher."
@@ -3123,49 +3414,49 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1126

+ #: sssd-ldap.5.xml:1169

  msgid "ldap_dns_service_name (string)"

  msgstr "ldap_dns_service_name (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1129

+ #: sssd-ldap.5.xml:1172

  msgid "Specifies the service name to use when service discovery is enabled."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1133

+ #: sssd-ldap.5.xml:1176

  msgid "Default: ldap"

  msgstr "Типове значення: ldap"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1139

+ #: sssd-ldap.5.xml:1182

  msgid "ldap_chpass_dns_service_name (string)"

  msgstr "ldap_chpass_dns_service_name (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1142

+ #: sssd-ldap.5.xml:1185

  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:1147

+ #: sssd-ldap.5.xml:1190

  msgid "Default: not set, i.e. service discovery is disabled"

  msgstr "Типове значення: не встановлено, тобто пошук служб вимкнено"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1153

+ #: sssd-ldap.5.xml:1196

  msgid "ldap_access_filter (string)"

  msgstr "ldap_access_filter (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1156

+ #: sssd-ldap.5.xml:1199

  msgid ""

  "If using access_provider = ldap, this option is mandatory. It specifies an "

  "LDAP search filter criteria that must be met for the user to be granted "
@@ -3176,13 +3467,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1166

+ #: sssd-ldap.5.xml:1209

  msgid "Example:"

  msgstr "Приклад:"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><programlisting>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><programlisting>

- #: sssd-ldap.5.xml:1169

+ #: sssd-ldap.5.xml:1212

  #, no-wrap

  msgid ""

  "access_provider = ldap\n"
@@ -3195,7 +3486,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1173

+ #: sssd-ldap.5.xml:1216

  msgid ""

  "This example means that access to this host is restricted to members of the "

  "\"allowedusers\" group in ldap."
@@ -3203,7 +3494,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1178

+ #: sssd-ldap.5.xml:1221

  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 "
@@ -3213,25 +3504,25 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1186 sssd-ldap.5.xml:1227

+ #: sssd-ldap.5.xml:1229 sssd-ldap.5.xml:1270

  msgid "Default: Empty"

  msgstr "Типове значення: порожній рядок"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1192

+ #: sssd-ldap.5.xml:1235

  msgid "ldap_account_expire_policy (string)"

  msgstr "ldap_account_expire_policy (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1195

+ #: sssd-ldap.5.xml:1238

  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:1199

+ #: sssd-ldap.5.xml:1242

  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 "
@@ -3239,19 +3530,19 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1206

+ #: sssd-ldap.5.xml:1249

  msgid "The following values are allowed:"

  msgstr "Можна використовувати такі значення:"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1209

+ #: sssd-ldap.5.xml:1252

  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:1214

+ #: sssd-ldap.5.xml:1257

  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 "
@@ -3260,7 +3551,7 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1221

+ #: sssd-ldap.5.xml:1264

  msgid ""

  "<emphasis>rhds</emphasis>, <emphasis>ipa</emphasis>, <emphasis>389ds</"

  "emphasis>: use the value of ldap_ns_account_lock to check if access is "
@@ -3269,12 +3560,12 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1233

+ #: sssd-ldap.5.xml:1276

  msgid "ldap_access_order (string)"

  msgstr "ldap_access_order (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1236

+ #: sssd-ldap.5.xml:1279

  msgid "Comma separated list of access control options.  Allowed values are:"

  msgstr ""

  "Список відокремлених комами параметрів керування доступом. Можливі значення "
@@ -3282,18 +3573,18 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1240

+ #: sssd-ldap.5.xml:1283

  msgid "<emphasis>filter</emphasis>: use ldap_access_filter"

  msgstr "<emphasis>filter</emphasis>: використовувати ldap_access_filter"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1243

+ #: sssd-ldap.5.xml:1286

  msgid "<emphasis>expire</emphasis>: use ldap_account_expire_policy"

  msgstr ""

  "<emphasis>expire</emphasis>: використовувати ldap_account_expire_policy"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1247

+ #: sssd-ldap.5.xml:1290

  msgid ""

  "<emphasis>authorized_service</emphasis>: use the authorizedService attribute "

  "to determine access"
@@ -3303,12 +3594,12 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1252

+ #: sssd-ldap.5.xml:1295

  msgid "Default: filter"

  msgstr "Типове значення: filter"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1255

+ #: sssd-ldap.5.xml:1298

  msgid ""

  "Please note that it is a configuration error if a value is used more than "

  "once."
@@ -3316,13 +3607,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1262

+ #: sssd-ldap.5.xml:1305

  msgid "ldap_deref (string)"

  msgstr "ldap_deref (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1265

+ #: sssd-ldap.5.xml:1308

  msgid ""

  "Specifies how alias dereferencing is done when performing a search. The "

  "following options are allowed:"
@@ -3330,13 +3621,13 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1270

+ #: sssd-ldap.5.xml:1313

  msgid "<emphasis>never</emphasis>: Aliases are never dereferenced."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1274

+ #: sssd-ldap.5.xml:1317

  msgid ""

  "<emphasis>searching</emphasis>: Aliases are dereferenced in subordinates of "

  "the base object, but not in locating the base object of the search."
@@ -3344,7 +3635,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1279

+ #: sssd-ldap.5.xml:1322

  msgid ""

  "<emphasis>finding</emphasis>: Aliases are only dereferenced when locating "

  "the base object of the search."
@@ -3352,7 +3643,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1284

+ #: sssd-ldap.5.xml:1327

  msgid ""

  "<emphasis>always</emphasis>: Aliases are dereferenced both in searching and "

  "in locating the base object of the search."
@@ -3360,7 +3651,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1289

+ #: sssd-ldap.5.xml:1332

  msgid ""

  "Default: Empty (this is handled as <emphasis>never</emphasis> by the LDAP "

  "client libraries)"
@@ -3378,55 +3669,55 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd-ldap.5.xml:1301

+ #: sssd-ldap.5.xml:1344

  msgid "ADVANCED OPTIONS"

  msgstr "ДОДАТКОВІ ПАРАМЕТРИ"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1308

+ #: sssd-ldap.5.xml:1351

  msgid "ldap_netgroup_search_base (string)"

  msgstr "ldap_netgroup_search_base (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1311

+ #: sssd-ldap.5.xml:1354

  msgid ""

  "An optional base DN to restrict netgroup searches to a specific subtree."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1315 sssd-ldap.5.xml:1329 sssd-ldap.5.xml:1343

+ #: sssd-ldap.5.xml:1358 sssd-ldap.5.xml:1372 sssd-ldap.5.xml:1386

  msgid "Default: the value of <emphasis>ldap_search_base</emphasis>"

  msgstr "Типове значення: значення <emphasis>ldap_search_base</emphasis>"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1322

+ #: sssd-ldap.5.xml:1365

  msgid "ldap_user_search_base (string)"

  msgstr "ldap_user_search_base (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1325

+ #: sssd-ldap.5.xml:1368

  msgid "An optional base DN to restrict user searches to a specific subtree."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-ldap.5.xml:1336

+ #: sssd-ldap.5.xml:1379

  msgid "ldap_group_search_base (string)"

  msgstr "ldap_group_search_base (рядок)"

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-ldap.5.xml:1339

+ #: sssd-ldap.5.xml:1382

  msgid "An optional base DN to restrict group searches to a specific subtree."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1303

+ #: sssd-ldap.5.xml:1346

  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 "
@@ -3435,7 +3726,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1359

+ #: sssd-ldap.5.xml:1402

  msgid ""

  "The following example assumes that SSSD is correctly configured and LDAP is "

  "set to one of the domains in the <replaceable>[domains]</replaceable> "
@@ -3444,7 +3735,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><programlisting>

  #. type: Content of: <reference><refentry><refsect1><para><programlisting>

- #: sssd-ldap.5.xml:1365

+ #: sssd-ldap.5.xml:1408

  #, no-wrap

  msgid ""

  "    [domain/LDAP]\n"
@@ -3466,20 +3757,20 @@

  "    enumerate = true\n"

  

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1364 sssd-simple.5.xml:134 sssd-ipa.5.xml:181

- #: sssd-krb5.5.xml:414

+ #: sssd-ldap.5.xml:1407 sssd-simple.5.xml:134 sssd-ipa.5.xml:238

+ #: sssd-krb5.5.xml:417

  msgid "<placeholder type=\"programlisting\" id=\"0\"/>"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: sssd-ldap.5.xml:1378 sssd_krb5_locator_plugin.8.xml:61

+ #: sssd-ldap.5.xml:1421 sssd_krb5_locator_plugin.8.xml:61

  msgid "NOTES"

  msgstr "ЗАУВАЖЕННЯ"

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1380

+ #: sssd-ldap.5.xml:1423

  msgid ""

  "The descriptions of some of the configuration options in this manual page "

  "are based on the <citerefentry> <refentrytitle>ldap.conf</refentrytitle> "
@@ -3489,7 +3780,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ldap.5.xml:1391

+ #: sssd-ldap.5.xml:1434

  msgid ""

  "<citerefentry> <refentrytitle>sssd.conf</refentrytitle><manvolnum>5</"

  "manvolnum> </citerefentry>, <citerefentry> <refentrytitle>sssd-krb5</"
@@ -3526,8 +3817,16 @@

  # type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis>

  #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis>

  #: pam_sss.8.xml:24

- msgid ""

- "<command>pam_sss.so</command> <arg choice='opt'> <replaceable>forward_pass</"

+ #, fuzzy

+ #| msgid ""

+ #| "<command>pam_sss.so</command> <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>"

+ 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> </"
@@ -3541,7 +3840,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:42

+ #: pam_sss.8.xml:45

  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"
@@ -3550,13 +3849,26 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: pam_sss.8.xml:52

+ #: pam_sss.8.xml:55

+ #, fuzzy

+ #| msgid "<option>retry=N</option>"

+ msgid "<option>quiet</option>"

+ msgstr "<option>retry=N</option>"

+ 

+ #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

+ #: pam_sss.8.xml:58

+ msgid "Suppress log messages for unknown users."

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

+ #: pam_sss.8.xml:63

  msgid "<option>forward_pass</option>"

  msgstr "<option>forward_pass</option>"

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:55

+ #: pam_sss.8.xml:66

  msgid ""

  "If <option>forward_pass</option> is set the entered password is put on the "

  "stack for other PAM modules to use."
@@ -3564,13 +3876,13 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: pam_sss.8.xml:62

+ #: pam_sss.8.xml:73

  msgid "<option>use_first_pass</option>"

  msgstr "<option>use_first_pass</option>"

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:65

+ #: pam_sss.8.xml:76

  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 "
@@ -3579,13 +3891,13 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: pam_sss.8.xml:73

+ #: pam_sss.8.xml:84

  msgid "<option>use_authtok</option>"

  msgstr "<option>use_authtok</option>"

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:76

+ #: pam_sss.8.xml:87

  msgid ""

  "When password changing enforce the module to set the new password to the one "

  "provided by a previously stacked password module."
@@ -3593,13 +3905,13 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: pam_sss.8.xml:83

+ #: pam_sss.8.xml:94

  msgid "<option>retry=N</option>"

  msgstr "<option>retry=N</option>"

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:86

+ #: pam_sss.8.xml:97

  msgid ""

  "If specified the user is asked another N times for a password if "

  "authentication fails. Default is 0."
@@ -3607,7 +3919,7 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: pam_sss.8.xml:88

+ #: pam_sss.8.xml:99

  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 "
@@ -3616,13 +3928,13 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: pam_sss.8.xml:99

+ #: pam_sss.8.xml:110

  msgid "MODULE TYPES PROVIDED"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:100

+ #: pam_sss.8.xml:111

  msgid ""

  "All module types (<option>account</option>, <option>auth</option>, "

  "<option>password</option> and <option>session</option>) are provided."
@@ -3630,13 +3942,13 @@

  

  # type: Content of: <reference><refentry><refsect1><title>

  #. type: Content of: <reference><refentry><refsect1><title>

- #: pam_sss.8.xml:106

+ #: pam_sss.8.xml:117

  msgid "FILES"

  msgstr "ФАЙЛИ"

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:107

+ #: pam_sss.8.xml:118

  msgid ""

  "If a password reset by root fails, because the corresponding SSSD provider "

  "does not support password resets, an individual message can be displayed. "
@@ -3645,7 +3957,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:112

+ #: pam_sss.8.xml:123

  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> "
@@ -3658,7 +3970,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:122

+ #: pam_sss.8.xml:133

  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 "
@@ -3667,7 +3979,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: pam_sss.8.xml:130

+ #: pam_sss.8.xml:141

  msgid ""

  "<citerefentry> <refentrytitle>sssd.conf</refentrytitle><manvolnum>8</"

  "manvolnum> </citerefentry>"
@@ -3960,15 +4272,14 @@

  msgid "ipa_server (string)"

  msgstr "ipa_server (рядок)"

  

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-ipa.5.xml:83

  msgid ""

- "The 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 the <quote>SERVICE DISCOVERY</quote> section."

+ "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 the <quote>SERVICE DISCOVERY</quote> section."

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>
@@ -4058,9 +4369,86 @@

  "end."

  msgstr ""

  

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:168

+ 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:172

+ 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><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #: sssd-ipa.5.xml:179

+ #, fuzzy

+ #| msgid "ipa_hbac_search_base (string)"

+ msgid "ipa_hbac_refresh (integer)"

+ msgstr "ipa_hbac_search_base (рядок)"

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:182

+ 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>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:189

+ #, fuzzy

+ #| msgid "Default: gecos"

+ msgid "Default: 5 (seconds)"

+ msgstr "Типове значення: gecos"

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

+ #: sssd-ipa.5.xml:194

+ #, fuzzy

+ #| msgid "ipa_hbac_search_base (string)"

+ msgid "ipa_hbac_treat_deny_as (string)"

+ msgstr "ipa_hbac_search_base (рядок)"

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:197

+ msgid ""

+ "This option specifies how to treat the deprecated DENY-type HBAC rules. As "

+ "of FreeIPA v2.1, DENY rules are no longer supported on the server. All users "

+ "of FreeIPA will need to migrate their rules to use only the ALLOW rules. The "

+ "client will support two modes of operation during this transition period:"

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:206

+ msgid ""

+ "<emphasis>DENY_ALL</emphasis>: If any HBAC DENY rules are detected, all "

+ "users will be denied access."

+ msgstr ""

+ 

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:211

+ msgid ""

+ "<emphasis>IGNORE</emphasis>: SSSD will ignore any DENY rules. Be very "

+ "careful with this option, as it may result in opening unintended access."

+ msgstr ""

+ 

+ # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

+ #: sssd-ipa.5.xml:216

+ #, fuzzy

+ #| msgid "Default: FALSE"

+ msgid "Default: DENY_ALL"

+ msgstr "Типове значення: FALSE"

+ 

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ipa.5.xml:175

+ #: sssd-ipa.5.xml:232

  msgid ""

  "The following example assumes that SSSD is correctly configured and example."

  "com is one of the domains in the <replaceable>[sssd]</replaceable> section. "
@@ -4069,7 +4457,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><programlisting>

  #. type: Content of: <reference><refentry><refsect1><para><programlisting>

- #: sssd-ipa.5.xml:182

+ #: sssd-ipa.5.xml:239

  #, no-wrap

  msgid ""

  "    [domain/example.com]\n"
@@ -4084,7 +4472,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-ipa.5.xml:193

+ #: sssd-ipa.5.xml:250

  msgid ""

  "<citerefentry> <refentrytitle>sssd.conf</refentrytitle><manvolnum>5</"

  "manvolnum> </citerefentry>, <citerefentry> <refentrytitle>sssd-ldap</"
@@ -4336,10 +4724,10 @@

  #. type: Content of: <reference><refentry><refsect1><para>

  #: sss_obfuscate.8.xml:37

  msgid ""

- "The cleartext password can be specified as an argument to the program, 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 "

+ "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."
@@ -4347,7 +4735,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sss_obfuscate.8.xml:50

+ #: 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 "
@@ -4358,19 +4746,19 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: sss_obfuscate.8.xml:64

+ #: sss_obfuscate.8.xml:63

  msgid "<option>-s</option>,<option>--stdin</option>"

  msgstr "<option>-s</option>,<option>--stdin</option>"

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: sss_obfuscate.8.xml:68

+ #: 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>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: sss_obfuscate.8.xml:75

+ #: sss_obfuscate.8.xml:74

  msgid ""

  "<option>-d</option>,<option>--domain</option> <replaceable>DOMAIN</"

  "replaceable>"
@@ -4380,7 +4768,7 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: sss_obfuscate.8.xml:80

+ #: sss_obfuscate.8.xml:79

  msgid ""

  "The SSSD domain to use the password in. The default name is <quote>default</"

  "quote>."
@@ -4388,7 +4776,7 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term>

- #: sss_obfuscate.8.xml:87

+ #: sss_obfuscate.8.xml:86

  msgid ""

  "<option>-f</option>,<option>--file</option> <replaceable>FILE</replaceable>"

  msgstr ""
@@ -4396,19 +4784,19 @@

  

  # type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: sss_obfuscate.8.xml:92

+ #: 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>

  #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para>

- #: sss_obfuscate.8.xml:96

+ #: sss_obfuscate.8.xml:95

  msgid "Default: <filename>/etc/sssd/sssd.conf</filename>"

  msgstr "Типове значення: <filename>/etc/sssd/sssd.conf</filename>"

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sss_obfuscate.8.xml:106

+ #: sss_obfuscate.8.xml:105

  msgid ""

  "<citerefentry> <refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</"

  "manvolnum> </citerefentry>"
@@ -4763,24 +5151,6 @@

  msgid "krb5_ccname_template (string)"

  msgstr "krb5_ccname_template (рядок)"

  

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:166

- msgid "%u"

- msgstr "%u"

- 

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:167

- msgid "login name"

- msgstr "ім'я користувача"

- 

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:170

- msgid "%U"

- msgstr "%U"

- 

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

  #: sssd-krb5.5.xml:171
@@ -4823,12 +5193,6 @@

  msgid "home directory"

  msgstr "домашній каталог"

  

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:188

- msgid "%d"

- msgstr "%d"

- 

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

  #: sssd-krb5.5.xml:189
@@ -4847,18 +5211,6 @@

  msgid "the process ID of the sssd client"

  msgstr "ідентифікатор процесу клієнтської частини sssd"

  

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:200

- msgid "%%"

- msgstr "%%"

- 

- # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

- #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:201

- msgid "a literal '%'"

- msgstr "символ відсотків («%»)"

- 

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-krb5.5.xml:160

  msgid ""
@@ -4926,17 +5278,19 @@

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

  #: sssd-krb5.5.xml:262

  msgid ""

- "Please note that this feature currently only available on a Linux platform."

+ "Please note that this feature currently only available on a Linux platform. "

+ "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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:272

+ #: sssd-krb5.5.xml:275

  msgid "krb5_renewable_lifetime (string)"

  msgstr "krb5_renewable_lifetime (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:275

+ #: sssd-krb5.5.xml:278

  msgid ""

  "Request a renewable ticket with a total lifetime given by an integer "

  "immediately followed by one of the following delimiters:"
@@ -4944,37 +5298,37 @@

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:280 sssd-krb5.5.xml:316

+ #: sssd-krb5.5.xml:283 sssd-krb5.5.xml:319

  msgid "<emphasis>s</emphasis> seconds"

  msgstr "<emphasis>s</emphasis> — секунди"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:283 sssd-krb5.5.xml:319

+ #: sssd-krb5.5.xml:286 sssd-krb5.5.xml:322

  msgid "<emphasis>m</emphasis> minutes"

  msgstr "<emphasis>m</emphasis> — хвилини"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:286 sssd-krb5.5.xml:322

+ #: sssd-krb5.5.xml:289 sssd-krb5.5.xml:325

  msgid "<emphasis>h</emphasis> hours"

  msgstr "<emphasis>h</emphasis> — години"

  

  # type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:289 sssd-krb5.5.xml:325

+ #: sssd-krb5.5.xml:292 sssd-krb5.5.xml:328

  msgid "<emphasis>d</emphasis> days."

  msgstr "<emphasis>d</emphasis> — дні."

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:292 sssd-krb5.5.xml:328

+ #: sssd-krb5.5.xml:295 sssd-krb5.5.xml:331

  msgid "If there is no delimiter <emphasis>s</emphasis> is assumed."

  msgstr ""

  "Якщо позначки часу не буде вказано, вважатиметься, що використано позначку "

  "<emphasis>s</emphasis>."

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:296

+ #: sssd-krb5.5.xml:299

  msgid ""

  "Please note that it is not possible to mix units.  If you want to set the "

  "renewable lifetime to one and a half hours please use '90m' instead of "
@@ -4982,51 +5336,51 @@

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:302

+ #: sssd-krb5.5.xml:305

  msgid "Default: not set, i.e. the TGT is not renewable"

  msgstr ""

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:308

+ #: sssd-krb5.5.xml:311

  msgid "krb5_lifetime (string)"

  msgstr "krb5_lifetime (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:311

+ #: sssd-krb5.5.xml:314

  msgid ""

  "Request ticket with a with a lifetime given by an integer immediately "

  "followed by one of the following delimiters:"

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:332

+ #: sssd-krb5.5.xml:335

  msgid ""

  "Please note that it is not possible to mix units.  If you want 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:337

+ #: sssd-krb5.5.xml:340

  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>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:344

+ #: sssd-krb5.5.xml:347

  msgid "krb5_renew_interval (integer)"

  msgstr "krb5_renew_interval (ціле число)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:347

+ #: sssd-krb5.5.xml:350

  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."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:352

+ #: sssd-krb5.5.xml:355

  msgid "If this option is not set or 0 the automatic renewal is disabled."

  msgstr ""

  "Якщо значення для цього параметра встановлено не буде або буде встановлено "
@@ -5034,51 +5388,51 @@

  

  # type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term>

- #: sssd-krb5.5.xml:362

+ #: sssd-krb5.5.xml:365

  msgid "krb5_use_fast (string)"

  msgstr "krb5_use_fast (рядок)"

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:365

+ #: sssd-krb5.5.xml:368

  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-krb5.5.xml:370

+ #: sssd-krb5.5.xml:373

  msgid ""

  "<emphasis>never</emphasis> use FAST, this is equivalent to not set this "

  "option at all."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:374

+ #: sssd-krb5.5.xml:377

  msgid ""

  "<emphasis>try</emphasis> to use FAST, if the server does not support fast "

  "continue without."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:378

+ #: sssd-krb5.5.xml:381

  msgid ""

  "<emphasis>demand</emphasis> to use FAST, fail if the server does not require "

  "fast."

  msgstr ""

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:382

+ #: sssd-krb5.5.xml:385

  msgid "Default: not set, i.e. FAST is not used."

  msgstr "Типове значення: не встановлено, тобто FAST не використовується."

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:385

+ #: sssd-krb5.5.xml:388

  msgid "Please note that a keytab is required to use fast."

  msgstr ""

  "Будь ласка, зауважте, що для використання fast потрібна таблиця ключів."

  

  #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para>

- #: sssd-krb5.5.xml:388

+ #: sssd-krb5.5.xml:391

  msgid ""

  "Please note also that sssd supports fast only with MIT Kerberos version 1.8 "

  "and above. If sssd used used with an older version using this option is a "
@@ -5097,7 +5451,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-krb5.5.xml:407

+ #: sssd-krb5.5.xml:410

  msgid ""

  "The following example assumes that SSSD is correctly configured and FOO is "

  "one of the domains in the <replaceable>[sssd]</replaceable> section. This "
@@ -5107,7 +5461,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para><programlisting>

  #. type: Content of: <reference><refentry><refsect1><para><programlisting>

- #: sssd-krb5.5.xml:415

+ #: sssd-krb5.5.xml:418

  #, no-wrap

  msgid ""

  "    [domain/FOO]\n"
@@ -5122,7 +5476,7 @@

  

  # type: Content of: <reference><refentry><refsect1><para>

  #. type: Content of: <reference><refentry><refsect1><para>

- #: sssd-krb5.5.xml:426

+ #: sssd-krb5.5.xml:429

  msgid ""

  "<citerefentry> <refentrytitle>sssd.conf</refentrytitle><manvolnum>5</"

  "manvolnum> </citerefentry>, <citerefentry> <refentrytitle>sssd-ldap</"

file added
+4991
The added file is too large to be shown here, see it at: src/man/po/ur.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/vi.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/vi_VN.po
file added
+4992
The added file is too large to be shown here, see it at: src/man/po/zh_CN.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/zh_HK.po
file added
+4991
The added file is too large to be shown here, see it at: src/man/po/zh_TW.po
file modified
+1 -2
@@ -34,8 +34,7 @@

              section of the SSSD config file.

          </para>

          <para>

-             The cleartext password can be specified as an argument to the

-             program, read from standard input or entered interactively.

+             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

file modified
+75 -1
@@ -80,7 +80,7 @@

                      <term>ipa_server (string)</term>

                      <listitem>

                          <para>

-                             The list of IP addresses or hostnames of the

+                             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
@@ -112,6 +112,11 @@

                              the IP address of this client.

                          </para>

                          <para>

+                             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

+                         </para>

+                         <para>

                              Default: false

                          </para>

                      </listitem>
@@ -161,6 +166,75 @@

                      </listitem>

                  </varlistentry>

  

+                 <varlistentry>

+                     <term>krb5_realm (string)</term>

+                     <listitem>

+                         <para>

+                             The name of the Kerberos realm. This is optional and

+                             defaults to the value of <quote>ipa_domain</quote>.

+                         </para>

+                         <para>

+                             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.

+                         </para>

+                     </listitem>

+                 </varlistentry>

+                 <varlistentry>

+                     <term>ipa_hbac_refresh (integer)</term>

+                     <listitem>

+                         <para>

+                             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.

+                         </para>

+                         <para>

+                             Default: 5 (seconds)

+                         </para>

+                     </listitem>

+                 </varlistentry>

+                 <varlistentry>

+                     <term>ipa_hbac_treat_deny_as (string)</term>

+                     <listitem>

+                         <para>

+                             This option specifies how to treat the deprecated

+                             DENY-type HBAC rules. As of FreeIPA v2.1, DENY

+                             rules are no longer supported on the server. All

+                             users of FreeIPA will need to migrate their rules

+                             to use only the ALLOW rules. The client will

+                             support two modes of operation during this

+                             transition period:

+                         </para>

+                         <para>

+                             <emphasis>DENY_ALL</emphasis>: If any HBAC DENY

+                             rules are detected, all users will be denied

+                             access.

+                         </para>

+                         <para>

+                             <emphasis>IGNORE</emphasis>: SSSD will ignore any

+                             DENY rules. Be very careful with this option, as

+                             it may result in opening unintended access.

+                         </para>

+                         <para>

+                             Default: DENY_ALL

+                         </para>

+                     </listitem>

+                 </varlistentry>

+                 <varlistentry>

+                     <term>ipa_hbac_support_srchost (boolean)</term>

+                     <listitem>

+                         <para>

+                             If this is set to false, then srchost as given

+                             to SSSD by PAM will be ignored.

+                         </para>

+                         <para>

+                             Default: false

+                         </para>

+                     </listitem>

+                 </varlistentry>

+ 

              </variablelist>

          </para>

      </refsect1>

file modified
+5 -2
@@ -74,7 +74,7 @@

                      <term>krb5_server (string)</term>

                      <listitem>

                          <para>

-                             Specifies the list of IP addresses or hostnames

+                             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,
@@ -260,7 +260,10 @@

                          </para>

                          <para>

                              Please note that this feature currently only

-                             available on a Linux platform.

+                             available on a Linux platform. Passwords stored in

+                             this way are kept in plaintext in the kernel

+                             keyring and are potentially accessible by the root

+                             user (with difficulty).

                          </para>

                          <para>

                              Default: false

file modified
+73 -3
@@ -60,12 +60,24 @@

                      <term>ldap_uri (string)</term>

                      <listitem>

                          <para>

-                             Specifies the list of URIs of the LDAP servers to which

+                             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 not specified, service discovery is enabled. For more information, refer

                              to the <quote>SERVICE DISCOVERY</quote> section.

                          </para>

+                         <para>

+                             The format of the URI must match the format defined in RFC 2732:

+                         </para>

+                         <para>

+                             ldap[s]://&lt;host&gt;[:port]

+                         </para>

+                         <para>

+                             For explicit IPv6 addresses, &lt;host&gt; must be enclosed in brackets []

+                         </para>

+                         <para>

+                             example: ldap://[fc00::126:25]:389

+                         </para>

                      </listitem>

                  </varlistentry>

  
@@ -73,7 +85,7 @@

                      <term>ldap_chpass_uri (string)</term>

                      <listitem>

                          <para>

-                             Specifies the list of URIs of the LDAP servers to

+                             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
@@ -164,6 +176,9 @@

                          <para>

                              obfuscated_password

                          </para>

+                         <para>

+                             Default: password

+                         </para>

                      </listitem>

                  </varlistentry>

  
@@ -835,6 +850,47 @@

                  </varlistentry>

  

                  <varlistentry>

+                     <term>ldap_page_size (integer)</term>

+                     <listitem>

+                         <para>

+                             Specify the number of records to retrieve from

+                             LDAP in a single request. Some LDAP servers

+                             enforce a maximum limit per-request.

+                         </para>

+                         <para>

+                             Default: 1000

+                         </para>

+                     </listitem>

+                 </varlistentry>

+ 

+                 <varlistentry>

+                     <term>ldap_disable_paging (boolean)</term>

+                     <listitem>

+                         <para>

+                             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.

+                         </para>

+                         <para>

+                             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.

+                         </para>

+                         <para>

+                             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.

+                         </para>

+                         <para>

+                             Default: False

+                         </para>

+                     </listitem>

+                 </varlistentry>

+ 

+                 <varlistentry>

                      <term>ldap_tls_reqcert (string)</term>

                      <listitem>

                          <para>
@@ -991,6 +1047,20 @@

                  </varlistentry>

  

                  <varlistentry>

+                     <term>ldap_sasl_canonicalize (boolean)</term>

+                     <listitem>

+                         <para>

+                             If set to true, the LDAP library would perform

+                             a reverse lookup to canonicalize the host name

+                             during a SASL bind.

+                         </para>

+                         <para>

+                             Default: false;

+                         </para>

+                     </listitem>

+                 </varlistentry>

+ 

+                 <varlistentry>

                      <term>ldap_krb5_keytab (string)</term>

                      <listitem>

                          <para>
@@ -1034,7 +1104,7 @@

                      <term>krb5_server (string)</term>

                      <listitem>

                          <para>

-                             Specifies the list of IP addresses or hostnames

+                             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,

file modified
+154
@@ -185,6 +185,26 @@

                              </para>

                          </listitem>

                      </varlistentry>

+                     <varlistentry>

+                         <term>krb5_rcache_dir (string)</term>

+                         <listitem>

+                             <para>

+                                 Directory on the filesystem where SSSD should

+                                 store Kerberos replay cache files.

+                             </para>

+                             <para>

+                                 This option accepts a special value

+                                 __LIBKRB5_DEFAULTS__ that will instruct SSSD

+                                 to let libkrb5 decide the appropriate

+                                 location for the replay cache.

+                             </para>

+                             <para>

+                                 Default: Distribution-specific and specified

+                                 at build-time. (__LIBKRB5_DEFAULTS__ if not

+                                 configured)

+                             </para>

+                         </listitem>

+                     </varlistentry>

                  </variablelist>

              </para>

          </refsect2>
@@ -244,6 +264,23 @@

                      </listitem>

                  </varlistentry>

                  <varlistentry>

+                     <term>fd_limit</term>

+                     <listitem>

+                         <para>

+                             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.

+                         </para>

+                         <para>

+                             Default: 8192 (or limits.conf "hard" limit)

+                         </para>

+                     </listitem>

+                 </varlistentry>

+                 <varlistentry>

                      <term>command (string)</term>

                      <listitem>

                          <para>
@@ -259,6 +296,21 @@

                          </para>

                      </listitem>

                  </varlistentry>

+                 <varlistentry>

+                     <term>client_idle_timeout</term>

+                     <listitem>

+                         <para>

+                             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 exhasution

+                             on the system.

+                         </para>

+                         <para>

+                             Default: 60

+                         </para>

+                     </listitem>

+                 </varlistentry>

              </variablelist>

          </refsect2>

  
@@ -354,6 +406,95 @@

                          </para>

                      </listitem>

                  </varlistentry>

+                 <varlistentry>

+                     <term>override_homedir (string)</term>

+                     <listitem>

+                         <para>

+                             Override the user's home directory. You

+                             can either provide an absolute value or a

+                             template. In the template, the following

+                             sequences are substituted:

+                             <variablelist>

+                                 <varlistentry>

+                                     <term>%u</term>

+                                     <listitem><para>login name</para></listitem>

+                                 </varlistentry>

+                                 <varlistentry>

+                                     <term>%U</term>

+                                     <listitem><para>UID number</para></listitem>

+                                 </varlistentry>

+                                 <varlistentry>

+                                     <term>%d</term>

+                                     <listitem><para>domain name</para></listitem>

+                                 </varlistentry>

+                                 <varlistentry>

+                                     <term>%f</term>

+                                     <listitem><para>fully qualified user name (user@domain)</para></listitem>

+                                 </varlistentry>

+                                 <varlistentry>

+                                     <term>%%</term>

+                                     <listitem><para>a literal '%'</para>

+                                     </listitem>

+                                 </varlistentry>

+                             </variablelist>

+                         </para>

+                         <para>

+                             This option can also be set per-domain.

+                         </para>

+                     </listitem>

+                 </varlistentry>

+                 <varlistentry>

+                     <term>allowed_shells (string)</term>

+                     <listitem>

+                         <para>

+                             Restrict user shell to one of the listed values. The order of evaluation is:

+                         </para>

+                         <para>

+                             1. If the shell is present in

+                             <quote>/etc/shells</quote>, it is used.

+                         </para>

+                         <para>

+                             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.

+                         </para>

+                         <para>

+                             3. If the shell is not in the allowed_shells list and

+                             not in <quote>/etc/shells</quote>, a nologin shell

+                             is used.

+                         </para>

+                         <para>

+                             An empty string for shell is passed as-is to libc.

+                         </para>

+                         <para>

+                             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.

+                         </para>

+                         <para>

+                             Default: Not set. The user shell is automatically used.

+                         </para>

+                     </listitem>

+                 </varlistentry>

+                 <varlistentry>

+                     <term>vetoed_shells (string)</term>

+                     <listitem>

+                         <para>

+                             Replace any instance of these shells with the shell_fallback

+                         </para>

+                     </listitem>

+                 </varlistentry>

+                 <varlistentry>

+                     <term>shell_fallback (string)</term>

+                     <listitem>

+                         <para>

+                             The default shell to use if an allowed shell is not

+                             installed on the machine.

+                         </para>

+                         <para>

+                             Default: /bin/sh

+                         </para>

+                     </listitem>

+                 </varlistentry>

              </variablelist>

          </refsect2>

          <refsect2 id='PAM'>
@@ -588,6 +729,10 @@

                              in the local LDB cache

                          </para>

                          <para>

+                             User credentials are stored in a SHA512 hash, not

+                             in plaintext

+                         </para>

+                         <para>

                              Default: FALSE

                          </para>

                      </listitem>
@@ -807,6 +952,15 @@

                          </para>

                      </listitem>

                  </varlistentry>

+ 

+                 <varlistentry>

+                     <term>override_gid (integer)</term>

+                     <listitem>

+                         <para>

+                             Override the primary GID value with the one specified.

+                         </para>

+                     </listitem>

+                 </varlistentry>

              </variablelist>

          </para>

  

file modified
+402 -237
@@ -52,16 +52,42 @@

  #include "dbus/dbus.h"

  #include "sbus/sssd_dbus.h"

  #include "monitor/monitor_interfaces.h"

+ #include "providers/child_common.h"

  

  /* 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

  

+ /* 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

+ 

+ /* Special value to leave the Kerberos Replay Cache set to use

+  * the libkrb5 defaults

+  */

+ #define KRB5_RCACHE_DIR_DISABLE "__LIBKRB5_DEFAULTS__"

+ 

  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;

  
@@ -79,12 +105,16 @@

  

      int restarts;

      time_t last_restart;

-     time_t last_ping;

      int failed_pongs;

+     DBusPendingCall *pending;

  

      int debug_level;

  

      struct tevent_timer *ping_ev;

+ 

+     struct sss_child_ctx *child_ctx;

+ 

+     struct tevent_timer *sigkill_ev;

  };

  

  struct config_file_callback {
@@ -112,6 +142,8 @@

      struct sss_domain_info *domains;

      TALLOC_CTX *service_ctx; /* Memory context for services */

      char **services;

+     int num_services;

+     int started_services;

      struct mt_svc *svc_list;

      struct sbus_connection *sbus_srv;

      struct config_file_ctx *file_ctx;
@@ -120,6 +152,9 @@

      bool check_children;

      bool services_started;

      struct netlink_ctx *nlctx;

+     struct sss_sigchild_ctx *sigchld_ctx;

+     bool is_daemon;

+     pid_t parent_pid;

  };

  

  static int start_service(struct mt_svc *mt_svc);
@@ -130,18 +165,19 @@

  static int service_signal_reset_offline(struct mt_svc *svc);

  static void ping_check(DBusPendingCall *pending, void *data);

  

- static int service_check_alive(struct mt_svc *svc);

- 

  static void set_tasks_checker(struct mt_svc *srv);

- static void set_global_checker(struct mt_ctx *ctx);

  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);

- static int add_new_provider(struct mt_ctx *ctx, const char *name);

+ 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);

  
@@ -306,6 +342,11 @@

          DLIST_REMOVE(svc->mt_ctx->svc_list, svc);

      }

  

+     /* Cancel any pending pings */

+     if (svc->pending) {

+         dbus_pending_call_cancel(svc->pending);

+     }

+ 

      /* svc is beeing freed, neutralize the spy */

      if (svc->conn_spy) {

          talloc_set_destructor((TALLOC_CTX *)svc->conn_spy, NULL);
@@ -381,7 +422,35 @@

          DEBUG(4, ("Now starting services!\n"));

          /* then start all services */

          for (i = 0; ctx->services[i]; i++) {

-             add_new_service(ctx, ctx->services[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)));

+             }

          }

      }

  
@@ -408,7 +477,7 @@

          DEBUG(4, ("Now starting services!\n"));

          /* then start all services */

          for (i = 0; ctx->services[i]; i++) {

-             add_new_service(ctx, ctx->services[i]);

+             add_new_service(ctx, ctx->services[i], 0);

          }

      }

  }
@@ -457,113 +526,43 @@

  

      ret = sbus_new_server(ctx, ctx->ev,

                            monitor_address, &monitor_server_interface,

-                           &ctx->sbus_srv, monitor_service_init, ctx);

+                           false, &ctx->sbus_srv, monitor_service_init, ctx);

  

      talloc_free(monitor_address);

  

      return ret;

  }

  

- static void svc_try_restart(struct mt_svc *svc, time_t now)

- {

-     int ret;

- 

-     DLIST_REMOVE(svc->mt_ctx->svc_list, svc);

-     if (svc->last_restart != 0) {

-         if ((now - svc->last_restart) > 30) { /* TODO: get val from config */

-             /* it was long ago reset restart threshold */

-             svc->restarts = 0;

-         }

-     }

- 

-     /* restart the process */

-     if (svc->restarts > 3) { /* TODO: get val from config */

-         DEBUG(0, ("Process [%s], definitely stopped!\n", svc->name));

-         talloc_free(svc);

-         return;

-     }

- 

-     /* Shut down the current ping timer so it will restart

-      * cleanly in start_service()

-      */

-     talloc_free(svc->ping_ev);

- 

-     ret = start_service(svc);

-     if (ret != EOK) {

-         DEBUG(0,("Failed to restart service '%s'\n", svc->name));

-         talloc_free(svc);

-         return;

-     }

- 

-     svc->restarts++;

-     svc->last_restart = now;

-     return;

- }

- 

  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);

-     time_t now = time(NULL);

-     bool process_alive = true;

      int ret;

  

-     ret = service_check_alive(svc);

+     ret = service_send_ping(svc);

      switch (ret) {

      case EOK:

          /* all fine */

          break;

  

-     case ECHILD:

-         DEBUG(1,("Process (%s) is stopped!\n", svc->name));

-         process_alive = false;

+     case ENXIO:

+         DEBUG(1,("Child (%s) not responding! (yet)\n", svc->name));

          break;

  

      default:

-         /* TODO: should we tear down it ? */

-         DEBUG(1,("Checking for service %s(%d) failed!!\n",

-                  svc->name, svc->pid));

+         /* TODO: should we tear it down ? */

+         DEBUG(1,("Sending a message to service (%s) failed!!\n", svc->name));

          break;

      }

  

-     if (process_alive) {

-         ret = service_send_ping(svc);

-         switch (ret) {

-         case EOK:

-             /* all fine */

-             break;

+     if (svc->failed_pongs >= 3) {

+         /* too long since we last heard of this process */

+         DEBUG(1, ("Killing service [%s], not responding to pings!\n",

+                svc->name));

  

-         case ENXIO:

-             DEBUG(1,("Child (%s) not responding! (yet)\n", svc->name));

-             break;

- 

-         default:

-             /* TODO: should we tear it down ? */

-             DEBUG(1,("Sending a message to service (%s) failed!!\n", svc->name));

-             break;

-         }

- 

-         if (svc->last_ping != 0) {

-             if ((now - svc->last_ping) > (svc->ping_time)) {

-                 svc->failed_pongs++;

-             } else {

-                 svc->failed_pongs = 0;

-             }

-             if (svc->failed_pongs > 3) {

-                 /* too long since we last heard of this process */

-                 DEBUG(1, ("Killing service [%s], not responding to pings!\n",

-                           svc->name));

-                 monitor_kill_service(svc);

-                 process_alive = false;

-             }

-         }

- 

-         svc->last_ping = now;

-     }

- 

-     if (!process_alive) {

-         svc_try_restart(svc, now);

+         /* Kill the service. The SIGCHLD handler will restart it */

+         monitor_kill_service(svc);

          return;

      }

  
@@ -588,75 +587,49 @@

      svc->ping_ev = te;

  }

  

- static void global_checks_handler(struct tevent_context *ev,

-                                   struct tevent_timer *te,

-                                   struct timeval t, void *ptr)

+ 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)

  {

-     struct mt_ctx *ctx = talloc_get_type(ptr, struct mt_ctx);

-     struct mt_svc *svc;

-     int status;

-     pid_t pid;

- 

-     if (!ctx->check_children) {

-         goto done;

-     }

- 

-     errno = 0;

-     pid = waitpid(0, &status, WNOHANG);

-     if (pid == 0) {

-         goto done;

-     }

+     int ret;

+     struct timeval tv;

  

-     if (pid == -1) {

-         DEBUG(0, ("waitpid returned -1 (errno:%d[%s])\n",

-                   errno, strerror(errno)));

-         goto done;

+     ret = kill(svc->pid, SIGTERM);

+     if (ret != EOK) {

+         DEBUG(0, ("Sending signal to child (%s:%d) failed! "

+                "Ignore and pretend child is dead.\n",

+                svc->name, svc->pid));

+         talloc_free(svc);

      }

  

-     /* let's see if it is a known service, and try to restart it */

-     for (svc = ctx->svc_list; svc; svc = svc->next) {

-         if (svc->pid == pid) {

-             time_t now = time(NULL);

-             DEBUG(1, ("Service [%s] did exit\n", svc->name));

-             svc_try_restart(svc, now);

-             goto done;

-         }

-     }

-     if (svc == NULL) {

-         DEBUG(0, ("Unknown child (%d) did exit\n", pid));

-     }

+     /* Set up a timer to send SIGKILL if this process

+      * doesn't exit within sixty seconds

+      */

+     tv = tevent_timeval_current_ofs(60, 0);

+     svc->sigkill_ev = tevent_add_timer(svc->mt_ctx->ev, svc, tv,

+                                        mt_svc_sigkill, svc);

  

- done:

-     set_global_checker(ctx);

+     return ret;

  }

  

- static void set_global_checker(struct mt_ctx *ctx)

+ static void mt_svc_sigkill(struct tevent_context *ev,

+                            struct tevent_timer *te,

+                            struct timeval t, void *ptr)

  {

-     struct tevent_timer *te = NULL;

-     struct timeval tv;

+     int ret;

+     struct mt_svc *svc = talloc_get_type(ptr, struct mt_svc);

  

-     gettimeofday(&tv, NULL);

-     tv.tv_sec += 1; /* once a second */

-     tv.tv_usec = 0;

-     te = tevent_add_timer(ctx->ev, ctx, tv, global_checks_handler, ctx);

-     if (te == NULL) {

-         DEBUG(0, ("failed to add global checker event! PANIC TIME!\n"));

-         /* FIXME: is this right ? shoulkd we try to clean up first ?*/

-         exit(-1);

-     }

- }

+     DEBUG(0, ("[%s][%d] is not responding to SIGTERM. Sending SIGKILL.\n",

+            svc->name, svc->pid));

  

- static int monitor_kill_service (struct mt_svc *svc)

- {

-     int ret;

-     ret = kill(svc->pid, SIGTERM);

+     ret = kill(svc->pid, SIGKILL);

      if (ret != EOK) {

-         DEBUG(0,("Sending signal to child (%s:%d) failed! "

-                  "Ignore and pretend child is dead.\n",

-                  svc->name, svc->pid));

+         DEBUG(0, ("Sending signal to child (%s:%d) failed! "

+               "Ignore and pretend child is dead.\n",

+               svc->name, svc->pid));

+         talloc_free(svc);

      }

- 

-     return ret;

  }

  

  static void reload_reply(DBusPendingCall *pending, void *data)
@@ -842,6 +815,7 @@

      int ret;

      int timeout_seconds;

      char *badsrv = NULL;

+     int i;

  

      ret = confdb_get_int(ctx->cdb, ctx,

                           CONFDB_MONITOR_CONF_ENTRY,
@@ -872,6 +846,12 @@

          return EINVAL;

      }

  

+     ctx->started_services = 0;

+     ctx->num_services = 0;

+     for (i = 0; ctx->services[i] != NULL; i++) {

+         ctx->num_services++;

+     }

+ 

      ctx->domain_ctx = talloc_new(ctx);

      if(!ctx->domain_ctx) {

          return ENOMEM;
@@ -903,6 +883,7 @@

      int ret;

      char *path;

      struct mt_svc *svc;

+     time_t now = time(NULL);

  

      *svc_cfg = NULL;

  
@@ -911,6 +892,7 @@

          return ENOMEM;

      }

      svc->mt_ctx = ctx;

+     svc->type = MT_SVC_SERVICE;

  

      talloc_set_destructor((TALLOC_CTX *)svc, svc_destructor);

  
@@ -969,13 +951,17 @@

          svc->ping_time = MONITOR_DEF_PING_TIME;

      }

  

+     svc->last_restart = now;

+ 

      *svc_cfg = svc;

      talloc_free(path);

  

      return EOK;

  }

  

- static int add_new_service(struct mt_ctx *ctx, const char *name)

+ static int add_new_service(struct mt_ctx *ctx,

+                            const char *name,

+                            int restarts)

  {

      int ret;

      struct mt_svc *svc;
@@ -985,6 +971,8 @@

          return ret;

      }

  

+     svc->restarts = restarts;

+ 

      ret = start_service(svc);

      if (ret != EOK) {

          DEBUG(0,("Failed to start service '%s'\n", svc->name));
@@ -1000,6 +988,7 @@

      int ret;

      char *path;

      struct mt_svc *svc;

+     time_t now = time(NULL);

  

      *svc_cfg = NULL;

  
@@ -1008,6 +997,7 @@

          return ENOMEM;

      }

      svc->mt_ctx = ctx;

+     svc->type = MT_SVC_PROVIDER;

  

      talloc_set_destructor((TALLOC_CTX *)svc, svc_destructor);

  
@@ -1082,12 +1072,16 @@

              return ENOMEM;

          }

      }

+     svc->last_restart = now;

+ 

  

      *svc_cfg = svc;

      return EOK;

  }

  

- static int add_new_provider(struct mt_ctx *ctx, const char *name)

+ static int add_new_provider(struct mt_ctx *ctx,

+                             const char *name,

+                             int restarts)

  {

      int ret;

      struct mt_svc *svc;
@@ -1098,6 +1092,7 @@

                    name));

          return ret;

      }

+     svc->restarts = restarts;

  

      if (strcasecmp(svc->provider, "local") == 0) {

          /* The LOCAL provider requires no back-end currently
@@ -1164,14 +1159,8 @@

      return EOK;

  }

  

- static void monitor_quit(struct tevent_context *ev,

-                          struct tevent_signal *se,

-                          int signum,

-                          int count,

-                          void *siginfo,

-                          void *private_data)

+ static void monitor_quit(struct mt_ctx *mt_ctx, int ret)

  {

-     struct mt_ctx *mt_ctx = talloc_get_type(private_data, struct mt_ctx);

      struct mt_svc *svc;

      pid_t pid;

      int status;
@@ -1179,10 +1168,7 @@

      int kret;

      bool killed;

  

-     DEBUG(8, ("Received shutdown command\n"));

- 

-     DEBUG(0, ("Monitor received %s: terminating children\n",

-               strsignal(signum)));

+     DEBUG(SSSDBG_OP_FAILURE, ("Returned with: %d\n", ret));

  

      /* Kill all of our known children manually */

      DLIST_FOR_EACH(svc, mt_ctx->svc_list) {
@@ -1209,7 +1195,9 @@

                  if (pid == -1) {

                      /* An error occurred while waiting */

                      error = errno;

-                     if (error != EINTR) {

+                     if (error == ECHILD) {

+                         killed = true;

+                     } else if (error != EINTR) {

                          DEBUG(0, ("[%d][%s] while waiting for [%s]\n",

                                    error, strerror(error), svc->name));

                          /* Forcibly kill this child */
@@ -1257,7 +1245,24 @@

  

      monitor_cleanup();

  

-     exit(0);

+     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_OP_FAILURE, ("Monitor received %s: terminating "

+                                   "children\n", strsignal(signum)));

+ 

+     monitor_quit(mt_ctx, 0);

  }

  

  static void signal_offline(struct tevent_context *ev,
@@ -1545,6 +1550,7 @@

          struct tevent_timer *tev;

          tv.tv_sec = t.tv_sec+5;

          tv.tv_usec = t.tv_usec;

+         DEBUG(5, ("Restoring inotify watch.\n"));

  

          cb->retries = 0;

          rw_ctx = talloc(file_ctx, struct rewatch_ctx);
@@ -1574,6 +1580,10 @@

      talloc_free(tmp_ctx);

  }

  

+ errno_t monitor_config_file_fallback(TALLOC_CTX *mem_ctx,

+                                      struct mt_ctx *ctx,

+                                      const char *file,

+                                      monitor_reconf_fn fn);

  static void rewatch_config_file(struct tevent_context *ev,

                                  struct tevent_timer *te,

                                  struct timeval t, void *ptr)
@@ -1594,9 +1604,23 @@

      /* Retry six times at five-second intervals before giving up */

      cb->retries++;

      if (cb->retries > 6) {

-         DEBUG(0, ("Could not restore inotify watch. Quitting!\n"));

+         DEBUG(0, ("Could not restore inotify watch. Switching to polling!\n"));

          close(file_ctx->mt_ctx->inotify_fd);

-         kill(getpid(), SIGTERM);

+         err = monitor_config_file_fallback(file_ctx->parent_ctx,

+                                            file_ctx->mt_ctx,

+                                            cb->filename,

+                                            cb->fn);

+         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,
@@ -1756,9 +1780,7 @@

  {

      int ret, err;

      bool use_inotify;

-     struct timeval tv;

      struct stat file_stat;

-     struct config_file_callback *cb = NULL;

  

      ret = stat(file, &file_stat);

      if (ret < 0) {
@@ -1793,31 +1815,54 @@

  

      if (!use_inotify) {

          /* Could not monitor file with inotify, fall back to polling */

-         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) {

+         ret = monitor_config_file_fallback(mem_ctx, ctx, file, fn);

+     }

+ 

+     return ret;

+ }

+ 

+ errno_t monitor_config_file_fallback(TALLOC_CTX *mem_ctx,

+                                      struct mt_ctx *ctx,

+                                      const char *file,

+                                      monitor_reconf_fn fn)

+ {

+     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;

+         DEBUG(0, ("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 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 EIO;

          }

      }

  
@@ -1831,8 +1876,34 @@

      struct sysdb_ctx_list *db_list;

      struct tevent_signal *tes;

      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(1,

+                   ("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,
@@ -1844,14 +1915,14 @@

      /* Set up an event handler for a SIGINT */

      BlockSignals(false, SIGINT);

      tes = tevent_add_signal(ctx->ev, ctx, SIGINT, 0,

-                             monitor_quit, ctx);

+                             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, ctx);

+                             monitor_quit_signal, ctx);

      if (tes == NULL) {

          return EIO;

      }
@@ -1872,6 +1943,10 @@

          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.
@@ -1923,7 +1998,7 @@

      /* start providers */

      num_providers = 0;

      for (dom = ctx->domains; dom; dom = dom->next) {

-         ret = add_new_provider(ctx, dom->name);

+         ret = add_new_provider(ctx, dom->name, 0);

          if (ret != EOK && ret != ENOENT) {

              return ret;

          }
@@ -1949,13 +2024,10 @@

          /* 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]);

+             add_new_service(ctx, ctx->services[i], 0);

          }

      }

  

-     /* now start checking for global events */

-     set_global_checker(ctx);

- 

      return EOK;

  }

  
@@ -2047,8 +2119,9 @@

      }

  

      ret = sbus_conn_send(svc->conn, msg,

-                          svc->mt_ctx->service_id_timeout,

-                          ping_check, svc, NULL);

+                          svc->ping_time * 1000, /* milliseconds */

+                          ping_check, svc, &svc->pending);

+ 

      dbus_message_unref(msg);

      return ret;

  }
@@ -2058,9 +2131,17 @@

      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(1, ("Invalid service pointer.\n"));

+         return;

+     }

+     svc->pending = NULL;

  

      reply = dbus_pending_call_steal_reply(pending);

      if (!reply) {
@@ -2090,13 +2171,26 @@

      case DBUS_MESSAGE_TYPE_ERROR:

  

          dbus_error_name = dbus_message_get_error_name(reply);

+         if (!dbus_error_name) {

+             dbus_error_name = "<UNKNOWN>";

+         }

+ 

+         len = strlen(DBUS_ERROR_NO_REPLY);

  

-         /* timeouts are handled in the main service check function */

-         if (strcmp(dbus_error_name, DBUS_ERROR_TIMEOUT) == 0)

+         /* Increase failed pong count */

+         if (strnlen(dbus_error_name, len + 1) == len

+                 && strncmp(dbus_error_name, DBUS_ERROR_NO_REPLY, len) == 0) {

+             DEBUG(1,

+                   ("A service PING timed out on [%s]. "

+                    "Attempt [%d]\n",

+                    svc->name, svc->failed_pongs));

+             svc->failed_pongs++;

              break;

+         }

  

-         DEBUG(0,("A service PING returned an error [%s], closing connection.\n",

-                  dbus_error_name));

+         DEBUG(0,

+               ("A service PING returned an error [%s], closing connection.\n",

+                dbus_error_name));

          /* Falling through to default intentionally*/

      default:

          /*
@@ -2114,39 +2208,6 @@

      dbus_message_unref(reply);

  }

  

- 

- 

- /* service_check_alive

-  * This function checks if the service child is still alive

-  */

- static int service_check_alive(struct mt_svc *svc)

- {

-     int status;

-     pid_t pid;

- 

-     DEBUG(4,("Checking service %s(%d) is still alive\n", svc->name, svc->pid));

- 

-     pid = waitpid(svc->pid, &status, WNOHANG);

-     if (pid == 0) {

-         return EOK;

-     }

- 

-     if (pid != svc->pid) {

-         DEBUG(1, ("bad return (%d) from waitpid() waiting for %d\n",

-                   pid, svc->pid));

-         /* TODO: what do we do now ? */

-         return EINVAL;

-     }

- 

-     if (WIFEXITED(status)) { /* children exited on it's own */

-         /* TODO: check configuration to see if it was removed

-          * from the list of process to run */

-         DEBUG(0,("Process [%s] exited\n", svc->name));

-     }

- 

-     return ECHILD;

- }

- 

  static void service_startup_handler(struct tevent_context *ev,

                                      struct tevent_timer *te,

                                      struct timeval t, void *ptr);
@@ -2180,10 +2241,12 @@

      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;

  
@@ -2202,6 +2265,21 @@

          /* 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(0, ("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);

  
@@ -2223,6 +2301,91 @@

      _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(6, ("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(1,

+               ("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);

+     struct mt_ctx *mt_ctx = svc->mt_ctx;

+     time_t now = time(NULL);

+     struct tevent_timer *te;

+     struct timeval tv;

+     int restart_delay;

+ 

+     if WIFEXITED(wait_status) {

+         DEBUG(2, ("Child [%s] exited with code [%d]\n",

+                svc->name, WEXITSTATUS(wait_status)));

+     } else if WIFSIGNALED(wait_status) {

+         DEBUG(2, ("Child [%s] terminated with signal [%d]\n",

+                svc->name, WTERMSIG(wait_status)));

+     } else {

+         DEBUG(0, ("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;

+     }

+ 

+     if ((now - svc->last_restart) > MONITOR_RESTART_CNT_INTERVAL_RESET) {

+         svc->restarts = 0;

+     }

+ 

+     /* Restart the service */

+     if (svc->restarts > MONITOR_MAX_SVC_RESTARTS) {

+         DEBUG(0, ("Process [%s], definitely stopped!\n", svc->name));

+         talloc_free(svc);

+ 

+         /* exit with error */

+         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) {

+         /* Nothing much we can do */

+         DEBUG(1, ("Out of memory?!\n"));

+         return;

+     }

+ }

+ 

  int main(int argc, const char *argv[])

  {

      int opt;
@@ -2308,7 +2471,7 @@

      }

  

      /* Warn if nscd seems to be running */

-     ret = check_file(NSCD_SOCKET_PATH, -1, -1, -1, CHECK_SOCK, NULL);

+     ret = check_file(NSCD_SOCKET_PATH, -1, -1, -1, CHECK_SOCK, NULL, false);

      if (ret == EOK) {

          sss_log(SSS_LOG_NOTICE,

                  "nscd socket was detected.  Nscd caching capabilities "
@@ -2338,6 +2501,8 @@

      ret = server_setup("sssd", flags, CONFDB_MONITOR_CONF_ENTRY, &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);

  

file modified
+239 -7
@@ -33,7 +33,217 @@

  #include "db/sysdb.h"

  #include "providers/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;

+ };

+ 

+ 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(0, ("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(0, ("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(8, ("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(2, ("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);

+     }

+ }

+ 

+ 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(8, ("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(sigchld_ctx->ev);

+             if (imm == NULL) {

+                 DEBUG(1, ("Out of memory invoking SIGCHLD callback\n"));

+                 return;

+             }

+ 

+             invoke_pvt = talloc_zero(child_ctx, struct sss_child_cb_pvt);

+             if (invoke_pvt == NULL) {

+                 DEBUG(1, ("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(7, ("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(2, ("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;
@@ -42,13 +252,14 @@

  };

  

  int child_handler_setup(struct tevent_context *ev, int pid,

-                         sss_child_callback_t cb, void *pvt)

+                         sss_child_callback_t cb, void *pvt,

+                         struct sss_child_ctx_old **_child_ctx)

  {

-     struct sss_child_ctx *child_ctx;

+     struct sss_child_ctx_old *child_ctx;

  

      DEBUG(8, ("Setting up signal handler up for pid [%d]\n", pid));

  

-     child_ctx = talloc_zero(ev, struct sss_child_ctx);

+     child_ctx = talloc_zero(ev, struct sss_child_ctx_old);

      if (child_ctx == NULL) {

          return ENOMEM;

      }
@@ -66,9 +277,30 @@

      child_ctx->pvt = pvt;

  

      DEBUG(8, ("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 {
@@ -300,7 +532,7 @@

                         int count, void *__siginfo, void *pvt)

  {

      int ret, err;

-     struct sss_child_ctx *child_ctx;

+     struct sss_child_ctx_old *child_ctx;

      struct tevent_immediate *imm;

  

      if (count <= 0) {
@@ -308,7 +540,7 @@

          return;

      }

  

-     child_ctx = talloc_get_type(pvt, struct sss_child_ctx);

+     child_ctx = talloc_get_type(pvt, struct sss_child_ctx_old);

      DEBUG(7, ("Waiting for child [%d].\n", child_ctx->pid));

  

      errno = 0;
@@ -363,8 +595,8 @@

                                    struct tevent_immediate *imm,

                                    void *pvt)

  {

-     struct sss_child_ctx *child_ctx =

-             talloc_get_type(pvt, struct sss_child_ctx);

+     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);

      }

file modified
+32 -1
@@ -45,6 +45,31 @@

      size_t size;

  };

  

+ /* 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);

+ 

+ void sss_child_handler(struct tevent_context *ev,

+                        struct tevent_signal *se,

+                        int signum,

+                        int count,

+                        void *siginfo,

+                        void *private_data);

+ 

  /* 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.
@@ -53,9 +78,15 @@

                                       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);

+                         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,

file modified
+109 -16
@@ -42,6 +42,7 @@

  #include "sbus/sssd_dbus.h"

  #include "providers/dp_backend.h"

  #include "providers/fail_over.h"

+ #include "providers/child_common.h"

  #include "resolv/async_resolv.h"

  #include "monitor/monitor_interfaces.h"

  
@@ -121,28 +122,112 @@

      async_req->fn(async_req->req);

  }

  

- static int be_file_request(struct be_ctx *ctx,

-                            be_req_fn_t fn,

-                            struct be_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 = mem_ctx;

+ 

+     /* 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 || !req) return EINVAL;

+     if (!fn || !be_req) return EINVAL;

  

-     areq = talloc(req, struct be_async_req);

+     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 = req;

+     areq->req = be_req;

  

      /* fire immediately */

      tv.tv_sec = 0;

      tv.tv_usec = 0;

  

-     te = tevent_add_timer(ctx->ev, req, tv, be_async_req_handler, areq);

+     te = tevent_add_timer(be_req->be_ctx->ev, be_req,

+                           tv, be_async_req_handler, areq);

      if (te == NULL) {

          return EIO;

      }
@@ -446,9 +531,9 @@

  

      be_req->req_data = req;

  

-     ret = be_file_request(becli->bectx,

-                           becli->bectx->bet_info[BET_ID].bet_ops->handler,

-                           be_req);

+     ret = be_file_request(becli->bectx->bet_info[BET_ID].pvt_bet_data,

+                           be_req,

+                           becli->bectx->bet_info[BET_ID].bet_ops->handler);

      if (ret != EOK) {

          err_maj = DP_ERR_FATAL;

          err_min = ret;
@@ -608,9 +693,9 @@

  

      be_req->req_data = pd;

  

-     ret = be_file_request(becli->bectx,

-                           becli->bectx->bet_info[target].bet_ops->handler,

-                           be_req);

+     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(7, ("be_file_request failed.\n"));

          goto done;
@@ -737,8 +822,9 @@

      req->be_ctx->offstat.went_offline = time(NULL);

      reset_fo(req->be_ctx);

  

-     ret = be_file_request(req->be_ctx,

-               req->be_ctx->bet_info[BET_ID].bet_ops->check_online, req);

+     ret = be_file_request(req->be_ctx, req,

+                           req->be_ctx->bet_info[BET_ID].bet_ops->check_online);

+ 

      if (ret != EOK) {

          DEBUG(1, ("be_file_request failed.\n"));

      }
@@ -907,7 +993,7 @@

      }

  

      ret = sbus_new_server(ctx, ctx->ev, sbus_address,

-                           &be_interface, &ctx->sbus_srv,

+                           &be_interface, true, &ctx->sbus_srv,

                            be_client_init, ctx);

      if (ret != EOK) {

          DEBUG(0, ("Could not set up sbus server.\n"));
@@ -1255,6 +1341,13 @@

          return EIO;

      }

  

+     ret = sss_sigchld_init(ctx, ctx->ev, &ctx->sigchld_ctx);

+     if (ret != EOK) {

+         DEBUG(0, ("Could not initialize sigchld context: [%s]\n",

+                strerror(ret)));

+         return ret;

+     }

+ 

      return EOK;

  }

  

@@ -42,9 +42,11 @@

      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 {
@@ -350,6 +352,7 @@

      int attempts;

  

      struct fo_server *srv;

+     bool first_try;

  };

  

  static void be_resolve_server_done(struct tevent_req *subreq);
@@ -357,7 +360,8 @@

  struct tevent_req *be_resolve_server_send(TALLOC_CTX *memctx,

                                            struct tevent_context *ev,

                                            struct be_ctx *ctx,

-                                           const char *service_name)

+                                           const char *service_name,

+                                           bool first_try)

  {

      struct tevent_req *req, *subreq;

      struct be_resolve_server_state *state;
@@ -378,6 +382,7 @@

  

      state->svc = svc;

      state->attempts = 0;

+     state->first_try = first_try;

  

      subreq = fo_resolve_service_send(state, ev,

                                       ctx->be_fo->resolv,
@@ -400,37 +405,38 @@

                                               struct be_resolve_server_state);

      struct be_svc_callback *callback;

      int ret;

+     time_t srv_status_change;

  

      ret = fo_resolve_service_recv(subreq, &state->srv);

      talloc_zfree(subreq);

      switch (ret) {

      case EOK:

          if (!state->srv) {

-             tevent_req_error(req, EFAULT);

-             return;

+             ret = EFAULT;

+             goto fail;

          }

          break;

  

      case ENOENT:

          /* all servers have been tried and none

           * was found good, go offline */

-         tevent_req_error(req, EIO);

-         return;

+         ret = EIO;

+         goto fail;

  

      default:

          /* mark server as bad and retry */

          if (!state->srv) {

-             tevent_req_error(req, EFAULT);

-             return;

+             ret = EFAULT;

+             goto fail;

          }

          DEBUG(6, ("Couldn't resolve server (%s), resolver returned (%d)\n",

-                   fo_get_server_name(state->srv), ret));

+               fo_get_server_str_name(state->srv), ret));

  

          state->attempts++;

          if (state->attempts >= 10) {

              DEBUG(2, ("Failed to find a server after 10 attempts\n"));

-             tevent_req_error(req, EIO);

-             return;

+             ret = EIO;

+             goto fail;

          }

  

          /* now try next one */
@@ -440,8 +446,8 @@

                                           state->ctx->be_fo->fo_ctx,

                                           state->svc->fo_service);

          if (!subreq) {

-             tevent_req_error(req, ENOMEM);

-             return;

+             ret = ENOMEM;

+             goto fail;

          }

          tevent_req_set_callback(subreq, be_resolve_server_done, req);

  
@@ -449,22 +455,43 @@

      }

  

      /* all fine we got the server */

+     if (state->svc->first_resolved == NULL || state->first_try == true) {

+         DEBUG(7, ("Saving the first resolved server\n"));

+         state->svc->first_resolved = state->srv;

+     } else if (state->svc->first_resolved == state->srv) {

+         DEBUG(2, ("The fail over cycled through all available servers\n"));

+         ret = ENOENT;

+         goto fail;

+     }

  

-     if (debug_level >= 4) {

-         struct hostent *srvaddr;

+     if (debug_level >= 4 && fo_get_server_name(state->srv)) {

+         struct resolv_hostent *srvaddr;

          char ipaddr[128];

          srvaddr = fo_get_server_hostent(state->srv);

-         inet_ntop(srvaddr->h_addrtype, srvaddr->h_addr_list[0],

+         if (!srvaddr) {

+             DEBUG(3, ("FATAL: No hostent available for server (%s)\n",

+                       fo_get_server_str_name(state->srv)));

+             ret = EFAULT;

+             goto fail;

+         }

+ 

+         inet_ntop(srvaddr->family, srvaddr->addr_list[0]->ipaddr,

                    ipaddr, 128);

  

-         DEBUG(4, ("Found address for server %s: [%s]\n",

-                   fo_get_server_name(state->srv), ipaddr));

+         DEBUG(4, ("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 */

-     if (state->srv != state->svc->last_good_srv || state->svc->run_callbacks) {

+      * 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) {
@@ -473,6 +500,12 @@

      }

  

      tevent_req_done(req);

+     return;

+ 

+ fail:

+     DEBUG(7, ("Server resolution failed: %d\n", ret));

+     state->svc->first_resolved = NULL;

+     tevent_req_error(req, ret);

  }

  

  int be_resolve_server_recv(struct tevent_req *req, struct fo_server **srv)
@@ -519,3 +552,33 @@

      fo_reset_services(be_ctx->be_fo->fo_ctx);

  }

  

+ void be_fo_set_port_status(struct be_ctx *ctx,

+                            struct fo_server *server,

+                            enum port_status status)

+ {

+     struct be_svc_data *svc;

+     struct fo_service *fsvc;

+ 

+     fo_set_port_status(server, status);

+ 

+     fsvc = fo_get_server_service(server);

+     if (!fsvc) {

+         DEBUG(3, ("BUG: No service associated with server\n"));

+         return;

+     }

+ 

+     DLIST_FOR_EACH(svc, ctx->be_fo->svcs) {

+         if (svc->fo_service == fsvc) break;

+     }

+ 

+     if (!svc) {

+         DEBUG(3, ("BUG: Unknown service\n"));

+         return;

+     }

+ 

+     if (status == PORT_WORKING) {

+         /* We were successful in connecting to the server. Cycle through all

+          * available servers next time */

+         svc->first_resolved = NULL;

+     }

+ }

file modified
+4 -1
@@ -255,7 +255,10 @@

          dbus_message_iter_recurse(&struct_iter, &sub_iter);

          dbus_message_iter_get_fixed_array(&sub_iter, &data, &len);

  

-         pam_add_response(pd, type, len, data);

+         if (pam_add_response(pd, type, len, data) != EOK) {

+             DEBUG(1, ("pam_add_response failed.\n"));

+             return false;

+         }

          dbus_message_iter_next(&array_iter);

      }

  

file modified
+8 -1
@@ -93,6 +93,7 @@

      const char *identity;

      const char *conf_path;

      struct be_failover_ctx *be_fo;

+     struct sss_sigchild_ctx *sigchld_ctx;

  

      /* Functions to be invoked when the

       * backend goes online or offline
@@ -183,8 +184,14 @@

  struct tevent_req *be_resolve_server_send(TALLOC_CTX *memctx,

                                            struct tevent_context *ev,

                                            struct be_ctx *ctx,

-                                           const char *service_name);

+                                           const char *service_name,

+                                           bool first_try);

  int be_resolve_server_recv(struct tevent_req *req, struct fo_server **srv);

+ 

+ void be_fo_set_port_status(struct be_ctx *ctx,

+                            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

file modified
+50 -25
@@ -90,7 +90,7 @@

      struct server_common *next;

  

      char *name;

-     struct hostent *hostent;

+     struct resolv_hostent *rhostent;

      struct resolve_service_request *request_list;

      int server_status;

      struct timeval last_status_change;
@@ -314,16 +314,23 @@

                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) {

-         gettimeofday(&tv, NULL);

          if (STATUS_DIFF(server->common, tv) > timeout) {

              DEBUG(4, ("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 = 0;

+             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(4, ("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;

  }

  
@@ -487,7 +494,7 @@

      common->ctx = ctx;

      common->prev = NULL;

      common->next = NULL;

-     common->hostent = NULL;

+     common->rhostent = NULL;

      common->request_list = NULL;

      common->server_status = DEFAULT_SERVER_STATUS;

      common->last_status_change.tv_sec = 0;
@@ -836,7 +843,8 @@

          subreq = resolv_gethostbyname_send(state->server->common,

                                             state->ev, state->resolv,

                                             state->server->common->name,

-                                            state->fo_ctx->opts->family_order);

+                                            state->fo_ctx->opts->family_order,

+                                            default_host_dbs);

          if (subreq == NULL) {

              tevent_req_error(req, ENOMEM);

              return true;
@@ -873,13 +881,13 @@

      struct resolve_service_request *request;

      int ret;

  

-     if (state->server->common->hostent != NULL) {

-         talloc_zfree(state->server->common->hostent);

+     if (state->server->common->rhostent != NULL) {

+         talloc_zfree(state->server->common->rhostent);

      }

  

      ret = resolv_gethostbyname_recv(subreq, state->server->common,

                                      &resolv_status, NULL,

-                                     &state->server->common->hostent);

+                                     &state->server->common->rhostent);

      talloc_zfree(subreq);

      if (ret != EOK) {

          DEBUG(1, ("Failed to resolve server '%s': %s\n",
@@ -1122,15 +1130,6 @@

      }

  

      for (reply = reply_list; reply; reply = reply->next) {

-         ret = EOK;

-         DLIST_FOR_EACH(server, state->service->server_list) {

-             if (server->port == reply->port) {

-                 ret = EEXIST;

-                 break;

-             }

-         }

-         if (ret == EEXIST) continue;

- 

          server = create_fo_server(state->service, reply->host,

                                    reply->port, state->meta->user_data);

          if (!server) {
@@ -1223,7 +1222,8 @@

  

      subreq = resolv_gethostbyname_send(state, ev, resolv,

                                         state->hostname,

-                                        foctx->opts->family_order);

+                                        foctx->opts->family_order,

+                                        default_host_dbs);

      if (!subreq) {

          talloc_zfree(req);

          return NULL;
@@ -1239,10 +1239,10 @@

                                                        struct tevent_req);

      struct resolve_get_domain_state *state = tevent_req_data(req,

                                                        struct resolve_get_domain_state);

-     struct hostent *hostent;

+     struct resolv_hostent *rhostent;

      int ret;

  

-     ret = resolv_gethostbyname_recv(subreq, req, NULL, NULL, &hostent);

+     ret = resolv_gethostbyname_recv(subreq, req, NULL, NULL, &rhostent);

      talloc_zfree(subreq);

      if (ret) {

          DEBUG(2, ("Could not get fully qualified name for host name %s "
@@ -1250,8 +1250,8 @@

                    state->hostname, ret, strerror(ret)));

          /* We'll proceed with hostname in this case */

      } else {

-         DEBUG(7, ("The full FQDN is: %s\n", hostent->h_name));

-         state->fqdn = hostent->h_name;

+         DEBUG(7, ("The full FQDN is: %s\n", rhostent->name));

+         state->fqdn = rhostent->name;

      }

      tevent_req_done(req);

  }
@@ -1354,7 +1354,16 @@

      return server->port;

  }

  

- const char *fo_get_server_name(struct fo_server *server)

+ 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)) {
@@ -1366,14 +1375,24 @@

      return server->common->name;

  }

  

- struct hostent *

+ struct resolv_hostent *

  fo_get_server_hostent(struct fo_server *server)

  {

      if (server->common == NULL) {

          DEBUG(1, ("Bug: Trying to get hostent from a name-less server\n"));

          return NULL;

      }

-     return server->common->hostent;

+ 

+     return server->common->rhostent;

+ }

+ 

+ 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;

  }

  

  void fo_reset_services(struct fo_ctx *fo_ctx)
@@ -1392,3 +1411,9 @@

      }

  }

  

+ struct fo_service *

+ fo_get_server_service(struct fo_server *server)

+ {

+     if (!server) return NULL;

+     return server->service;

+ }

file modified
+8 -1
@@ -169,9 +169,16 @@

  

  const char *fo_get_server_name(struct fo_server *server);

  

- struct hostent *fo_get_server_hostent(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);

+ 

+ time_t fo_get_server_hostname_last_change(struct fo_server *server);

  

  int fo_is_srv_lookup(struct fo_server *s);

  

  void fo_reset_services(struct fo_ctx *fo_ctx);

+ 

+ struct fo_service *fo_get_server_service(struct fo_server *server);

+ 

  #endif /* !__FAIL_OVER_H__ */

@@ -0,0 +1,334 @@

+ /*

+     SSSD

+ 

+     IPA Backend Module -- Access control

+ 

+     Authors:

+         Sumit Bose <sbose@redhat.com>

+         Stephen Gallagher <sgallagh@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #include <stdlib.h>

+ #include <string.h>

+ #include <errno.h>

+ #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;

+             (*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);

+     info = NULL;

+ }

+ 

+ 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";

+     }

+ }

file modified
+479 -1722
@@ -27,1650 +27,151 @@

  

  #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_hbac_private.h"

  

- #define OBJECTCLASS "objectclass"

- #define IPA_MEMBEROF "memberOf"

- #define IPA_HOST_SERVERHOSTNAME "serverHostName"

- #define IPA_HOST_FQDN "fqdn"

- #define IPA_ACCESS_RULE_TYPE "accessRuleType"

- #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_UNIQUE_ID "ipauniqueid"

- #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_HOST_BASE_TMPL "cn=computers,cn=accounts,%s"

- #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_HOSTS_SUBDIR "hbac_hosts"

- #define HBAC_SERVICES_SUBDIR "hbac_services"

- 

- static char *get_hbac_search_base(TALLOC_CTX *mem_ctx,

-                                   struct dp_option *ipa_options)

- {

-     char *base;

-     int ret;

- 

-     base = dp_opt_get_string(ipa_options, IPA_HBAC_SEARCH_BASE);

-     if (base != NULL) {

-         return talloc_strdup(mem_ctx, base);

-     }

- 

-     DEBUG(9, ("ipa_hbac_search_base not available, trying base DN.\n"));

- 

-     ret = domain_to_basedn(mem_ctx,

-                            dp_opt_get_string(ipa_options, IPA_DOMAIN),

-                            &base);

-     if (ret != EOK) {

-         DEBUG(1, ("domain_to_basedn failed.\n"));

-         return NULL;

-     }

- 

-     return base;

- }

- 

- static errno_t msgs2attrs_array(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(1, ("talloc_array failed.\n"));

-         return ENOMEM;

-     }

- 

-     for (i = 0; i < count; i++) {

-         a[i] = talloc(a, struct sysdb_attrs);

-         if (a[i] == NULL) {

-             DEBUG(1, ("talloc_array 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;

- }

- 

- static 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(1, ("sysdb_attrs_replace_name failed.\n"));

-             return ret;

-         }

-     }

- 

-     return EOK;

- }

- 

- static errno_t hbac_sdap_data_recv(struct tevent_req *subreq,

-                                    TALLOC_CTX *mem_ctx, size_t *count,

-                                    struct sysdb_attrs ***attrs)

- {

-     int ret;

- 

-     ret = sdap_get_generic_recv(subreq, mem_ctx, count, attrs);

-     if (ret != EOK) {

-         DEBUG(1, ("sdap_get_generic_recv failed.\n"));

-         return ret;

-     }

- 

-     ret = replace_attribute_name(IPA_MEMBEROF, SYSDB_ORIG_MEMBEROF,

-                                  *count, *attrs);

-     if (ret != EOK) {

-         DEBUG(1, ("replace_attribute_name failed.\n"));

-         return ret;

-     }

- 

-     return EOK;

- }

- 

- static errno_t hbac_sysdb_data_recv(TALLOC_CTX *mem_ctx,

-                                     struct sysdb_ctx *sysdb,

-                                     struct sss_domain_info *domain,

-                                     const char *filter,

-                                     const char *subtree_name,

-                                     const char **search_attrs,

-                                     size_t *count,

-                                     struct sysdb_attrs ***reply_attrs)

- {

-     int ret;

-     struct ldb_message **msgs;

- 

-     ret = sysdb_search_custom(mem_ctx, sysdb, domain, filter, subtree_name,

-                               search_attrs, count, &msgs);

-     if (ret != EOK) {

-         if (ret == ENOENT) {

-             *count = 0;

-             *reply_attrs = NULL;

-             return EOK;

-         }

-         DEBUG(1, ("sysdb_search_custom failed.\n"));

-         return ret;

-     }

- 

-     ret = msgs2attrs_array(mem_ctx, *count, msgs, reply_attrs);

-     talloc_zfree(msgs);

-     if (ret != EOK) {

-         DEBUG(1, ("msgs2attrs_array failed.\n"));

-         return ret;

-     }

- 

-     return EOK;

- }

- 

- static errno_t set_local_and_remote_host_info(TALLOC_CTX *mem_ctx,

-                                               size_t host_count,

-                                               struct sysdb_attrs **host_list,

-                                               const char *local_hostname,

-                                               const char *remote_hostname,

-                                               struct hbac_host_info **local_hhi,

-                                               struct hbac_host_info **remote_hhi)

- 

- {

-     size_t c;

-     int ret;

-     struct hbac_host_info *hhi;

-     struct ldb_message_element *el;

-     TALLOC_CTX *tmp_ctx = NULL;

- 

-     if (local_hostname == NULL || *local_hostname == '\0') {

-         DEBUG(1, ("Missing local hostname.\n"));

-         ret = EINVAL;

-         goto done;

-     }

- 

-     if (host_count == 0) {

-         DEBUG(1, ("No host data available.\n"));

-         ret = EINVAL;

-         goto done;

-     }

- 

-     tmp_ctx = talloc_new(mem_ctx);

-     if (tmp_ctx == NULL) {

-         ret = ENOMEM;

-         goto done;

-     }

- 

-     for (c = 0; c < host_count; c++) {

-         hhi = talloc_zero(tmp_ctx, struct hbac_host_info);

-         if (hhi == NULL) {

-             DEBUG(1, ("talloc_zero failed.\n"));

-             ret = ENOMEM;

-             goto done;

-         }

- 

-         ret = sysdb_attrs_get_el(host_list[c], SYSDB_ORIG_DN, &el);

-         if (ret != EOK) {

-             DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-             goto done;

-         }

-         if (el->num_values == 0) {

-             DEBUG(1, ("Missing OriginalDN.\n"));

-             ret = EINVAL;

-             goto done;

-         }

-         DEBUG(9, ("OriginalDN: [%.*s].\n", el->values[0].length,

-                                            (char *)el->values[0].data));

-         hhi->dn = talloc_strndup(hhi, (char *)el->values[0].data,

-                                  el->values[0].length);

-         if (hhi->dn == NULL) {

-             DEBUG(1, ("talloc_strndup failed.\n"));

-             ret = ENOMEM;

-             goto done;

-         }

- 

-         ret = sysdb_attrs_get_el(host_list[c], IPA_HOST_SERVERHOSTNAME, &el);

-         if (ret != EOK) {

-             DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-             goto done;

-         }

-         if (el->num_values == 0) {

-             DEBUG(1, ("Missing ServerHostName.\n"));

-             ret = EINVAL;

-             goto done;

-         }

-         DEBUG(9, ("ServerHostName: [%.*s].\n", el->values[0].length,

-                                                (char *)el->values[0].data));

-         hhi->serverhostname = talloc_strndup(hhi, (char *)el->values[0].data,

-                                              el->values[0].length);

-         if (hhi->serverhostname == NULL) {

-             DEBUG(1, ("talloc_strndup failed.\n"));

-             ret = ENOMEM;

-             goto done;

-         }

- 

-         ret = sysdb_attrs_get_el(host_list[c], IPA_HOST_FQDN, &el);

-         if (ret != EOK) {

-             DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-             goto done;

-         }

-         if (el->num_values == 0) {

-             DEBUG(1, ("Missing FQDN.\n"));

-             ret = EINVAL;

-             goto done;

-         }

-         DEBUG(9, ("FQDN: [%.*s].\n", el->values[0].length,

-                                      (char *)el->values[0].data));

-         hhi->fqdn = talloc_strndup(hhi, (char *)el->values[0].data,

-                                    el->values[0].length);

-         if (hhi->fqdn == NULL) {

-             DEBUG(1, ("talloc_strndup failed.\n"));

-             ret = ENOMEM;

-             goto done;

-         }

- 

-         ret = sysdb_attrs_get_string_array(host_list[c], SYSDB_ORIG_MEMBEROF,

-                                            hhi, &hhi->memberof);

-         if (ret != EOK) {

-             if (ret != ENOENT) {

-                 DEBUG(1, ("sysdb_attrs_get_string_array failed.\n"));

-                 goto done;

-             }

- 

-             hhi->memberof = talloc_array(hhi, const char *, 1);

-             if (hhi->memberof == NULL) {

-                 DEBUG(1, ("talloc_array failed.\n"));

-                 ret = ENOMEM;

-                 goto done;

-             }

-             hhi->memberof[0] = NULL;

-         }

- 

-         if (strcmp(hhi->fqdn, local_hostname) == 0 ||

-             strcmp(hhi->serverhostname, local_hostname) == 0) {

-             *local_hhi = talloc_steal(mem_ctx, hhi);

-         }

- 

-         if (remote_hostname != NULL && *remote_hostname != '\0') {

-             if (strcmp(hhi->fqdn, remote_hostname) == 0 ||

-                 strcmp(hhi->serverhostname, remote_hostname) == 0) {

-                 *remote_hhi = talloc_steal(mem_ctx, hhi);

-             }

-         }

-     }

- 

-     ret = EOK;

- 

- done:

-     talloc_free(tmp_ctx);

-     return ret;

- }

- 

- 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->req_data, 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->fn(be_req, DP_ERR_OK, pam_status, NULL);

-     } else {

-         be_req->fn(be_req, DP_ERR_FATAL, pam_status, NULL);

-     }

- }

- 

- static errno_t hbac_save_list(struct sysdb_ctx *sysdb, bool delete_subdir,

-                               const char *subdir, struct sss_domain_info *domain,

-                               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(1, ("talloc_new failed.\n"));

-         return ENOMEM;

-     }

- 

-     if (delete_subdir) {

-         base_dn = sysdb_custom_subtree_dn(sysdb, tmp_ctx, domain->name, subdir);

-         if (base_dn == NULL) {

-             ret = ENOMEM;

-             goto done;

-         }

- 

-         ret = sysdb_delete_recursive(tmp_ctx, sysdb, base_dn, true);

-         if (ret != EOK) {

-             DEBUG(1, ("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(1, ("sysdb_attrs_get_el failed.\n"));

-             goto done;

-         }

-         if (el->num_values == 0) {

-             DEBUG(1, ("IPA_UNIQUE_ID not found.\n"));

-             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(1, ("talloc_strndup failed.\n"));

-             ret = ENOMEM;

-             goto done;

-         }

-         DEBUG(9, ("Object name: [%s].\n", object_name));

- 

-         ret = sysdb_store_custom(tmp_ctx, sysdb, domain, object_name, subdir,

-                                  list[c]);

-         if (ret != EOK) {

-             DEBUG(1, ("sysdb_store_custom failed.\n"));

-             goto done;

-         }

-     }

- 

-     ret = EOK;

- 

- done:

-     talloc_free(tmp_ctx);

-     return ret;

- }

- 

- static errno_t hbac_save_data_to_sysdb(struct hbac_ctx *hbac_ctx)

- {

-     int ret;

-     bool in_transaction = false;

-     struct sysdb_ctx *sysdb = hbac_ctx_sysdb(hbac_ctx);

-     struct sss_domain_info *domain = hbac_ctx_be(hbac_ctx)->domain;

- 

-     ret = sysdb_transaction_start(sysdb);

-     if (ret != EOK) {

-         DEBUG(1, ("sysdb_transaction_start failed.\n"));

-         return ret;

-     }

-     in_transaction = true;

- 

-     ret = hbac_save_list(sysdb, true, HBAC_SERVICES_SUBDIR, domain,

-                          IPA_UNIQUE_ID, hbac_ctx->hbac_services_count,

-                          hbac_ctx->hbac_services_list);

-     if (ret != EOK) {

-         DEBUG(1, ("hbac_save_list failed.\n"));

-         goto done;

-     }

- 

-     ret = hbac_save_list(sysdb, true, HBAC_RULES_SUBDIR, domain,

-                          IPA_UNIQUE_ID, hbac_ctx->hbac_rule_count,

-                          hbac_ctx->hbac_rule_list);

-     if (ret != EOK) {

-         DEBUG(1, ("hbac_save_list failed.\n"));

-         goto done;

-     }

- 

-     ret = hbac_save_list(sysdb, false, HBAC_HOSTS_SUBDIR, domain,

-                          IPA_HOST_FQDN, hbac_ctx->hbac_hosts_count,

-                          hbac_ctx->hbac_hosts_list);

-     if (ret != EOK) {

-         DEBUG(1, ("hbac_save_list failed.\n"));

-         goto done;

-     }

- 

-     ret = sysdb_transaction_commit(sysdb);

-     if (ret != EOK) {

-         DEBUG(1, ("sysdb_transaction_commit failed.\n"));

-         goto done;

-     }

-     in_transaction = false;

- 

-     ret = EOK;

- 

- done:

-     if (in_transaction) {

-         sysdb_transaction_cancel(sysdb);

-     }

-     return ret;

- }

- 

- struct hbac_get_service_data_state {

-     struct hbac_ctx *hbac_ctx;

-     bool offline;

- 

-     char *services_filter;

-     const char **services_attrs;

-     struct sysdb_attrs **services_reply_list;

-     size_t services_reply_count;

- 

-     size_t current_item;

- };

- 

- static void hbac_services_get_done(struct tevent_req *subreq);

- 

- struct tevent_req *hbac_get_service_data_send(TALLOC_CTX *memctx,

-                                               struct hbac_ctx *hbac_ctx)

- {

-     struct tevent_req *req = NULL;

-     struct tevent_req *subreq = NULL;

-     struct hbac_get_service_data_state *state;

-     struct sdap_handle *sdap_handle;

-     int ret;

- 

-     req = tevent_req_create(memctx, &state, struct hbac_get_service_data_state);

-     if (req == NULL) {

-         DEBUG(1, ("tevent_req_create failed.\n"));

-         return NULL;

-     }

- 

-     state->hbac_ctx = hbac_ctx;

- 

-     state->services_reply_list = NULL;

-     state->services_reply_count = 0;

- 

-     state->current_item = 0;

- 

-     state->services_attrs = talloc_array(state, const char *, 7);

-     if (state->services_attrs == NULL) {

-         DEBUG(1, ("Failed to allocate service attribute list.\n"));

-         ret = ENOMEM;

-         goto fail;

-     }

-     state->services_attrs[0] = IPA_CN;

-     state->services_attrs[1] = SYSDB_ORIG_DN;

-     state->services_attrs[2] = IPA_UNIQUE_ID;

-     state->services_attrs[3] = IPA_MEMBEROF;

-     state->services_attrs[4] = SYSDB_ORIG_MEMBEROF;

-     state->services_attrs[5] = OBJECTCLASS;

-     state->services_attrs[6] = NULL;

- 

-     state->services_filter = talloc_asprintf(state,

-                                             "(objectclass=ipaHBACService)");

-     if (state->services_filter == NULL) {

-         ret = ENOMEM;

-         goto fail;

-     }

- 

-     DEBUG(9, ("Services filter: [%s].\n", state->services_filter));

- 

-     if (hbac_ctx_is_offline(state->hbac_ctx)) {

-         ret = hbac_sysdb_data_recv(state,

-                                    hbac_ctx_sysdb(state->hbac_ctx),

-                                    hbac_ctx_be(state->hbac_ctx)->domain,

-                                    state->services_filter, HBAC_SERVICES_SUBDIR,

-                                    state->services_attrs,

-                                    &state->services_reply_count,

-                                    &state->services_reply_list);

-         if (ret) {

-             DEBUG(1, ("hbac_sysdb_data_recv failed.\n"));

-             goto fail;

-         }

- 

-         tevent_req_done(req);

-         tevent_req_post(req, hbac_ctx_ev(state->hbac_ctx));

-         return req;

-     }

- 

-     sdap_handle = sdap_id_op_handle(hbac_ctx_sdap_id_op(state->hbac_ctx));

-     if (sdap_handle == NULL) {

-         DEBUG(1, ("Bug: sdap_id_op is disconnected.\n"));

-         ret = EIO;

-         goto fail;

-     }

-     subreq = sdap_get_generic_send(state,

-                         hbac_ctx_ev(state->hbac_ctx),

-                         hbac_ctx_sdap_id_ctx(state->hbac_ctx)->opts,

-                         sdap_handle,

-                         state->hbac_ctx->hbac_search_base,

-                         LDAP_SCOPE_SUB,

-                         state->services_filter,

-                         state->services_attrs,

-                         NULL, 0,

-                         dp_opt_get_int(

-                              hbac_ctx_sdap_id_ctx(state->hbac_ctx)->opts->basic,

-                              SDAP_ENUM_SEARCH_TIMEOUT));

- 

-     if (subreq == NULL) {

-         DEBUG(1, ("sdap_get_generic_send failed.\n"));

-         ret = ENOMEM;

-         goto fail;

-     }

- 

-     tevent_req_set_callback(subreq, hbac_services_get_done, req);

- 

-     return req;

- 

- fail:

-     tevent_req_error(req, ret);

-     tevent_req_post(req, hbac_ctx_ev(state->hbac_ctx));

-     return req;

- }

- 

- static void hbac_services_get_done(struct tevent_req *subreq)

- {

-     struct tevent_req *req = tevent_req_callback_data(subreq,

-                                                       struct tevent_req);

-     struct hbac_get_service_data_state *state = tevent_req_data(req,

-                                             struct hbac_get_service_data_state);

-     int ret;

- 

-     ret = hbac_sdap_data_recv(subreq, state, &state->services_reply_count,

-                               &state->services_reply_list);

-     talloc_zfree(subreq);

-     if (ret != EOK) {

-         tevent_req_error(req, ret);

-         return;

-     }

- 

-     tevent_req_done(req);

-     return;

- }

- 

- static int hbac_get_service_data_recv(struct tevent_req *req,

-                                   TALLOC_CTX *memctx,

-                                   size_t *hbac_services_count,

-                                   struct sysdb_attrs ***hbac_services_list)

- {

-     struct hbac_get_service_data_state *state = tevent_req_data(req,

-                                             struct hbac_get_service_data_state);

-     int i;

- 

-     TEVENT_REQ_RETURN_ON_ERROR(req);

- 

-     *hbac_services_count = state->services_reply_count;

-     *hbac_services_list = talloc_steal(memctx, state->services_reply_list);

-     for (i = 0; i < state->services_reply_count; i++) {

-         talloc_steal(memctx, state->services_reply_list[i]);

-     }

- 

-     return EOK;

- }

- 

- static int hbac_get_user_info(TALLOC_CTX *memctx,

-                               struct be_ctx *be_ctx,

-                               const char *user,

-                               const char **user_dn,

-                               size_t *groups_count,

-                               const char ***_groups)

- {

-     TALLOC_CTX *tmpctx;

-     const char *attrs[] = { SYSDB_ORIG_DN, NULL };

-     struct ldb_message *user_msg;

-     const char *user_orig_dn;

-     struct ldb_message **msgs;

-     size_t count;

-     const char **groups;

-     int ret;

-     int i;

- 

-     tmpctx = talloc_new(memctx);

-     if (!tmpctx) {

-         return ENOMEM;

-     }

- 

-     ret = sysdb_search_user_by_name(tmpctx, be_ctx->sysdb,

-                                     be_ctx->domain, user, attrs, &user_msg);

-     if (ret != EOK) {

-         goto fail;

-     }

- 

-     DEBUG(9, ("Found user info for user [%s].\n", user));

-     user_orig_dn = ldb_msg_find_attr_as_string(user_msg, SYSDB_ORIG_DN, NULL);

-     if (user_orig_dn == NULL) {

-         DEBUG(1, ("Original DN of user [%s] not available.\n", user));

-         ret = EINVAL;

-         goto fail;

-     }

-     DEBUG(9, ("Found original DN [%s] for user [%s].\n",

-               user_orig_dn, user));

- 

-     ret = sysdb_asq_search(tmpctx, be_ctx->sysdb, be_ctx->domain,

-                            user_msg->dn, NULL, SYSDB_MEMBEROF, attrs,

-                            &count, &msgs);

-     if (ret != EOK) {

-         DEBUG(1, ("sysdb_asq_search on user %s failed.\n", user));

-         goto fail;

-     }

- 

-     if (count == 0) {

-         *user_dn = talloc_strdup(memctx, user_orig_dn);

-         if (*user_dn == NULL) {

-             ret = ENOMEM;

-             goto fail;

-         }

-         *groups_count = 0;

-         *_groups = NULL;

-         talloc_zfree(tmpctx);

-         return EOK;

-     }

- 

-     groups = talloc_array(tmpctx, const char *, count);

-     if (groups == NULL) {

-         DEBUG(1, ("talloc_groups failed.\n"));

-         ret = ENOMEM;

-         goto fail;

-     }

- 

-     for(i = 0; i < count; i++) {

-         if (msgs[i]->num_elements != 1) {

-             DEBUG(1, ("Unexpected number of elements.\n"));

-             ret = EINVAL;

-             goto fail;

-         }

- 

-         if (msgs[i]->elements[0].num_values != 1) {

-             DEBUG(1, ("Unexpected number of values.\n"));

-             ret = EINVAL;

-             goto fail;

-         }

- 

-         groups[i] = talloc_strndup(groups,

-                         (const char *)msgs[i]->elements[0].values[0].data,

-                         msgs[i]->elements[0].values[0].length);

-         if (groups[i] == NULL) {

-             DEBUG(1, ("talloc_strndup failed.\n"));

-             ret = ENOMEM;

-             goto fail;

-         }

- 

-         DEBUG(9, ("Found group [%s].\n", groups[i]));

-     }

- 

-     *user_dn = talloc_strdup(memctx, user_orig_dn);

-     if (*user_dn == NULL) {

-         ret = ENOMEM;

-         goto fail;

-     }

-     *groups_count = count;

-     *_groups = talloc_steal(memctx, groups);

- 

-     talloc_zfree(tmpctx);

-     return EOK;

- 

- fail:

-     DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));

-     talloc_zfree(tmpctx);

-     return ret;

- }

- 

- 

- struct hbac_get_host_info_state {

-     struct hbac_ctx *hbac_ctx;

- 

-     char *host_filter;

-     const char **host_attrs;

- 

-     struct sysdb_attrs **host_reply_list;

-     size_t host_reply_count;

-     size_t current_item;

-     struct hbac_host_info **hbac_host_info;

- };

- 

- static void hbac_get_host_memberof(struct tevent_req *req, bool offline);

- static void hbac_get_host_memberof_done(struct tevent_req *subreq);

- 

- static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx,

-                                                   struct hbac_ctx *hbac_ctx,

-                                                   const char **hostnames)

- {

-     struct tevent_req *req = NULL;

-     struct tevent_req *subreq = NULL;

-     struct hbac_get_host_info_state *state;

-     struct sdap_handle *sdap_handle;

-     char *host;

-     int ret;

-     int i;

- 

-     if (hostnames == NULL) {

-         DEBUG(1, ("Missing hostnames.\n"));

-         return NULL;

-     }

- 

-     req = tevent_req_create(memctx, &state, struct hbac_get_host_info_state);

-     if (req == NULL) {

-         DEBUG(1, ("tevent_req_create failed.\n"));

-         return NULL;

-     }

- 

-     state->hbac_ctx = hbac_ctx;

- 

-     state->host_reply_list = NULL;

-     state->host_reply_count = 0;

-     state->current_item = 0;

-     state->hbac_host_info = NULL;

- 

-     state->host_filter = talloc_asprintf(state, "(&(objectclass=ipaHost)(|");

-     if (state->host_filter == NULL) {

-         DEBUG(1, ("Failed to create filter.\n"));

-         ret = ENOMEM;

-         goto fail;

-     }

-     for (i = 0; hostnames[i] != NULL; i++) {

-         ret = sss_filter_sanitize(state->host_filter, hostnames[i], &host);

-         if (ret != EOK) {

-             goto fail;

-         }

- 

-         state->host_filter = talloc_asprintf_append(state->host_filter,

-                                          "(%s=%s)(%s=%s)",

-                                          IPA_HOST_FQDN, host,

-                                          IPA_HOST_SERVERHOSTNAME, host);

- 

-         if (state->host_filter == NULL) {

-             ret = ENOMEM;

-             goto fail;

-         }

-         talloc_zfree(host);

-     }

-     state->host_filter = talloc_asprintf_append(state->host_filter, "))");

-     if (state->host_filter == NULL) {

-         ret = ENOMEM;

-         goto fail;

-     }

- 

-     state->host_attrs = talloc_array(state, const char *, 8);

-     if (state->host_attrs == NULL) {

-         DEBUG(1, ("Failed to allocate host attribute list.\n"));

-         ret = ENOMEM;

-         goto fail;

-     }

-     state->host_attrs[0] = IPA_MEMBEROF;

-     state->host_attrs[1] = IPA_HOST_SERVERHOSTNAME;

-     state->host_attrs[2] = IPA_HOST_FQDN;

-     state->host_attrs[3] = "objectClass";

-     state->host_attrs[4] = SYSDB_ORIG_DN;

-     state->host_attrs[5] = SYSDB_ORIG_MEMBEROF;

-     state->host_attrs[6] = IPA_UNIQUE_ID;

-     state->host_attrs[7] = NULL;

- 

-     if (hbac_ctx_is_offline(state->hbac_ctx)) {

-         ret = hbac_sysdb_data_recv(state, hbac_ctx_sysdb(state->hbac_ctx),

-                                    hbac_ctx_be(state->hbac_ctx)->domain,

-                                    state->host_filter, HBAC_HOSTS_SUBDIR,

-                                    state->host_attrs,

-                                    &state->host_reply_count,

-                                    &state->host_reply_list);

-         if (ret != EOK) {

-             DEBUG(1, ("hbac_sysdb_data_recv failed.\n"));

-             goto fail;

-         }

-         hbac_get_host_memberof(req, true);

-         tevent_req_post(req, hbac_ctx_ev(state->hbac_ctx));

-         return req;

-     }

- 

-     sdap_handle = sdap_id_op_handle(hbac_ctx_sdap_id_op(state->hbac_ctx));

-     if (sdap_handle == NULL) {

-         DEBUG(1, ("Bug: sdap_id_op is disconnected.\n"));

-         ret = EIO;

-         goto fail;

-     }

-     subreq = sdap_get_generic_send(state, hbac_ctx_ev(state->hbac_ctx),

-                         hbac_ctx_sdap_id_ctx(state->hbac_ctx)->opts,

-                         sdap_handle,

-                         state->hbac_ctx->hbac_search_base,

-                         LDAP_SCOPE_SUB,

-                         state->host_filter,

-                         state->host_attrs,

-                         NULL, 0,

-                         dp_opt_get_int(

-                              hbac_ctx_sdap_id_ctx(state->hbac_ctx)->opts->basic,

-                              SDAP_ENUM_SEARCH_TIMEOUT));

- 

-     if (subreq == NULL) {

-         DEBUG(1, ("sdap_get_generic_send failed.\n"));

-         ret = ENOMEM;

-         goto fail;

-     }

- 

-     tevent_req_set_callback(subreq, hbac_get_host_memberof_done, req);

- 

-     return req;

- 

- fail:

-     tevent_req_error(req, ret);

-     tevent_req_post(req, hbac_ctx_ev(state->hbac_ctx));

-     return req;

- }

- 

- static void hbac_get_host_memberof_done(struct tevent_req *subreq)

- {

-     struct tevent_req *req = tevent_req_callback_data(subreq,

-                                                       struct tevent_req);

-     struct hbac_get_host_info_state *state = tevent_req_data(req,

-                                                struct hbac_get_host_info_state);

-     int ret;

- 

-     ret = hbac_sdap_data_recv(subreq, state, &state->host_reply_count,

-                               &state->host_reply_list);

-     talloc_zfree(subreq);

-     if (ret != EOK) {

-         tevent_req_error(req, ret);

-         return;

-     }

- 

-     hbac_get_host_memberof(req, false);

- }

- 

- static bool hbac_is_known_host(size_t host_reply_count,

-                                struct sysdb_attrs **host_reply_list,

-                                const char *fqdn)

- {

-     int i;

-     const char *new_fqdn;

-     int ret;

- 

-     if (!host_reply_list || !fqdn) {

-         return false;

-     }

- 

-     for (i = 0; i < host_reply_count; i++) {

-         ret = sysdb_attrs_get_string(host_reply_list[i], IPA_HOST_FQDN,

-                                      &new_fqdn);

-         if (ret != 0) {

-             DEBUG(1, ("missing FQDN in new HBAC host record\n"));

-             continue;

-         }

- 

-         if(strcmp(new_fqdn, fqdn) == 0) {

-             return true;

-         }

-     }

- 

-     return false;

- }

- 

- static void hbac_get_host_memberof(struct tevent_req *req, bool offline)

- {

-     struct hbac_get_host_info_state *state =

-                     tevent_req_data(req, struct hbac_get_host_info_state);

-     struct sysdb_ctx *sysdb;

-     struct sss_domain_info *domain;

-     bool in_transaction = false;

-     int ret;

-     int i;

-     const char *fqdn_attrs[] = { IPA_HOST_FQDN, NULL };

-     const char *fqdn;

- 

-     size_t cached_count;

-     struct ldb_message **cached_entries = 0;

- 

-     if (offline) {

-         tevent_req_done(req);

-         return;

-     }

- 

-     sysdb = hbac_ctx_sysdb(state->hbac_ctx);

-     domain = hbac_ctx_be(state->hbac_ctx)->domain;

- 

-     ret = sysdb_transaction_start(sysdb);

-     if (ret != EOK) {

-         tevent_req_error(req, ret);

-         return;

-     }

-     in_transaction = true;

- 

-     ret = sysdb_search_custom(state, sysdb, domain,

-                               state->host_filter, HBAC_HOSTS_SUBDIR,

-                               fqdn_attrs,

-                               &cached_count,

-                               &cached_entries);

- 

-     if (ret == ENOENT) {

-         cached_count = 0;

-         ret = EOK;

-     }

- 

-     if (ret) {

-         DEBUG(1, ("sysdb_search_custom failed: [%d](%s)\n", ret, strerror(ret)));

-         goto fail;

-     }

- 

-     for (i = 0; i < cached_count; i++) {

-         fqdn = ldb_msg_find_attr_as_string(cached_entries[i], IPA_HOST_FQDN, NULL);

-         if (!fqdn) {

-             DEBUG(1, ("missing FQDN in cached HBAC host record\n"));

-         } else if (hbac_is_known_host(state->host_reply_count,

-                                       state->host_reply_list, fqdn)) {

-             continue;

-         } else {

-             DEBUG(9, ("deleting obsolete HBAC host record for %s\n", fqdn));

-         }

- 

-         ret = sysdb_delete_entry(sysdb, cached_entries[i]->dn, true);

-         if (ret) {

-             DEBUG(1, ("sysdb_delete_entry failed: [%d](%s)\n", ret, strerror(ret)));

-             goto fail;

-         }

-     }

- 

-     talloc_zfree(cached_entries);

- 

-     ret = sysdb_transaction_commit(sysdb);

-     if (ret) {

-         DEBUG(1, ("sysdb_transaction_commit failed.\n"));

-         goto fail;

-     }

-     in_transaction = false;

- 

-     tevent_req_done(req);

-     return;

- 

- fail:

-     talloc_zfree(cached_entries);

- 

-     if (in_transaction) {

-         sysdb_transaction_cancel(sysdb);

-     }

-     tevent_req_error(req, ret);

-     return;

- }

- 

- static int hbac_get_host_info_recv(struct tevent_req *req, TALLOC_CTX *memctx,

-                                    size_t *hbac_hosts_count,

-                                    struct sysdb_attrs ***hbac_hosts_list)

- {

-     size_t c;

-     struct hbac_get_host_info_state *state = tevent_req_data(req,

-                                                struct hbac_get_host_info_state);

- 

-     TEVENT_REQ_RETURN_ON_ERROR(req);

- 

-     *hbac_hosts_count = state->host_reply_count;

-     *hbac_hosts_list = talloc_steal(memctx, state->host_reply_list);

-     for (c = 0; c < state->host_reply_count; c++) {

-         talloc_steal(memctx, state->host_reply_list[c]);

-     }

- 

-     return EOK;

- }

- 

- 

- struct hbac_get_rules_state {

-     struct hbac_ctx *hbac_ctx;

- 

-     const char *host_dn;

-     const char **memberof;

-     char *hbac_filter;

-     const char **hbac_attrs;

- 

-     struct ldb_message *old_rules;

-     struct sysdb_attrs **hbac_reply_list;

-     size_t hbac_reply_count;

-     int current_item;

- };

- 

- static void hbac_rule_get_done(struct tevent_req *subreq);

- 

- static struct tevent_req *hbac_get_rules_send(TALLOC_CTX *memctx,

-                                               struct hbac_ctx *hbac_ctx,

-                                               const char *host_dn,

-                                               const char **memberof)

- {

-     struct tevent_req *req = NULL;

-     struct tevent_req *subreq = NULL;

-     struct hbac_get_rules_state *state;

-     struct sdap_handle *sdap_handle;

-     char *host_dn_clean;

-     int ret;

-     int i;

- 

-     if (host_dn == NULL) {

-         DEBUG(1, ("Missing host_dn.\n"));

-         return NULL;

-     }

- 

-     req = tevent_req_create(memctx, &state, struct hbac_get_rules_state);

-     if (req == NULL) {

-         DEBUG(1, ("tevent_req_create failed.\n"));

-         return NULL;

-     }

- 

-     state->hbac_ctx = hbac_ctx;

-     state->host_dn = host_dn;

-     state->memberof = memberof;

- 

-     state->old_rules = NULL;

-     state->hbac_reply_list = NULL;

-     state->hbac_reply_count = 0;

-     state->current_item = 0;

- 

-     state->hbac_attrs = talloc_array(state, const char *, 17);

-     if (state->hbac_attrs == NULL) {

-         DEBUG(1, ("Failed to allocate HBAC attribute list.\n"));

-         ret = ENOMEM;

-         goto fail;

-     }

-     state->hbac_attrs[0] = IPA_ACCESS_RULE_TYPE;

-     state->hbac_attrs[1] = IPA_MEMBER_USER;

-     state->hbac_attrs[2] = IPA_USER_CATEGORY;

-     state->hbac_attrs[3] = IPA_SERVICE_NAME;

-     state->hbac_attrs[4] = IPA_SOURCE_HOST;

-     state->hbac_attrs[5] = IPA_SOURCE_HOST_CATEGORY;

-     state->hbac_attrs[6] = IPA_EXTERNAL_HOST;

-     state->hbac_attrs[7] = IPA_UNIQUE_ID;

-     state->hbac_attrs[8] = IPA_ENABLED_FLAG;

-     state->hbac_attrs[9] = IPA_CN;

-     state->hbac_attrs[10] = OBJECTCLASS;

-     state->hbac_attrs[11] = IPA_MEMBER_HOST;

-     state->hbac_attrs[12] = IPA_HOST_CATEGORY;

-     state->hbac_attrs[13] = IPA_MEMBER_SERVICE;

-     state->hbac_attrs[14] = IPA_SERVICE_CATEGORY;

-     state->hbac_attrs[15] = SYSDB_ORIG_DN;

-     state->hbac_attrs[16] = NULL;

- 

-     ret = sss_filter_sanitize(state, host_dn, &host_dn_clean);

-     if (ret != EOK) {

-         goto fail;

-     }

- 

-     state->hbac_filter = talloc_asprintf(state,

-                                          "(&(objectclass=ipaHBACRule)"

-                                          "(%s=%s)(|(%s=%s)(%s=%s)",

-                                          IPA_ENABLED_FLAG, IPA_TRUE_VALUE,

-                                          IPA_HOST_CATEGORY, "all",

-                                          IPA_MEMBER_HOST, host_dn_clean);

-     if (state->hbac_filter == NULL) {

-         ret = ENOMEM;

-         goto fail;

-     }

-     talloc_zfree(host_dn_clean);

- 

-     for (i = 0; memberof[i] != NULL; i++) {

-         state->hbac_filter = talloc_asprintf_append(state->hbac_filter,

-                                                     "(%s=%s)",

-                                                     IPA_MEMBER_HOST,

-                                                     memberof[i]);

-         if (state->hbac_filter == NULL) {

-             ret = ENOMEM;

-             goto fail;

-         }

-     }

-     state->hbac_filter = talloc_asprintf_append(state->hbac_filter, "))");

-     if (state->hbac_filter == NULL) {

-         ret = ENOMEM;

-         goto fail;

-     }

- 

-     DEBUG(9, ("HBAC rule filter: [%s].\n", state->hbac_filter));

- 

-     if (hbac_ctx_is_offline(state->hbac_ctx)) {

-         ret = hbac_sysdb_data_recv(state, hbac_ctx_sysdb(state->hbac_ctx),

-                                    hbac_ctx_be(state->hbac_ctx)->domain,

-                                    state->hbac_filter, HBAC_RULES_SUBDIR,

-                                    state->hbac_attrs,

-                                    &state->hbac_reply_count,

-                                    &state->hbac_reply_list);

-         if (ret) {

-             DEBUG(1, ("hbac_sysdb_data_recv failed.\n"));

-             goto fail;

-         }

-         tevent_req_done(req);

-         tevent_req_post(req, hbac_ctx_ev(state->hbac_ctx));

-         return req;

-     }

- 

-     sdap_handle = sdap_id_op_handle(hbac_ctx_sdap_id_op(state->hbac_ctx));

-     if (sdap_handle == NULL) {

-         DEBUG(1, ("Bug: sdap_id_op is disconnected.\n"));

-         ret = EIO;

-         goto fail;

-     }

-     subreq = sdap_get_generic_send(state, hbac_ctx_ev(state->hbac_ctx),

-                         hbac_ctx_sdap_id_ctx(state->hbac_ctx)->opts,

-                         sdap_handle,

-                         state->hbac_ctx->hbac_search_base,

-                         LDAP_SCOPE_SUB,

-                         state->hbac_filter,

-                         state->hbac_attrs,

-                         NULL, 0,

-                         dp_opt_get_int(

-                              hbac_ctx_sdap_id_ctx(state->hbac_ctx)->opts->basic,

-                              SDAP_ENUM_SEARCH_TIMEOUT));

- 

-     if (subreq == NULL) {

-         DEBUG(1, ("sdap_get_generic_send failed.\n"));

-         ret = ENOMEM;

-         goto fail;

-     }

- 

-     tevent_req_set_callback(subreq, hbac_rule_get_done, req);

- 

-     return req;

- 

- fail:

-     tevent_req_error(req, ret);

-     tevent_req_post(req, hbac_ctx_ev(state->hbac_ctx));

-     return req;

- }

- 

- static void hbac_rule_get_done(struct tevent_req *subreq)

- {

-     struct tevent_req *req = tevent_req_callback_data(subreq,

-                                                       struct tevent_req);

-     struct hbac_get_rules_state *state = tevent_req_data(req,

-                                                      struct hbac_get_rules_state);

-     int ret;

- 

-     ret = hbac_sdap_data_recv(subreq, state, &state->hbac_reply_count,

-                               &state->hbac_reply_list);

-     talloc_zfree(subreq);

-     if (ret != EOK) {

-         tevent_req_error(req, ret);

-         return;

-     }

- 

-     tevent_req_done(req);

-     return;

- }

- 

- static int hbac_get_rules_recv(struct tevent_req *req, TALLOC_CTX *memctx,

-                                size_t *hbac_rule_count,

-                                struct sysdb_attrs ***hbac_rule_list)

- {

-     struct hbac_get_rules_state *state = tevent_req_data(req,

-                                                      struct hbac_get_rules_state);

- 

-     TEVENT_REQ_RETURN_ON_ERROR(req);

- 

-     *hbac_rule_count = state->hbac_reply_count;

-     *hbac_rule_list = talloc_steal(memctx, state->hbac_reply_list);

-     /* we do not need to steal each hbac_reply_list[i]

-      * as it belongs to hbac_reply_list memory block */

-     return EOK;

- }

- 

- enum hbac_result {

-     HBAC_ALLOW = 1,

-     HBAC_DENY,

-     HBAC_NOT_APPLICABLE

- };

- 

- enum check_result {

-     RULE_APPLICABLE = 0,

-     RULE_NOT_APPLICABLE,

-     RULE_ERROR

- };

- 

- static errno_t get_service_data(const char *cn, size_t count,

-                                 struct sysdb_attrs **list, const char **dn,

-                                 struct ldb_message_element **mof)

- {

-     int ret;

-     int i;

-     int j;

-     struct ldb_message_element *el;

- 

-     for (i = 0; i < count; i++) {

-         ret = sysdb_attrs_get_el(list[i], IPA_CN, &el);

-         if (ret != EOK) {

-             DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-             return ENOENT;

-         }

-         if (el->num_values == 0) {

-             DEBUG(9, ("No cn found.\n"));

-             return ENOENT;

-         } else {

-             for (j = 0; j < el->num_values; j++) {

-                 if (strlen(cn) == el->values[j].length &&

-                     strncmp(cn, (const char *) el->values[j].data,

-                             el->values[j].length) == 0) {

- 

-                     ret = sysdb_attrs_get_string(list[i], SYSDB_ORIG_DN, dn);

-                     if (ret != EOK) {

-                         DEBUG(1, ("sysdb_attrs_get_string failed.\n"));

-                         return ret;

-                     }

- 

-                     ret = sysdb_attrs_get_el(list[i], SYSDB_ORIG_MEMBEROF, mof);

-                     if (ret != EOK) {

-                         DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-                         return ret;

-                     }

- 

-                     return EOK;

-                 }

-             }

-         }

-     }

- 

-     return ENOENT;

- }

- 

- enum check_result check_service(struct hbac_ctx *hbac_ctx,

-                                 struct sysdb_attrs *rule_attrs)

- {

-     int ret;

-     int i;

-     int g;

-     struct ldb_message_element *el;

-     const char *service_dn;

-     struct ldb_message_element *service_memberof;

- 

-     if (hbac_ctx->pd->service == NULL) {

-         DEBUG(1, ("No service in pam data, assuming error.\n"));

-         return RULE_ERROR;

-     }

- 

-     ret = sysdb_attrs_get_el(rule_attrs, IPA_SERVICE_CATEGORY, &el);

-     if (ret != EOK) {

-         DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-         return RULE_ERROR;

-     }

-     if (el->num_values == 0) {

-         DEBUG(9, ("Service category is not set.\n"));

-     } else {

-         for (i = 0; i < el->num_values; i++) {

-             if (strncasecmp("all", (const char *) el->values[i].data,

-                             el->values[i].length) == 0) {

-                 DEBUG(9, ("Service category is set to 'all', rule applies.\n"));

-                 return RULE_APPLICABLE;

-             }

-             DEBUG(9, ("Unsupported service category [%.*s].\n",

-                       el->values[i].length,

-                       (char *) el->values[i].data));

-         }

-     }

- 

-     ret = get_service_data(hbac_ctx->pd->service, hbac_ctx->hbac_services_count,

-                            hbac_ctx->hbac_services_list, &service_dn,

-                            &service_memberof);

-     if (ret != EOK) {

-         DEBUG(1, ("Cannot find original DN for service [%s].\n",

-                   hbac_ctx->pd->service));

-         return RULE_ERROR;

-     }

-     DEBUG(9, ("OriginalDN for service [%s]: [%s].\n", hbac_ctx->pd->service,

-               service_dn));

- 

-     ret = sysdb_attrs_get_el(rule_attrs, IPA_MEMBER_SERVICE, &el);

-     if (ret != EOK) {

-         DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-         return RULE_ERROR;

-     }

-     if (el->num_values == 0) {

-         DEBUG(9, ("No service or service group specified, rule does not apply.\n"));

-         return RULE_NOT_APPLICABLE;

-     }

- 

-     for (i = 0; i < el->num_values; i++) {

-         if (strncmp(service_dn, (const char *) el->values[i].data,

-                     el->values[i].length) == 0) {

-             DEBUG(9, ("Service [%s] found in the list of allowed "

-                       "services.\n", hbac_ctx->pd->service));

-             return RULE_APPLICABLE;

-         }

- 

-         for (g = 0; g < service_memberof->num_values; g++) {

-             if (service_memberof->values[g].length == el->values[i].length &&

-                 strncmp((const char *) service_memberof->values[g].data,

-                         (const char *) el->values[i].data,

-                         el->values[i].length) == 0) {

-                 DEBUG(9, ("Service [%s] is a member of a group in the list of "

-                           "allowed service groups.\n", hbac_ctx->pd->service));

-                 return RULE_APPLICABLE;

-             }

-         }

-     }

- 

-     DEBUG(9, ("Service [%s] was not found in the list of allowed services and "

-               "service groups.\n", hbac_ctx->pd->service));

-     return RULE_NOT_APPLICABLE;

- }

- 

- enum check_result check_user(struct hbac_ctx *hbac_ctx,

-                              struct sysdb_attrs *rule_attrs)

- {

-     int ret;

-     int i;

-     int g;

-     struct ldb_message_element *el;

- 

-     if (hbac_ctx->user_dn == NULL) {

-         DEBUG(1, ("No user DN available, this should never happen.\n"));

-         return RULE_ERROR;

-     }

- 

-     ret = sysdb_attrs_get_el(rule_attrs, IPA_USER_CATEGORY, &el);

-     if (ret != EOK) {

-         DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-         return RULE_ERROR;

-     }

-     if (el->num_values == 0) {

-         DEBUG(9, ("User category is not set.\n"));

-     } else {

-         for (i = 0; i < el->num_values; i++) {

-             if (strncasecmp("all", (const char *) el->values[i].data,

-                             el->values[i].length) == 0) {

-                 DEBUG(9, ("User category is set to 'all', rule applies.\n"));

-                 return RULE_APPLICABLE;

-             }

-             DEBUG(9, ("Unsupported user category [%.*s].\n",

-                       el->values[i].length,

-                       (char *) el->values[i].data));

-         }

-     }

- 

-     ret = sysdb_attrs_get_el(rule_attrs, IPA_MEMBER_USER, &el);

-     if (ret != EOK) {

-         DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-         return RULE_ERROR;

-     }

-     if (el->num_values == 0) {

-         DEBUG(9, ("No user specified, rule does not apply.\n"));

-         return RULE_NOT_APPLICABLE;

-     } else {

-         for (i = 0; i < el->num_values; i++) {

-             DEBUG(9, ("Searching matches for [%.*s].\n", el->values[i].length,

-                                            (const char *) el->values[i].data));

-             DEBUG(9, ("Checking user [%s].\n", hbac_ctx->user_dn));

-             if (strncmp(hbac_ctx->user_dn, (const char *) el->values[i].data,

-                        el->values[i].length) == 0) {

-                 DEBUG(9, ("User [%s] found, rule applies.\n",

-                           hbac_ctx->user_dn));

-                 return RULE_APPLICABLE;

-             }

- 

-             for (g = 0; g < hbac_ctx->groups_count; g++) {

-                 DEBUG(9, ("Checking group [%s].\n", hbac_ctx->groups[g]));

-                 if (strncmp(hbac_ctx->groups[g],

-                            (const char *) el->values[i].data,

-                            el->values[i].length) == 0) {

-                     DEBUG(9, ("Group [%s] found, rule applies.\n",

-                               hbac_ctx->groups[g]));

-                     return RULE_APPLICABLE;

-                 }

-             }

-         }

-         DEBUG(9, ("No matching user found, rule does not apply.\n"));

-         return RULE_NOT_APPLICABLE;

-     }

- 

-     return RULE_ERROR;

- }

- 

- enum check_result check_remote_hosts(const char *rhost,

-                                      struct hbac_host_info *hhi,

-                                      struct sysdb_attrs *rule_attrs)

- {

-     int ret;

-     int i;

-     int m;

-     struct ldb_message_element *cat_el;

-     struct ldb_message_element *src_el;

-     struct ldb_message_element *ext_el;

- 

-     if (hhi == NULL && (rhost == NULL || *rhost == '\0')) {

-         DEBUG(1, ("No remote host information specified, assuming error.\n"));

-         return RULE_ERROR;

-     }

- 

-     ret = sysdb_attrs_get_el(rule_attrs, IPA_SOURCE_HOST_CATEGORY, &cat_el);

-     if (ret != EOK) {

-         DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-         return RULE_ERROR;

-     }

-     if (cat_el->num_values == 0) {

-         DEBUG(9, ("Source host category not set.\n"));

-     } else {

-         for(i = 0; i < cat_el->num_values; i++) {

-             if (strncasecmp("all", (const char *) cat_el->values[i].data,

-                             cat_el->values[i].length) == 0) {

-                 DEBUG(9, ("Source host category is set to 'all', "

-                           "rule applies.\n"));

-                 return RULE_APPLICABLE;

-             }

-             DEBUG(9, ("Unsupported source hosts category [%.*s].\n",

-                       cat_el->values[i].length,

-                       (char *) cat_el->values[i].data));

-         }

-     }

- 

-     ret = sysdb_attrs_get_el(rule_attrs, IPA_SOURCE_HOST, &src_el);

-     if (ret != EOK) {

-         DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-         return RULE_ERROR;

-     }

-     ret = sysdb_attrs_get_el(rule_attrs, IPA_EXTERNAL_HOST, &ext_el);

-     if (ret != EOK) {

-         DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-         return RULE_ERROR;

-     }

- 

-     if (src_el->num_values == 0 && ext_el->num_values == 0) {

-         DEBUG(9, ("No remote host specified in rule, rule does not apply.\n"));

-         return RULE_NOT_APPLICABLE;

-     } else {

-         if (hhi != NULL) {

-             for (i = 0; i < src_el->num_values; i++) {

-                 if (strncasecmp(hhi->dn, (const char *) src_el->values[i].data,

-                                 src_el->values[i].length) == 0) {

-                     DEBUG(9, ("Source host [%s] found, rule applies.\n",

-                               hhi->dn));

-                     return RULE_APPLICABLE;

-                 }

-                 for (m = 0; hhi->memberof[m] != NULL; m++) {

-                     if (strncasecmp(hhi->memberof[m],

-                                     (const char *) src_el->values[i].data,

-                                     src_el->values[i].length) == 0) {

-                         DEBUG(9, ("Source host group [%s] found, rule applies.\n",

-                                   hhi->memberof[m]));

-                         return RULE_APPLICABLE;

-                     }

-                 }

-             }

-         }

- 

-         if (rhost != NULL && *rhost != '\0') {

-             for (i = 0; i < ext_el->num_values; i++) {

-                 if (strncasecmp(rhost, (const char *) ext_el->values[i].data,

-                                 ext_el->values[i].length) == 0) {

-                     DEBUG(9, ("External host [%s] found, rule applies.\n",

-                               rhost));

-                     return RULE_APPLICABLE;

-                 }

-             }

-         }

-         DEBUG(9, ("No matching remote host found.\n"));

-         return RULE_NOT_APPLICABLE;

-     }

- 

-     return RULE_ERROR;

- }

- 

- static errno_t check_if_rule_applies(struct hbac_ctx *hbac_ctx,

-                                      struct sysdb_attrs *rule_attrs,

-                                      enum hbac_result *result) {

+ static char *get_hbac_search_base(TALLOC_CTX *mem_ctx,

+                                   struct dp_option *ipa_options)

+ {

+     char *base;

      int ret;

-     struct ldb_message_element *el;

-     enum hbac_result rule_type;

-     char *rule_name;

-     struct pam_data *pd = hbac_ctx->pd;

  

-     ret = sysdb_attrs_get_el(rule_attrs, IPA_CN, &el);

-     if (ret != EOK) {

-         DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-         return ret;

-     }

-     if (el->num_values == 0) {

-         DEBUG(4, ("rule has no name, assuming '(none)'.\n"));

-         rule_name = talloc_strdup(rule_attrs, "(none)");

-     } else {

-         rule_name = talloc_strndup(rule_attrs, (const char*) el->values[0].data,

-                                    el->values[0].length);

-     }

-     if (rule_name == NULL) {

-         DEBUG(1, ("talloc_strdup failed.\n"));

-         return ENOMEM;

+     base = dp_opt_get_string(ipa_options, IPA_HBAC_SEARCH_BASE);

+     if (base != NULL) {

+         return talloc_strdup(mem_ctx, base);

      }

-     DEBUG(9, ("Processsing rule [%s].\n", rule_name));

  

-     ret = sysdb_attrs_get_el(rule_attrs, IPA_ENABLED_FLAG, &el);

-     if (ret != EOK) {

-         DEBUG(1, ("Failed to find out if rule is enabled or not, "

-                   "assuming it is enabled.\n"));

-     } else {

-         if (el->num_values == 0) {

-             DEBUG(1, ("Failed to find out if rule is enabled or not, "

-                       "assuming it is enabled.\n"));

-         } else {

-             if (strncasecmp("false", (const char*) el->values[0].data,

-                             el->values[0].length) == 0) {

-                 DEBUG(7, ("Rule is disabled.\n"));

-                 *result = HBAC_NOT_APPLICABLE;

-                 return EOK;

-             }

-         }

-     }

+     DEBUG(9, ("ipa_hbac_search_base not available, trying base DN.\n"));

  

-     /* rule type */

-     ret = sysdb_attrs_get_el(rule_attrs, IPA_ACCESS_RULE_TYPE, &el);

+     ret = domain_to_basedn(mem_ctx,

+                            dp_opt_get_string(ipa_options, IPA_KRB5_REALM),

+                            &base);

      if (ret != EOK) {

-         DEBUG(1, ("sysdb_attrs_get_el failed.\n"));

-         return ret;

-     }

-     if (el->num_values == 0) {

-         DEBUG(4, ("rule has no type, assuming 'deny'.\n"));

-         rule_type = HBAC_DENY;

-     } else if (el->num_values == 1) {

-         if (strncasecmp((const char *) el->values[0].data, "allow",

-                         el->values[0].length) == 0) {

-             rule_type = HBAC_ALLOW;

-         } else {

-             rule_type = HBAC_DENY;

-         }

-     } else {

-         DEBUG(1, ("rule has an unsupported number of values [%d].\n",

-                   el->num_values));

-         return EINVAL;

-     }

- 

-     ret = check_service(hbac_ctx, rule_attrs);

-     if (ret != RULE_APPLICABLE) {

-         goto not_applicable;

-     }

- 

-     ret = check_user(hbac_ctx, rule_attrs);

-     if (ret != RULE_APPLICABLE) {

-         goto not_applicable;

-     }

- 

-     ret = check_remote_hosts(pd->rhost, hbac_ctx->remote_hhi, rule_attrs);

-     if (ret != RULE_APPLICABLE) {

-         goto not_applicable;

+         DEBUG(1, ("domain_to_basedn failed.\n"));

+         return NULL;

      }

  

-     *result = rule_type;

- 

-     return EOK;

- 

- not_applicable:

-     if (ret == RULE_NOT_APPLICABLE) {

-         *result = HBAC_NOT_APPLICABLE;

-     } else {

-         *result = HBAC_DENY;

-     }

-     return EOK;

+     return base;

  }

  

- static int evaluate_ipa_hbac_rules(struct hbac_ctx *hbac_ctx,

-                                    bool *access_allowed)

+ static void ipa_access_reply(struct hbac_ctx *hbac_ctx, int pam_status)

  {

-     bool allow_matched = false;

-     enum hbac_result result;

-     int ret;

-     int i;

- 

-     *access_allowed = false;

- 

-     for (i = 0; i < hbac_ctx->hbac_rule_count ; i++) {

- 

-         ret = check_if_rule_applies(hbac_ctx, hbac_ctx->hbac_rule_list[i],

-                                     &result);

-         if (ret != EOK) {

-             DEBUG(1, ("check_if_rule_applies failed.\n"));

-             return ret;

-         }

+     struct be_req *be_req = hbac_ctx->be_req;

+     struct pam_data *pd;

+     pd = talloc_get_type(be_req->req_data, struct pam_data);

+     pd->pam_status = pam_status;

  

-         switch (result) {

-             case HBAC_DENY:

-                 DEBUG(3, ("Access denied by single rule.\n"));

-                 return EOK;

-                 break;

-             case HBAC_ALLOW:

-                 allow_matched = true;

-                 DEBUG(9, ("Current rule allows access.\n"));

-                 break;

-             default:

-                 DEBUG(9, ("Current rule does not apply.\n"));

-         }

+     /* 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->fn(be_req, DP_ERR_OK, pam_status, NULL);

+     } else {

+         be_req->fn(be_req, DP_ERR_FATAL, pam_status, NULL);

      }

+ }

  

-     *access_allowed = allow_matched;

+ enum hbac_result {

+     HBAC_ALLOW = 1,

+     HBAC_DENY,

+     HBAC_NOT_APPLICABLE

+ };

  

-     return EOK;

- }

+ 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 hbac_get_host_info_done(struct tevent_req *req);

- static void hbac_get_rules_done(struct tevent_req *req);

- static void hbac_get_service_data_done(struct tevent_req *req);

+ 

+ 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;

+ 

+     pd = talloc_get_type(be_req->req_data, struct pam_data);

+ 

+     ipa_access_ctx = talloc_get_type(

+                               be_req->be_ctx->bet_info[BET_ACCESS].pvt_bet_data,

+                               struct ipa_access_ctx);

+ 

+     /* 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_req->be_ctx->ev,

+                            be_req->be_ctx,

+                            ipa_access_ctx->sdap_access_ctx,

+                            pd);

+     if (!req) {

+         be_req->fn(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 pam_data *pd;

      struct hbac_ctx *hbac_ctx;

+     const char *deny_method;

      int pam_status = PAM_SYSTEM_ERR;

      struct ipa_access_ctx *ipa_access_ctx;

-     bool offline;

      int ret;

  

+     be_req = tevent_req_callback_data(req, struct be_req);

      pd = talloc_get_type(be_req->req_data, struct pam_data);

  

+     ret = sdap_access_recv(req, &pam_status);

+     if (ret != EOK) goto fail;

+ 

+     switch(pam_status) {

+     case PAM_SUCCESS:

+         /* Account wasn't locked. Continue below

+          * to HBAC processing.

+          */

+         break;

+     case PAM_PERM_DENIED:

+         /* Account was locked. Return permission denied

+          * here.

+          */

+         pd->pam_status = PAM_PERM_DENIED;

+         be_req->fn(be_req, DP_ERR_OK, PAM_PERM_DENIED, NULL);

+         return;

+     default:

+         /* We got an unexpected error. Return it as-is */

+         pd->pam_status = PAM_SYSTEM_ERR;

+         be_req->fn(be_req, DP_ERR_FATAL, pam_status, NULL);

+         return;

+     }

+ 

      hbac_ctx = talloc_zero(be_req, struct hbac_ctx);

      if (hbac_ctx == NULL) {

          DEBUG(1, ("talloc failed.\n"));

          goto fail;

      }

+ 

      hbac_ctx->be_req = be_req;

      hbac_ctx->pd = pd;

      ipa_access_ctx = talloc_get_type(

                                be_req->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;
@@ -1681,16 +182,12 @@

          goto fail;

      }

  

-     offline = be_is_offline(be_req->be_ctx);

-     DEBUG(9, ("Connection status is [%s].\n", offline ? "offline" : "online"));

- 

-     if (!offline) {

-         hbac_ctx->sdap_op = sdap_id_op_create(hbac_ctx,

-                                     hbac_ctx_sdap_id_ctx(hbac_ctx)->conn_cache);

-         if (!hbac_ctx->sdap_op) {

-             DEBUG(1, ("sdap_id_op_create failed.\n"));

-             goto fail;

-         }

+     deny_method = dp_opt_get_string(hbac_ctx->ipa_options,

+                                     IPA_HBAC_DENY_METHOD);

+     if (strcasecmp(deny_method, "IGNORE") == 0) {

+         hbac_ctx->get_deny_rules = false;

+     } else {

+         hbac_ctx->get_deny_rules = true;

      }

  

      ret = hbac_retry(hbac_ctx);
@@ -1713,18 +210,48 @@

  {

      struct tevent_req *subreq;

      int ret;

+     bool offline;

+     time_t now, refresh_interval;

+     struct ipa_access_ctx *access_ctx = hbac_ctx->access_ctx;

  

-     if (hbac_ctx_is_offline(hbac_ctx)) {

-         return hbac_get_host_info_step(hbac_ctx);

-     }

+     offline = be_is_offline(hbac_ctx->be_req->be_ctx);

+     DEBUG(9, ("Connection status is [%s].\n", offline ? "offline" : "online"));

+ 

+     refresh_interval = dp_opt_get_int(hbac_ctx->ipa_options,

+                                       IPA_HBAC_REFRESH);

  

-     subreq = sdap_id_op_connect_send(hbac_ctx_sdap_id_op(hbac_ctx), hbac_ctx, &ret);

-     if (!subreq) {

-         DEBUG(1, ("sdap_id_op_connect_send failed: %d(%s).\n", ret, strerror(ret)));

-         return ret;

+     now = time(NULL);

+     if (now < access_ctx->last_update + refresh_interval) {

+         /* Simulate offline mode and just go to the cache */

+         DEBUG(6, ("Performing cached HBAC evaluation\n"));

+         offline = true;

      }

  

-     tevent_req_set_callback(subreq, hbac_connect_done, hbac_ctx);

+     if (!offline) {

+         if (hbac_ctx->sdap_op == NULL) {

+             hbac_ctx->sdap_op = sdap_id_op_create(hbac_ctx,

+                                         hbac_ctx_sdap_id_ctx(hbac_ctx)->conn_cache);

+             if (hbac_ctx->sdap_op == NULL) {

+                 DEBUG(1, ("sdap_id_op_create failed.\n"));

+                 return EIO;

+             }

+         }

+ 

+         subreq = sdap_id_op_connect_send(hbac_ctx_sdap_id_op(hbac_ctx), hbac_ctx, &ret);

+         if (!subreq) {

+             DEBUG(1, ("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;

  }

  
@@ -1739,6 +266,9 @@

      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;

      }
@@ -1754,6 +284,24 @@

      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 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)

  {
@@ -1774,6 +322,10 @@

          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;

          }

  
@@ -1790,173 +342,378 @@

      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 pam_data *pd = hbac_ctx->pd;

-     const char *hostlist[3];

-     struct tevent_req *subreq;

- 

-     hostlist[0] = dp_opt_get_cstring(hbac_ctx->ipa_options, IPA_HOSTNAME);

-     if (hostlist[0] == NULL) {

-         DEBUG(1, ("ipa_hostname not available.\n"));

-         return EINVAL;

-     }

-     if (pd->rhost != NULL && *pd->rhost != '\0') {

-         hostlist[1] = pd->rhost;

-         hostlist[2] = NULL;

-     } else {

-         hostlist[1] = NULL;

-         pd->rhost = discard_const_p(char, hostlist[0]);

-     }

- 

-     subreq = hbac_get_host_info_send(hbac_ctx, hbac_ctx, hostlist);

-     if (!subreq) {

-         DEBUG(1, ("hbac_get_host_info_send failed.\n"));

+     struct tevent_req *req =

+             ipa_hbac_host_info_send(hbac_ctx,

+                                     hbac_ctx_ev(hbac_ctx),

+                                     hbac_ctx_sysdb(hbac_ctx),

+                                     hbac_ctx_be(hbac_ctx)->domain,

+                                     sdap_id_op_handle(hbac_ctx->sdap_op),

+                                     hbac_ctx_sdap_id_ctx(hbac_ctx)->opts,

+                                     dp_opt_get_bool(hbac_ctx->ipa_options,

+                                                     IPA_HBAC_SUPPORT_SRCHOST),

+                                     dp_opt_get_string(hbac_ctx->ipa_options,

+                                                       IPA_HOSTNAME),

+                                     hbac_ctx->hbac_search_base);

+     if (req == NULL) {

+         DEBUG(1, ("Could not get host info\n"));

          return ENOMEM;

      }

+     tevent_req_set_callback(req, hbac_get_service_info_step, hbac_ctx);

  

-     tevent_req_set_callback(subreq, hbac_get_host_info_done, hbac_ctx);

      return EOK;

  }

  

- static void hbac_get_host_info_done(struct tevent_req *req)

+ static void hbac_get_service_info_step(struct tevent_req *req)

  {

-     struct hbac_ctx *hbac_ctx = tevent_req_callback_data(req, struct hbac_ctx);

-     int ret;

-     int pam_status = PAM_SYSTEM_ERR;

-     const char *ipa_hostname;

-     struct hbac_host_info *local_hhi = NULL;

+     errno_t ret;

+     struct hbac_ctx *hbac_ctx =

+             tevent_req_callback_data(req, struct hbac_ctx);

  

-     ret = hbac_get_host_info_recv(req, hbac_ctx, &hbac_ctx->hbac_hosts_count,

-                                   &hbac_ctx->hbac_hosts_list);

+     ret = ipa_hbac_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,

+                                     hbac_ctx_ev(hbac_ctx),

+                                     hbac_ctx_sysdb(hbac_ctx),

+                                     hbac_ctx_be(hbac_ctx)->domain,

+                                     sdap_id_op_handle(hbac_ctx->sdap_op),

+                                     hbac_ctx_sdap_id_ctx(hbac_ctx)->opts,

+                                     hbac_ctx->hbac_search_base);

+     if (req == NULL) {

+         DEBUG(1,("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);

+ 

+     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(1, ("Missing ipa_hostname, this should never happen.\n"));

          goto fail;

      }

  

-     ret = set_local_and_remote_host_info(hbac_ctx, hbac_ctx->hbac_hosts_count,

-                                          hbac_ctx->hbac_hosts_list, ipa_hostname,

-                                          hbac_ctx->pd->rhost, &local_hhi,

-                                          &hbac_ctx->remote_hhi);

-     if (ret != EOK) {

-         DEBUG(1, ("set_local_and_remote_host_info failed.\n"));

-         goto fail;

-      }

+     for (i = 0; i < hbac_ctx->host_count; i++) {

+         ret = sysdb_attrs_get_string(hbac_ctx->hosts[i],

+                                      IPA_HOST_FQDN,

+                                      &hostname);

+         if (ret != EOK) {

+             DEBUG(1, ("Could not locate IPA host\n"));

+             goto fail;

+         }

  

-     if (local_hhi == NULL) {

-         DEBUG(1, ("Missing host info for [%s].\n", ipa_hostname));

-         pam_status = PAM_PERM_DENIED;

+         if (strcasecmp(hostname, ipa_hostname) == 0) {

+             hbac_ctx->ipa_host = hbac_ctx->hosts[i];

+             break;

+         }

+     }

+     if (hbac_ctx->ipa_host == NULL) {

+         DEBUG(1, ("Could not locate IPA host\n"));

          goto fail;

      }

-     req = hbac_get_rules_send(hbac_ctx, hbac_ctx, local_hhi->dn,

-                               local_hhi->memberof);

+ 

+ 

+     /* Get the list of applicable rules */

+     req = ipa_hbac_rule_info_send(hbac_ctx,

+                                   hbac_ctx->get_deny_rules,

+                                   hbac_ctx_ev(hbac_ctx),

+                                   hbac_ctx_sysdb(hbac_ctx),

+                                   hbac_ctx_be(hbac_ctx)->domain,

+                                   sdap_id_op_handle(hbac_ctx->sdap_op),

+                                   hbac_ctx_sdap_id_ctx(hbac_ctx)->opts,

+                                   hbac_ctx->hbac_search_base,

+                                   hbac_ctx->ipa_host);

      if (req == NULL) {

-         DEBUG(1, ("hbac_get_rules_send failed.\n"));

+         DEBUG(1, ("Could not get rules\n"));

          goto fail;

      }

  

-     tevent_req_set_callback(req, hbac_get_rules_done, hbac_ctx);

+     tevent_req_set_callback(req, hbac_sysdb_save, hbac_ctx);

      return;

  

  fail:

-     ipa_access_reply(hbac_ctx, pam_status);

+     ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR);

  }

  

- static void hbac_get_rules_done(struct tevent_req *req)

+ static void hbac_sysdb_save(struct tevent_req *req)

  {

-     struct hbac_ctx *hbac_ctx = tevent_req_callback_data(req, struct hbac_ctx);

-     int ret;

-     int pam_status = PAM_SYSTEM_ERR;

- 

-     hbac_ctx->hbac_rule_count = 0;

-     talloc_zfree(hbac_ctx->hbac_rule_list);

+     errno_t ret;

+     bool in_transaction = false;

+     struct hbac_ctx *hbac_ctx =

+             tevent_req_callback_data(req, struct hbac_ctx);

+     struct sss_domain_info *domain = hbac_ctx_be(hbac_ctx)->domain;

+     struct sysdb_ctx *sysdb = hbac_ctx_sysdb(hbac_ctx);

+     struct ldb_dn *base_dn;

+     struct be_ctx *be_ctx = hbac_ctx_be(hbac_ctx);

+     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 = hbac_get_rules_recv(req, hbac_ctx, &hbac_ctx->hbac_rule_count,

-                               &hbac_ctx->hbac_rule_list);

+     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(sysdb, tmp_ctx,

+                                           domain->name,

+                                           HBAC_RULES_SUBDIR);

+         if (base_dn == NULL) {

+             talloc_free(tmp_ctx);

+             ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR);

+             return;

+         }

+ 

+         ret = sysdb_delete_recursive(tmp_ctx, sysdb, base_dn, true);

+         talloc_free(tmp_ctx);

+         if (ret != EOK) {

+             DEBUG(1, ("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;

      }

  

-     req = hbac_get_service_data_send(hbac_ctx, hbac_ctx);

-     if (req == NULL) {

-         DEBUG(1, ("hbac_get_service_data_send failed.\n"));

-         goto failed;

+     ret = sysdb_transaction_start(sysdb);

+     if (ret != EOK) {

+         DEBUG(0, ("Could not start transaction\n"));

+         goto fail;

      }

+     in_transaction = true;

  

-     tevent_req_set_callback(req, hbac_get_service_data_done, hbac_ctx);

-     return;

+     /* Save the hosts */

+     ret = ipa_hbac_sysdb_save(sysdb, domain,

+                               HBAC_HOSTS_SUBDIR, IPA_HOST_FQDN,

+                               hbac_ctx->host_count, hbac_ctx->hosts,

+                               HBAC_HOSTGROUPS_SUBDIR, IPA_CN,

+                               hbac_ctx->hostgroup_count,

+                               hbac_ctx->hostgroups);

+     if (ret != EOK) {

+         DEBUG(1, ("Error saving hosts: [%d][%s]\n",

+                   ret, strerror(ret)));

+         goto fail;

+     }

  

- failed:

-     ipa_access_reply(hbac_ctx, pam_status);

- }

+     /* Save the services */

+     ret = ipa_hbac_sysdb_save(sysdb, 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(1, ("Error saving services:  [%d][%s]\n",

+                   ret, strerror(ret)));

+         goto fail;

+     }

+     /* Save the rules */

+     ret = ipa_hbac_sysdb_save(sysdb, domain,

+                               HBAC_RULES_SUBDIR, IPA_UNIQUE_ID,

+                               hbac_ctx->rule_count,

+                               hbac_ctx->rules,

+                               NULL, NULL, 0, NULL);

+     if (ret != EOK) {

+         DEBUG(1, ("Error saving rules:  [%d][%s]\n",

+                   ret, strerror(ret)));

+         goto fail;

+     }

  

- static void hbac_get_service_data_done(struct tevent_req *req)

- {

-     struct hbac_ctx *hbac_ctx = tevent_req_callback_data(req, struct hbac_ctx);

-     struct pam_data *pd = hbac_ctx->pd;

-     int ret;

-     int pam_status = PAM_SYSTEM_ERR;

-     bool access_allowed = false;

+     ret = sysdb_transaction_commit(sysdb);

+     if (ret != EOK) {

+         DEBUG(0, ("Failed to commit transaction\n"));

+         goto fail;

+     }

  

-     hbac_ctx->hbac_services_count = 0;

-     talloc_zfree(hbac_ctx->hbac_services_list);

+     /* We don't need the rule data any longer,

+      * the rest of the processing relies on

+      * sysdb lookups.

+      */

+     hbac_clear_rule_data(hbac_ctx);

  

-     ret = hbac_get_service_data_recv(req, hbac_ctx,

-                                      &hbac_ctx->hbac_services_count,

-                                      &hbac_ctx->hbac_services_list);

-     talloc_zfree(req);

  

-     if (!hbac_check_step_result(hbac_ctx, ret)) {

-         return;

-     }

+     access_ctx->last_update = time(NULL);

  

-     if (hbac_ctx->user_dn) {

-         talloc_free(discard_const_p(TALLOC_CTX, hbac_ctx->user_dn));

-         hbac_ctx->user_dn = 0;

-     }

+     /* Now evaluate the request against the rules */

+     ipa_hbac_evaluate_rules(hbac_ctx);

+ 

+     return;

  

-     if (!hbac_ctx_is_offline(hbac_ctx)) {

-         ret = hbac_save_data_to_sysdb(hbac_ctx);

+ fail:

+     if (in_transaction) {

+         ret = sysdb_transaction_cancel(sysdb);

          if (ret != EOK) {

-             DEBUG(1, ("Failed to save data, "

-                       "offline authentication might not work.\n"));

-             /* This is not a fatal error. */

+             DEBUG(0, ("Could not cancel transaction\n"));

          }

      }

+     ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR);

+ }

+ 

+ static errno_t hbac_get_cached_rules(TALLOC_CTX *mem_ctx,

+                                      struct hbac_ctx *hbac_ctx);

  

-     hbac_ctx->groups_count = 0;

-     talloc_zfree(hbac_ctx->groups);

+ void ipa_hbac_evaluate_rules(struct hbac_ctx *hbac_ctx)

+ {

+     errno_t ret;

+     struct hbac_rule **hbac_rules;

+     struct hbac_eval_req *eval_req;

+     enum hbac_eval_result result;

+     struct hbac_info *info;

  

-     ret = hbac_get_user_info(hbac_ctx, hbac_ctx_be(hbac_ctx),

-                              pd->user, &hbac_ctx->user_dn,

-                              &hbac_ctx->groups_count, &hbac_ctx->groups);

+     /* Get HBAC rules from the sysdb */

+     ret = hbac_get_cached_rules(hbac_ctx, hbac_ctx);

      if (ret != EOK) {

-         goto failed;

+         DEBUG(1, ("Could not retrieve rules from the cache\n"));

+         ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR);

      }

  

-     ret = evaluate_ipa_hbac_rules(hbac_ctx, &access_allowed);

-     if (ret != EOK) {

-         DEBUG(1, ("evaluate_ipa_hbac_rules failed.\n"));

-         goto failed;

+     ret = hbac_ctx_to_rules(hbac_ctx, hbac_ctx,

+                             &hbac_rules, &eval_req);

+     if (ret == EPERM) {

+         DEBUG(1, ("DENY rules detected. Denying access to all users\n"));

+         ipa_access_reply(hbac_ctx, PAM_PERM_DENIED);

+         return;

+     } else if (ret != EOK) {

+         DEBUG(1, ("Could not construct HBAC rules\n"));

+         ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR);

+         return;

      }

  

-     if (access_allowed) {

-         pam_status = PAM_SUCCESS;

-         DEBUG(5, ("Access allowed.\n"));

-     } else {

-         pam_status = PAM_PERM_DENIED;

-         DEBUG(3, ("Access denied.\n"));

+     result = hbac_evaluate(hbac_rules, eval_req, &info);

+     if (result == HBAC_EVAL_ALLOW) {

+         DEBUG(3, ("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(1, ("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(1, ("Insufficient memory\n"));

+         ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR);

+         return;

+     }

+ 

+     DEBUG(3, ("Access denied by HBAC rules\n"));

+     hbac_free_info(info);

+     ipa_access_reply(hbac_ctx, PAM_PERM_DENIED);

+ }

+ 

+ static errno_t hbac_get_cached_rules(TALLOC_CTX *mem_ctx,

+                                      struct hbac_ctx *hbac_ctx)

+ {

+     errno_t ret;

+     struct sysdb_ctx *sysdb = hbac_ctx_sysdb(hbac_ctx);

+     struct sss_domain_info *domain = hbac_ctx_be(hbac_ctx)->domain;

+     size_t count;

+     struct ldb_message **msgs;

+     TALLOC_CTX *tmp_ctx;

+     char *filter;

+     const char *attrs[] = { OBJECTCLASS,

+                             IPA_CN,

+                             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(hbac_ctx);

+     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(mem_ctx, sysdb, domain, filter,

+                               HBAC_RULES_SUBDIR, attrs,

+                               &count, &msgs);

+     if (ret != EOK && ret != ENOENT) {

+         DEBUG(1, ("Error looking up HBAC rules"));

+         goto done;

+     } if (ret == ENOENT) {

+        count = 0;

      }

  

- failed:

-     ipa_access_reply(hbac_ctx, pam_status);

+     ret = msgs2attrs_array(mem_ctx, count, msgs, &hbac_ctx->rules);

+     if (ret != EOK) {

+         DEBUG(1, ("Could not convert ldb message to sysdb_attrs\n"));

+         goto done;

+     }

+     hbac_ctx->rule_count = count;

+ 

+     ret = EOK;

+ done:

+     talloc_free(tmp_ctx);

+     return ret;

  }

file modified
+22 -10
@@ -43,26 +43,38 @@

      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 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 sysdb_attrs **hbac_hosts_list;

-     size_t hbac_hosts_count;

-     struct hbac_host_info *remote_hhi;

-     struct sysdb_attrs **hbac_rule_list;

-     size_t hbac_rule_count;

-     const char *user_dn;

-     size_t groups_count;

-     const char **groups;

+ 

      char *hbac_search_base;

-     struct sysdb_attrs **hbac_services_list;

-     size_t hbac_services_count;

+ 

+     /* Hosts */

+     size_t host_count;

+     struct sysdb_attrs **hosts;

+     size_t hostgroup_count;

+     struct sysdb_attrs **hostgroups;

+     struct sysdb_attrs *ipa_host;

+ 

+     /* Rules */

+     bool get_deny_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;

  };

  

  /* Get BE context associated with HBAC context */

file modified
+8 -7
@@ -46,7 +46,7 @@

      struct sdap_handle *sh;

      enum sdap_result result;

      struct fo_server *srv;

-     char *ipa_domain;

+     char *ipa_realm;

      bool password_migration;

  };

  
@@ -56,13 +56,13 @@

  static struct tevent_req *get_password_migration_flag_send(TALLOC_CTX *memctx,

                                              struct tevent_context *ev,

                                              struct sdap_auth_ctx *sdap_auth_ctx,

-                                             char *ipa_domain)

+                                             char *ipa_realm)

  {

      int ret;

      struct tevent_req *req, *subreq;

      struct get_password_migration_flag_state *state;

  

-     if (sdap_auth_ctx == NULL || ipa_domain == NULL) {

+     if (sdap_auth_ctx == NULL || ipa_realm == NULL) {

          DEBUG(1, ("Missing parameter.\n"));

          return NULL;

      }
@@ -80,7 +80,7 @@

      state->result = SDAP_ERROR;

      state->srv = NULL;

      state->password_migration = false;

-     state->ipa_domain = ipa_domain;

+     state->ipa_realm = ipa_realm;

  

      /* We request to use StartTLS here, because if password migration is

       * enabled we will use this connection for authentication, too. */
@@ -126,7 +126,7 @@

          return;

      }

  

-     ret = domain_to_basedn(state, state->ipa_domain, &ldap_basedn);

+     ret = domain_to_basedn(state, state->ipa_realm, &ldap_basedn);

      if (ret != EOK) {

          DEBUG(1, ("domain_to_basedn failed.\n"));

          tevent_req_error(req, ret);
@@ -155,7 +155,8 @@

                                     state->sh, search_base, LDAP_SCOPE_SUBTREE,

                                     IPA_CONFIG_FILTER, attrs, NULL, 0,

                                     dp_opt_get_int(state->sdap_auth_ctx->opts->basic,

-                                                   SDAP_SEARCH_TIMEOUT));

+                                                   SDAP_SEARCH_TIMEOUT),

+                                    false);

      if (!subreq) {

          tevent_req_error(req, ENOMEM);

          return;
@@ -311,7 +312,7 @@

                                               state->ipa_auth_ctx->sdap_auth_ctx,

                                               dp_opt_get_string(

                                                 state->ipa_auth_ctx->ipa_options,

-                                                IPA_DOMAIN));

+                                                IPA_KRB5_REALM));

          if (req == NULL) {

              DEBUG(1, ("get_password_migration_flag failed.\n"));

              goto done;

file modified
+117 -36
@@ -35,7 +35,11 @@

      { "ipa_hostname", DP_OPT_STRING, NULL_STRING, NULL_STRING },

      { "ipa_dyndns_update", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },

      { "ipa_dyndns_iface", DP_OPT_STRING, NULL_STRING, NULL_STRING},

-     { "ipa_hbac_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING}

+     { "ipa_hbac_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_hbac_treat_deny_as", DP_OPT_STRING, { "DENY_ALL" }, NULL_STRING },

+     { "ipa_hbac_support_srchost", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }

  };

  

  struct dp_option ipa_def_ldap_opts[] = {
@@ -60,7 +64,7 @@

      { "ldap_enumeration_refresh_timeout", DP_OPT_NUMBER, { .number = 300 }, NULL_NUMBER },

      { "ldap_purge_cache_timeout", DP_OPT_NUMBER, { .number = 3600 }, NULL_NUMBER },

      { "entry_cache_timeout", DP_OPT_NUMBER, { .number = 1800 }, NULL_NUMBER },

-     { "ldap_tls_cacert", DP_OPT_STRING, NULL_STRING, NULL_STRING },

+     { "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 },
@@ -82,7 +86,7 @@

      { "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_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_dns_service_name", DP_OPT_STRING, NULL_STRING, NULL_STRING },
@@ -90,7 +94,10 @@

      /* 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_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_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },

+     { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }

  };

  

  struct sdap_attr_map ipa_attr_map[] = {
@@ -174,8 +181,10 @@

      struct ipa_options *opts;

      char *domain;

      char *server;

+     char *realm;

      char *ipa_hostname;

      int ret;

+     int i;

      char hostname[HOST_NAME_MAX + 1];

  

      opts = talloc_zero(memctx, struct ipa_options);
@@ -195,6 +204,7 @@

          if (ret != EOK) {

              goto done;

          }

+         domain = dom->name;

      }

  

      server = dp_opt_get_string(opts->basic, IPA_SERVER);
@@ -219,6 +229,27 @@

          }

      }

  

+     /* 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 */

+         realm = talloc_strdup(opts, domain);

+         if (!realm) {

+             ret = ENOMEM;

+             goto done;

+         }

+ 

+         /* Use the upper-case IPA domain for the kerberos realm */

+         for (i = 0; realm[i]; i++) {

+             realm[i] = toupper(realm[i]);

+         }

+ 

+         ret = dp_opt_set_string(opts->basic, IPA_KRB5_REALM,

+                                 realm);

+         if (ret != EOK) {

+             goto done;

+         }

+     }

  

      ret = EOK;

      *_opts = opts;
@@ -271,14 +302,14 @@

          goto done;

      }

  

-     if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE)) {

-         ret = domain_to_basedn(tmpctx,

-                                dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN),

-                                &basedn);

-         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);
@@ -318,16 +349,13 @@

  

      /* 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_DOMAIN);

+         realm = dp_opt_get_string(ipa_opts->basic, IPA_KRB5_REALM);

          value = talloc_strdup(tmpctx, realm);

          if (value == NULL) {

              DEBUG(1, ("talloc_strdup failed.\n"));

              ret = ENOMEM;

              goto done;

          }

-         for (i = 0; value[i]; i++) {

-             value[i] = toupper(value[i]);

-         }

          ret = dp_opt_set_string(ipa_opts->id->basic,

                                  SDAP_KRB5_REALM, value);

          if (ret != EOK) {
@@ -372,12 +400,31 @@

  

      if (NULL == dp_opt_get_string(ipa_opts->id->basic,

                                    SDAP_NETGROUP_SEARCH_BASE)) {

+ #if 0

          ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_NETGROUP_SEARCH_BASE,

                                  dp_opt_get_string(ipa_opts->id->basic,

                                                    SDAP_SEARCH_BASE));

          if (ret != EOK) {

              goto done;

          }

+ #else

+         /* We don't yet have support for the native representation

+          * of netgroups in IPA. For now, we need to point at the

+          * compat tree

+          */

+         value = talloc_asprintf(tmpctx, "cn=ng,cn=compat,%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;

+         }

+ #endif

          DEBUG(6, ("Option %s set to %s\n",

                    ipa_opts->id->basic[SDAP_NETGROUP_SEARCH_BASE].opt_name,

                    dp_opt_get_string(ipa_opts->id->basic,
@@ -447,7 +494,6 @@

      char *value;

      char *copy = NULL;

      int ret;

-     int i;

  

      /* self check test, this should never fail, unless someone forgot

       * to properly update the code after new ldap options have been added */
@@ -481,7 +527,7 @@

  

      /* set krb realm */

      if (NULL == dp_opt_get_string(ipa_opts->auth, KRB5_REALM)) {

-         value = dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN);

+         value = dp_opt_get_string(ipa_opts->basic, IPA_KRB5_REALM);

          if (!value) {

              ret = ENOMEM;

              goto done;
@@ -492,9 +538,6 @@

              ret = ENOMEM;

              goto done;

          }

-         for (i = 0; copy[i]; i++) {

-             copy[i] = toupper(copy[i]);

-         }

          ret = dp_opt_set_string(ipa_opts->auth, KRB5_REALM, copy);

          if (ret != EOK) {

              goto done;
@@ -517,49 +560,82 @@

  

  static void ipa_resolve_callback(void *private_data, struct fo_server *server)

  {

+     TALLOC_CTX *tmp_ctx = NULL;

      struct ipa_service *service;

-     struct hostent *srvaddr;

+     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(1, ("talloc_new failed\n"));

+         return;

+     }

+ 

      service = talloc_get_type(private_data, struct ipa_service);

      if (!service) {

          DEBUG(1, ("FATAL: Bad private_data\n"));

+         talloc_free(tmp_ctx);

          return;

      }

  

      srvaddr = fo_get_server_hostent(server);

      if (!srvaddr) {

          DEBUG(1, ("FATAL: No hostent available for server (%s)\n",

-                   fo_get_server_name(server)));

+                   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(1, ("resolv_get_sockaddr_address failed.\n"));

+         talloc_free(tmp_ctx);

          return;

      }

  

-     address = talloc_zero_size(service, 128);

+     address = resolv_get_string_address(tmp_ctx, srvaddr);

      if (address == NULL) {

-         DEBUG(1, ("talloc_zero failed.\n"));

+         DEBUG(1, ("resolv_get_string_address failed.\n"));

+         talloc_free(tmp_ctx);

          return;

      }

  

-     if (inet_ntop(srvaddr->h_addrtype, srvaddr->h_addr_list[0],

-                   address, 128) == NULL) {

-         DEBUG(1, ("inet_ntop failed [%d][%s].\n", errno, strerror(errno)));

+     safe_address = sss_ldap_escape_ip_address(tmp_ctx,

+                                               srvaddr->family,

+                                               address);

+     if (safe_address == NULL) {

+         DEBUG(1, ("sss_ldap_escape_ip_address failed.\n"));

+         talloc_free(tmp_ctx);

          return;

      }

  

-     new_uri = talloc_asprintf(service, "ldap://%s", address);

+     srv_name = fo_get_server_name(server);

+     if (srv_name == NULL) {

+         DEBUG(1, ("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(2, ("Failed to copy URI ...\n"));

-         talloc_free(address);

+         talloc_free(tmp_ctx);

          return;

      }

+     DEBUG(6, ("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);

      talloc_zfree(service->krb5_service->address);

-     service->krb5_service->address = address;

+     service->krb5_service->address = talloc_steal(service, address);

  

      ret = write_krb5info_file(service->krb5_service->realm, address,

                                SSS_KRB5KDC_FO_SRV);
@@ -567,10 +643,12 @@

          DEBUG(2, ("write_krb5info_file failed, authentication might fail.\n"));

      }

  

+     talloc_free(tmp_ctx);

  }

  

  int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,

-                      const char *servers, const char *domain,

+                      const char *servers,

+                      struct ipa_options *options,

                       struct ipa_service **_service)

  {

      TALLOC_CTX *tmp_ctx;
@@ -620,15 +698,18 @@

      }

      service->sdap->kinit_service_name = service->krb5_service->name;

  

-     realm = talloc_strdup(service, domain);

+     realm = dp_opt_get_string(options->basic, IPA_KRB5_REALM);

      if (!realm) {

-         ret = ENOMEM;

+         DEBUG(1, ("No Kerberos realm set\n"));

+         ret = EINVAL;

          goto done;

      }

-     for (i = 0; realm[i]; i++) {

-         realm[i] = toupper(realm[i]);

+     service->krb5_service->realm =

+         talloc_strdup(service->krb5_service, realm);

+     if (!service->krb5_service->realm) {

+         ret = ENOMEM;

+         goto done;

      }

-     service->krb5_service->realm = realm;

  

      if (!servers) {

          servers = BE_SRV_IDENTIFIER;

@@ -35,7 +35,7 @@

  /* the following defines are used to keep track of the options in the ldap

   * module, so that if they change and ipa is not updated correspondingly

   * this will trigger a runtime abort error */

- #define IPA_OPTS_BASIC_TEST 48

+ #define IPA_OPTS_BASIC_TEST 51

  

  /* the following define is used to keep track of the options in the krb5

   * module, so that if they change and ipa is not updated correspondingly
@@ -49,6 +49,10 @@

      IPA_DYNDNS_UPDATE,

      IPA_DYNDNS_IFACE,

      IPA_HBAC_SEARCH_BASE,

+     IPA_KRB5_REALM,

+     IPA_HBAC_REFRESH,

+     IPA_HBAC_DENY_METHOD,

+     IPA_HBAC_SUPPORT_SRCHOST,

  

      IPA_OPTS_BASIC /* opts counter */

  };
@@ -93,7 +97,8 @@

                           struct dp_option **_opts);

  

  int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,

-                      const char *servers, const char *domain,

+                      const char *servers,

+                      struct ipa_options *options,

                       struct ipa_service **_service);

  

  #endif /* _IPA_COMMON_H_ */

file modified
+141 -32
@@ -45,7 +45,7 @@

      struct ipa_ipaddress *next;

      struct ipa_ipaddress *prev;

  

-     struct sockaddr *addr;

+     struct sockaddr_storage *addr;

      bool matched;

  };

  
@@ -54,7 +54,7 @@

      struct sdap_id_op* sdap_op;

      char *hostname;

      struct ipa_ipaddress *addresses;

-     int child_status;

+     bool use_server_with_nsupdate;

  };

  

  
@@ -70,7 +70,7 @@

          DEBUG(1, ("Could not update DNS\n"));

          return;

      }

-     tevent_req_set_callback(req, ipa_dyndns_update_done, req);

+     tevent_req_set_callback(req, ipa_dyndns_update_done, NULL);

  }

  

  static void ipa_dyndns_sdap_connect_done(struct tevent_req *subreq);
@@ -93,6 +93,7 @@

      struct ifaddrs *ifa;

      struct ipa_ipaddress *address;

      struct tevent_req *req, *subreq;

+     size_t addrsize;

  

      DEBUG (9, ("Performing update\n"));

  
@@ -101,6 +102,7 @@

          return NULL;

      }

      state->ipa_ctx = ctx;

+     state->use_server_with_nsupdate = false;

  

      iface = dp_opt_get_string(ctx->basic, IPA_DYNDNS_IFACE);

  
@@ -131,8 +133,12 @@

                      goto failed;

                  }

  

+                 addrsize = ifa->ifa_addr->sa_family == AF_INET ? \

+                                     sizeof(struct sockaddr_in) : \

+                                     sizeof(struct sockaddr_in6);

+ 

                  address->addr = talloc_memdup(address, ifa->ifa_addr,

-                                               sizeof(struct sockaddr));

+                                               addrsize);

                  if(address->addr == NULL) {

                      goto failed;

                  }
@@ -218,8 +224,8 @@

      int ret;

      int fd;

      struct ipa_ipaddress *address;

-     struct sockaddr sa;

-     socklen_t sa_len = sizeof(sa);

+     struct sockaddr_storage ss;

+     socklen_t ss_len = sizeof(ss);

  

      if (!sh) {

          return EINVAL;
@@ -231,21 +237,21 @@

          return ret;

      }

  

-     ret = getsockname(fd, &sa, &sa_len);

+     ret = getsockname(fd, (struct sockaddr *) &ss, &ss_len);

      if (ret == -1) {

          DEBUG(0,("Failed to get socket name\n"));

          return errno;

      }

  

-     switch(sa.sa_family) {

+     switch(ss.ss_family) {

      case AF_INET:

      case AF_INET6:

          address = talloc(state, struct ipa_ipaddress);

          if (!address) {

              return ENOMEM;

          }

-         address->addr = talloc_memdup(address, &sa,

-                                       sizeof(struct sockaddr));

+         address->addr = talloc_memdup(address, &ss,

+                                       sizeof(struct sockaddr_storage));

          if(address->addr == NULL) {

              talloc_zfree(address);

              return ENOMEM;
@@ -301,10 +307,12 @@

      struct ipa_dyndns_ctx *dyndns_ctx;

      int pipefd_to_child;

      struct tevent_timer *timeout_handler;

+     int child_status;

  };

  

  

- static int create_nsupdate_message(struct ipa_nsupdate_ctx *ctx);

+ static int create_nsupdate_message(struct ipa_nsupdate_ctx *ctx,

+                                    bool use_server_with_nsupdate);

  

  static struct tevent_req *

  fork_nsupdate_send(struct ipa_nsupdate_ctx *ctx);
@@ -324,9 +332,10 @@

          return NULL;

      }

      state->dyndns_ctx = ctx;

+     state->child_status = 0;

  

      /* Format the message to pass to the nsupdate command */

-     ret = create_nsupdate_message(state);

+     ret = create_nsupdate_message(state, ctx->use_server_with_nsupdate);

      if (ret != EOK) {

          goto failed;

      }
@@ -347,27 +356,47 @@

  

  struct nsupdate_send_ctx {

      struct ipa_nsupdate_ctx *nsupdate_ctx;

+     struct sss_child_ctx_old *child_ctx;

+     int child_status;

  };

  

- static int create_nsupdate_message(struct ipa_nsupdate_ctx *ctx)

+ static int create_nsupdate_message(struct ipa_nsupdate_ctx *ctx,

+                                    bool use_server_with_nsupdate)

  {

      int ret, i;

-     char *servername;

+     char *servername = NULL;

+     char *realm;

+     char *realm_directive;

      char *zone;

      char ip_addr[INET6_ADDRSTRLEN];

      const char *ip;

      struct ipa_ipaddress *new_record;

+     TALLOC_CTX *tmp_ctx;

  

-     servername = dp_opt_get_string(ctx->dyndns_ctx->ipa_ctx->basic,

-                                    IPA_SERVER);

-     if (!servername) {

-         return EIO;

+     tmp_ctx = talloc_new(NULL);

+     if (!tmp_ctx) return ENOMEM;

+ 

+     realm = dp_opt_get_string(ctx->dyndns_ctx->ipa_ctx->basic, IPA_KRB5_REALM);

+     if (!realm) {

+         ret = EIO;

+         goto done;

+     }

+ 

+ #ifdef HAVE_NSUPDATE_REALM

+     realm_directive = talloc_asprintf(tmp_ctx, "realm %s\n", realm);

+ #else

+     realm_directive = talloc_asprintf(tmp_ctx, "");

+ #endif

+     if (!realm_directive) {

+         ret = ENOMEM;

+         goto done;

      }

  

      zone = dp_opt_get_string(ctx->dyndns_ctx->ipa_ctx->basic,

                               IPA_DOMAIN);

      if (!zone) {

-         return EIO;

+         ret = EIO;

+         goto done;

      }

  

      /* The DNS zone for IPA is the lower-case
@@ -377,10 +406,34 @@

          zone[i] = tolower(zone[i]);

      }

  

-     /* Add the server and zone headers */

-     ctx->update_msg = talloc_asprintf(ctx, "server %s\nzone %s.\n",

-                                            servername,

-                                            zone);

+     if (use_server_with_nsupdate) {

+         if (strncmp(ctx->dyndns_ctx->ipa_ctx->service->sdap->uri,

+                     "ldap://", 7) != 0) {

+             DEBUG(1, ("Unexpected format of LDAP URI.\n"));

+             ret = EIO;

+             goto done;

+         }

+         servername = ctx->dyndns_ctx->ipa_ctx->service->sdap->uri + 7;

+         if (!servername) {

+             ret = EIO;

+             goto done;

+         }

+ 

+         DEBUG(5, ("Creating update message for server [%s], realm [%s] "

+                   "and zone [%s].\n", servername, realm, zone));

+ 

+         /* Add the server, realm and zone headers */

+         ctx->update_msg = talloc_asprintf(ctx, "server %s\n%szone %s.\n",

+                                                servername, realm_directive,

+                                                zone);

+     } else {

+         DEBUG(5, ("Creating update message for realm [%s] and zone [%s].\n",

+                   realm, zone));

+ 

+         /* Add the realm and zone headers */

+         ctx->update_msg = talloc_asprintf(ctx, "%szone %s.\n",

+                                                realm_directive, zone);

+     }

      if (ctx->update_msg == NULL) {

          ret = ENOMEM;

          goto done;
@@ -398,9 +451,9 @@

      }

  

      DLIST_FOR_EACH(new_record, ctx->dyndns_ctx->addresses) {

-         switch(new_record->addr->sa_family) {

+         switch(new_record->addr->ss_family) {

          case AF_INET:

-             ip = inet_ntop(new_record->addr->sa_family,

+             ip = inet_ntop(new_record->addr->ss_family,

                             &(((struct sockaddr_in *)new_record->addr)->sin_addr),

                             ip_addr, INET6_ADDRSTRLEN);

              if (ip == NULL) {
@@ -410,7 +463,7 @@

              break;

  

          case AF_INET6:

-             ip = inet_ntop(new_record->addr->sa_family,

+             ip = inet_ntop(new_record->addr->ss_family,

                             &(((struct sockaddr_in6 *)new_record->addr)->sin6_addr),

                             ip_addr, INET6_ADDRSTRLEN);

              if (ip == NULL) {
@@ -430,7 +483,7 @@

                  ctx->update_msg,

                  "update add %s. 86400 in %s %s\n",

                  ctx->dyndns_ctx->hostname,

-                 new_record->addr->sa_family == AF_INET ? "A" : "AAAA",

+                 new_record->addr->ss_family == AF_INET ? "A" : "AAAA",

                  ip_addr);

          if (ctx->update_msg == NULL) {

              ret = ENOMEM;
@@ -444,9 +497,13 @@

          goto done;

      }

  

+     DEBUG(6, (" -- Begin nsupdate message -- \n%s", ctx->update_msg));

+     DEBUG(6, (" -- End nsupdate message -- \n"));

+ 

      ret = EOK;

  

  done:

+     talloc_free(tmp_ctx);

      return ret;

  }

  
@@ -478,6 +535,7 @@

          return NULL;

      }

      state->nsupdate_ctx = ctx;

+     state->child_status = 0;

  

      ret = pipe(pipefd_to_child);

      if (ret == -1) {
@@ -531,7 +589,8 @@

  

          /* Set up SIGCHLD handler */

          ret = child_handler_setup(ctx->dyndns_ctx->ipa_ctx->id_ctx->be->ev,

-                                   pid, ipa_dyndns_child_handler, req);

+                                   pid, ipa_dyndns_child_handler, req,

+                                   &state->child_ctx);

          if (ret != EOK) {

              return NULL;

          }
@@ -561,9 +620,16 @@

  {

      struct tevent_req *req =

              talloc_get_type(pvt, struct tevent_req);

+     struct nsupdate_send_ctx *state =

+             tevent_req_data(req, struct nsupdate_send_ctx);

+ 

  

      DEBUG(1, ("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, ETIMEDOUT);

  }

  
@@ -597,6 +663,10 @@

                                       void *pvt)

  {

      struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);

+     struct nsupdate_send_ctx *state =

+             tevent_req_data(req, struct nsupdate_send_ctx);

+ 

+     state->child_status = child_status;

  

      if (WIFEXITED(child_status) && WEXITSTATUS(child_status) != 0) {

          DEBUG(1, ("Dynamic DNS child failed with status [%d]\n",
@@ -615,6 +685,18 @@

      tevent_req_done(req);

  }

  

+ static int ipa_dyndns_child_recv(struct tevent_req *req, int *child_status)

+ {

+     struct nsupdate_send_ctx *state =

+             tevent_req_data(req, struct nsupdate_send_ctx);

+ 

+     *child_status = state->child_status;

+ 

+     TEVENT_REQ_RETURN_ON_ERROR(req);

+ 

+     return EOK;

+ }

+ 

  static int ipa_dyndns_generic_recv(struct tevent_req *req)

  {

      TEVENT_REQ_RETURN_ON_ERROR(req);
@@ -627,8 +709,10 @@

      int ret;

      struct tevent_req *req =

              tevent_req_callback_data(subreq, struct tevent_req);

+     struct ipa_nsupdate_ctx *state = tevent_req_data(req,

+                                                      struct ipa_nsupdate_ctx);

  

-     ret = ipa_dyndns_generic_recv(subreq);

+     ret = ipa_dyndns_child_recv(subreq, &state->child_status);

      talloc_zfree(subreq);

      if (ret != EOK) {

          tevent_req_error(req, ret);
@@ -638,21 +722,46 @@

      tevent_req_done(req);

  }

  

+ static int fork_nsupdate_recv(struct tevent_req *req, int *child_status)

+ {

+     struct ipa_nsupdate_ctx *state =

+             tevent_req_data(req, struct ipa_nsupdate_ctx);

+ 

+     *child_status = state->child_status;

+ 

+     TEVENT_REQ_RETURN_ON_ERROR(req);

+ 

+     return EOK;

+ }

+ 

  static void ipa_dyndns_gss_tsig_update_done(struct tevent_req *subreq)

  {

      /* Check the return code from the sigchld handler

       * and return it to the parent request.

       */

      int ret;

+     int child_status;

  

      struct tevent_req *req =

              tevent_req_callback_data(subreq, struct tevent_req);

+     struct ipa_dyndns_ctx *state = tevent_req_data(req, struct ipa_dyndns_ctx);

  

-     ret = ipa_dyndns_generic_recv(subreq);

+     ret = fork_nsupdate_recv(subreq, &child_status);

      talloc_zfree(subreq);

      if (ret != EOK) {

-         tevent_req_error(req, ret);

-         return;

+         if (state->use_server_with_nsupdate == false &&

+             WIFEXITED(child_status) && WEXITSTATUS(child_status) != 0) {

+             DEBUG(9, ("nsupdate failed, retrying with server name.\n"));

+             state->use_server_with_nsupdate = true;

+             ret = ipa_dyndns_gss_tsig_update_step(req);

+             if (ret != EOK) {

+                 tevent_req_error(req, ret);

+             }

+             return;

+         } else {

+             tevent_req_error(req, ret);

+             return;

+         }

      }

  

      tevent_req_done(req);

The added file is too large to be shown here, see it at: src/providers/ipa/ipa_hbac.doxy.in
@@ -0,0 +1,315 @@

+ /*

+     SSSD

+ 

+     IPA Backend Module -- Access control

+ 

+     Authors:

+         Sumit Bose <sbose@redhat.com>

+         Stephen Gallagher <sgallagh@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #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 <stdint.h>

+ #include <stdbool.h>

+ 

+ /** 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,

+ 

+     /** Succesful 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_ */

@@ -0,0 +1,11 @@

+ prefix=@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/

@@ -0,0 +1,800 @@

+ /*

+     SSSD

+ 

+     Authors:

+         Stephen Gallagher <sgallagh@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #include "providers/ipa/ipa_hbac_private.h"

+ #include "providers/ipa/ipa_hbac.h"

+ #include "providers/ipa/ipa_common.h"

+ 

+ errno_t

+ ipa_hbac_save_list(struct sysdb_ctx *sysdb, bool delete_subdir,

+                    const char *subdir, struct sss_domain_info *domain,

+                    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(1, ("talloc_new failed.\n"));

+         return ENOMEM;

+     }

+ 

+     if (delete_subdir) {

+         base_dn = sysdb_custom_subtree_dn(sysdb, tmp_ctx, domain->name, subdir);

+         if (base_dn == NULL) {

+             ret = ENOMEM;

+             goto done;

+         }

+ 

+         ret = sysdb_delete_recursive(tmp_ctx, sysdb, base_dn, true);

+         if (ret != EOK) {

+             DEBUG(1, ("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(1, ("sysdb_attrs_get_el failed.\n"));

+             goto done;

+         }

+         if (el->num_values == 0) {

+             DEBUG(1, ("[%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(1, ("talloc_strndup failed.\n"));

+             ret = ENOMEM;

+             goto done;

+         }

+         DEBUG(9, ("Object name: [%s].\n", object_name));

+ 

+         ret = sysdb_store_custom(tmp_ctx, sysdb, domain, object_name, subdir,

+                                  list[c]);

+         if (ret != EOK) {

+             DEBUG(1, ("sysdb_store_custom failed.\n"));

+             goto done;

+         }

+     }

+ 

+     ret = EOK;

+ 

+ done:

+     talloc_free(tmp_ctx);

+     return ret;

+ }

+ 

+ errno_t

+ ipa_hbac_sysdb_save(struct sysdb_ctx *sysdb, 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(sysdb);

+     if (ret != EOK) return ret;

+     in_transaction = true;

+ 

+     /* First, save the specific entries */

+     ret = ipa_hbac_save_list(sysdb, true,

+                              primary_subdir,

+                              domain,

+                              attr_name,

+                              primary_count,

+                              primary);

+     if (ret != EOK) {

+         DEBUG(1, ("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(sysdb, true,

+                                  group_subdir,

+                                  domain,

+                                  groupattr_name,

+                                  group_count,

+                                  groups);

+         if (ret != EOK) {

+             DEBUG(1, ("Could not save %s. [%d][%s]\n",

+                       group_subdir, ret, strerror(ret)));

+             goto done;

+         }

+     }

+ 

+     ret = sysdb_transaction_commit(sysdb);

+     if (ret != EOK) goto done;

+     in_transaction = false;

+ 

+ done:

+     if (in_transaction) {

+         sret = sysdb_transaction_cancel(sysdb);

+         if (sret != EOK) {

+             DEBUG(0, ("Could not cancel sysdb transaction\n"));

+         }

+     }

+ 

+     if (ret != EOK) {

+         DEBUG(3, ("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(1, ("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;

+     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(1, ("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(1, ("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)

+ {

+     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(4, ("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(7, ("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(7, ("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,

+                                   hbac_ctx_sysdb(hbac_ctx),

+                                   hbac_ctx_be(hbac_ctx)->domain,

+                                   new_rule->name,

+                                   hbac_ctx->rules[idx],

+                                   &new_rule->users);

+     if (ret != EOK) {

+         DEBUG(1, ("Could not parse users for rule [%s]\n",

+                   new_rule->name));

+         goto done;

+     }

+ 

+     /* Get the services */

+     ret = hbac_service_attrs_to_rule(new_rule,

+                                      hbac_ctx_sysdb(hbac_ctx),

+                                      hbac_ctx_be(hbac_ctx)->domain,

+                                      new_rule->name,

+                                      hbac_ctx->rules[idx],

+                                      &new_rule->services);

+     if (ret != EOK) {

+         DEBUG(1, ("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,

+                                    hbac_ctx_sysdb(hbac_ctx),

+                                    hbac_ctx_be(hbac_ctx)->domain,

+                                    new_rule->name,

+                                    hbac_ctx->rules[idx],

+                                    &new_rule->targethosts);

+     if (ret != EOK) {

+         DEBUG(1, ("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,

+                                    hbac_ctx_sysdb(hbac_ctx),

+                                    hbac_ctx_be(hbac_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(1, ("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(5, ("Category is set to 'all'.\n"));

+                 cats |= HBAC_CATEGORY_ALL;

+                 continue;

+             }

+             DEBUG(9, ("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 sysdb_ctx *sysdb,

+                        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 sysdb_ctx *sysdb,

+                           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 sysdb_ctx *sysdb,

+                        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 sysdb_ctx *sysdb = hbac_ctx_sysdb(hbac_ctx);

+     struct sss_domain_info *domain = hbac_ctx_be(hbac_ctx)->domain;

+     const char *rhost;

+     const char *thost;

+ 

+     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 */

+     ret = hbac_eval_user_element(eval_req, sysdb, 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, sysdb, 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, sysdb, 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(1, ("Missing ipa_hostname, this should never happen.\n"));

+         ret = EINVAL;

+         goto done;

+     }

+ 

+     ret = hbac_eval_host_element(eval_req, sysdb, 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 sysdb_ctx *sysdb,

+                        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, sysdb, domain,

+                                     users->name, attrs, &msg);

+     if (ret != EOK) {

+         DEBUG(1, ("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(7, ("No groups for [%s]\n", users->name));

+         ret = create_empty_grouplist(users);

+         goto done;

+     }

+     DEBUG(7, ("[%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, sysdb, member_dn,

+                                 &users->groups[num_groups]);

+         if (ret != EOK && ret != ENOENT) {

+             DEBUG(3, ("Parse error on [%s]\n", member_dn));

+             goto done;

+         } else if (ret == EOK) {

+             DEBUG(7, ("Added group [%s] for user [%s]\n",

+                       users->groups[num_groups], users->name));

+             num_groups++;

+             continue;

+         }

+         /* Skip entries that are not groups */

+         DEBUG(8, ("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 sysdb_ctx *sysdb,

+                           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(sysdb, tmp_ctx, domain->name,

+                              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, 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(1, ("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, sysdb,

+                                        (const char *)el->values[i].data,

+                                        &name);

+         if (ret != EOK && ret != ENOENT) goto done;

+ 

+         /* ENOENT 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 sysdb_ctx *sysdb,

+                        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(sysdb, tmp_ctx, domain->name,

+                               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, 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(1, ("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, sysdb,

+                                     (const char *)el->values[i].data,

+                                     &name);

+         if (ret != EOK && ret != ENOENT) goto done;

+ 

+         /* ENOENT 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;

+ }

@@ -0,0 +1,970 @@

+ /*

+     SSSD

+ 

+     Authors:

+         Stephen Gallagher <sgallagh@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #include "util/util.h"

+ #include "db/sysdb.h"

+ #include "providers/ipa/ipa_hbac_private.h"

+ #include "providers/ldap/sdap_async.h"

+ 

+ struct ipa_hbac_host_state {

+     struct tevent_context *ev;

+     struct sysdb_ctx *sysdb;

+     struct sss_domain_info *dom;

+     struct sdap_handle *sh;

+     struct sdap_options *opts;

+     const char *search_base;

+     const char **attrs;

+ 

+     bool support_srchost;

+     const char *hostname;

+ 

+     /* Return values */

+     size_t host_count;

+     struct sysdb_attrs **hosts;

+ 

+     size_t hostgroup_count;

+     struct sysdb_attrs **hostgroups;

+ };

+ 

+ #define HOSTGROUP_MAP_ATTRS_COUNT 5

+ static struct sdap_attr_map hostgroup_map[] = {

+     {"objectclass", "ipahostgroup", "hostgroup", NULL},

+     {"name_attr", IPA_CN, IPA_CN, NULL},

+     {"member", IPA_MEMBER, SYSDB_ORIG_MEMBER, NULL},

+     {"memberof", IPA_MEMBEROF, SYSDB_ORIG_MEMBEROF, NULL},

+     {"ipa_id", IPA_UNIQUE_ID, IPA_UNIQUE_ID, NULL}

+ };

+ 

+ static void

+ ipa_hbac_host_info_done(struct tevent_req *subreq);

+ 

+ static void

+ ipa_hbac_hostgroup_info_done(struct tevent_req *subreq);

+ 

+ struct tevent_req *

+ ipa_hbac_host_info_send(TALLOC_CTX *mem_ctx,

+                         struct tevent_context *ev,

+                         struct sysdb_ctx *sysdb,

+                         struct sss_domain_info *dom,

+                         struct sdap_handle *sh,

+                         struct sdap_options *opts,

+                         bool support_srchost,

+                         const char *hostname,

+                         const char *search_base)

+ {

+     errno_t ret;

+     struct ipa_hbac_host_state *state;

+     struct tevent_req *req;

+     struct tevent_req *subreq;

+     char *host_filter;

+ 

+     req = tevent_req_create(mem_ctx, &state, struct ipa_hbac_host_state);

+     if (req == NULL) {

+         return NULL;

+     }

+ 

+     state->ev = ev;

+     state->sysdb = sysdb;

+     state->dom = dom;

+     state->sh = sh;

+     state->opts = opts;

+     state->support_srchost = support_srchost;

+     state->hostname = hostname;

+     state->search_base = search_base;

+ 

+     if (support_srchost) {

+         host_filter = talloc_asprintf(state, "(objectClass=%s)", IPA_HOST);

+     } else {

+         if (hostname == NULL) {

+             ret = EINVAL;

+             goto immediate;

+         }

+         host_filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=%s))",

+                                       IPA_HOST, IPA_HOST_FQDN, hostname);

+     }

+     if (host_filter == NULL) {

+         ret = ENOMEM;

+         goto immediate;

+     }

+ 

+     state->attrs = talloc_array(state, const char *, 7);

+     if (state->attrs == NULL) {

+         DEBUG(1, ("Failed to allocate host attribute list.\n"));

+         ret = ENOMEM;

+         goto immediate;

+     }

+     state->attrs[0] = "objectClass";

+     state->attrs[1] = IPA_HOST_SERVERHOSTNAME;

+     state->attrs[2] = IPA_HOST_FQDN;

+     state->attrs[3] = IPA_UNIQUE_ID;

+     state->attrs[4] = IPA_MEMBEROF;

+     state->attrs[5] = IPA_CN;

+     state->attrs[6] = NULL;

+ 

+     subreq = sdap_get_generic_send(state, ev, opts, sh, search_base,

+                                    LDAP_SCOPE_SUB, host_filter,

+                                    state->attrs, NULL, 0,

+                                    dp_opt_get_int(opts->basic,

+                                                   SDAP_ENUM_SEARCH_TIMEOUT),

+                                    true);

+     if (subreq == NULL) {

+         DEBUG(1, ("Error requesting host info\n"));

+         ret = EIO;

+         goto immediate;

+     }

+     tevent_req_set_callback(subreq, ipa_hbac_host_info_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 errno_t

+ ipa_hbac_get_hostgroups_recv(struct tevent_req *subreq,

+                              TALLOC_CTX *mem_ctx,

+                              size_t *count,

+                              struct sysdb_attrs ***parents);

+ 

+ static struct tevent_req *

+ ipa_hbac_get_hostgroups_send(TALLOC_CTX *mem_ctx,

+                              struct tevent_context *ev,

+                              struct sdap_options *opts,

+                              struct sdap_handle *sh,

+                              size_t queue_len,

+                              char **queued_parents);

+ 

+ static void

+ ipa_hbac_host_info_done(struct tevent_req *subreq)

+ {

+     errno_t ret;

+     struct tevent_req *req =

+             tevent_req_callback_data(subreq, struct tevent_req);

+     struct ipa_hbac_host_state *state =

+             tevent_req_data(req, struct ipa_hbac_host_state);

+     char *hostgroup_filter;

+     const char *parent_dn;

+     struct ldb_message_element *parent_el;

+     char **queued_parents;

+     size_t queue_len;

+     int i;

+ 

+     ret = sdap_get_generic_recv(subreq, state,

+                                 &state->host_count,

+                                 &state->hosts);

+     talloc_zfree(subreq);

+     if (ret != EOK) goto error;

+ 

+     if (state->host_count == 0) goto error;

+ 

+     ret = replace_attribute_name(IPA_MEMBEROF, SYSDB_ORIG_MEMBEROF,

+                                  state->host_count,

+                                  state->hosts);

+     if (ret != EOK) {

+         DEBUG(1, ("Could not replace attribute names\n"));

+         goto error;

+     }

+ 

+     /* Complete the map */

+     for (i = 0; i < HOSTGROUP_MAP_ATTRS_COUNT; i++) {

+         /* These are allocated on the state, so the next time they'll

+          * have to be allocated again

+          */

+         hostgroup_map[i].name = talloc_strdup(state,

+                                               hostgroup_map[i].def_name);

+         if (hostgroup_map[i].name == NULL) goto error;

+     }

+ 

+     /* Look up host groups */

+     if (state->support_srchost) {

+         hostgroup_filter = talloc_asprintf(state, "(objectClass=%s)",

+                                                   IPA_HOSTGROUP);

+         if (hostgroup_filter == NULL) goto error;

+ 

+         subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,

+                                        state->search_base, LDAP_SCOPE_SUB,

+                                        hostgroup_filter, state->attrs, hostgroup_map,

+                                        HOSTGROUP_MAP_ATTRS_COUNT,

+                                        dp_opt_get_int(state->opts->basic,

+                                                       SDAP_ENUM_SEARCH_TIMEOUT),

+                                        true);

+         if (subreq == NULL) {

+             DEBUG(1, ("Error requesting host info\n"));

+             goto error;

+         }

+         tevent_req_set_callback(subreq, ipa_hbac_hostgroup_info_done, req);

+         return;

+     }

+ 

+     /* Source host processing is disabled */

+ 

+     ret = sysdb_attrs_get_el_ext(state->hosts[0],

+                                  SYSDB_ORIG_MEMBEROF,

+                                  false,

+                                  &parent_el);

+     if (ret != EOK && ret != ENOENT) goto error;

+ 

+     if (ret == ENOENT) {

+         queue_len = 0;

+         queued_parents = NULL;

+     } else {

+         /* Iterate through the memberOf DNs and retrieve

+          * the hostgroup entries in parallel

+          */

+ 

+         /* We'll assume that all parents are hostgroups for efficiency */

+         queued_parents = talloc_array(state, char *,

+                                       parent_el->num_values);

+         if (!queued_parents) {

+             ret = ENOMEM;

+             goto error;

+         }

+         queue_len = 0;

+ 

+         for (i=0; i < parent_el->num_values; i++) {

+             parent_dn = (char *)parent_el->values[i].data;

+ 

+             ret = get_ipa_hostgroupname(NULL, state->sysdb, parent_dn, NULL);

+             if (ret == ENOENT) {

+                 /* Skip this entry, it's not a hostgroup */

+                 continue;

+             } else if (ret != EOK) goto error;

+ 

+             /* Enqueue this hostgroup for lookup */

+             queued_parents[queue_len] =

+                     talloc_strdup(queued_parents, parent_dn);

+             if (!queued_parents[queue_len]) {

+                 ret = ENOMEM;

+                 goto error;

+             }

+             queue_len++;

+         }

+     }

+ 

+     subreq = ipa_hbac_get_hostgroups_send(state,

+                                           state->ev,

+                                           state->opts,

+                                           state->sh,

+                                           queue_len,

+                                           queued_parents);

+     if (!subreq) {

+         ret = ENOMEM;

+         goto error;

+     }

+ 

+     tevent_req_set_callback(subreq, ipa_hbac_hostgroup_info_done, req);

+     return;

+ 

+ error:

+     DEBUG(3, ("Error: [%s]\n", strerror(ret)));

+     tevent_req_error(req, ret);

+ }

+ 

+ #define HOSTGROUP_REQ_PARALLEL 50

+ 

+ struct ipa_hbac_get_hostgroups_state {

+     struct tevent_context *ev;

+     struct sdap_options *opts;

+     struct sdap_handle *sh;

+ 

+     const char **attrs;

+ 

+     char **queued_parents;

+     size_t queue_len;

+     size_t queue_iter;

+     size_t running;

+ 

+     /* Results */

+     struct sysdb_attrs **parents;

+     size_t parent_count;

+ };

+ 

+ static void

+ ipa_hbac_get_hostgroups_done(struct tevent_req *subreq);

+ 

+ static struct tevent_req *

+ ipa_hbac_get_hostgroups_send(TALLOC_CTX *mem_ctx,

+                              struct tevent_context *ev,

+                              struct sdap_options *opts,

+                              struct sdap_handle *sh,

+                              size_t queue_len,

+                              char **queued_parents)

+ {

+     errno_t ret;

+     struct tevent_req *req;

+     struct tevent_req *subreq;

+     struct ipa_hbac_get_hostgroups_state *state;

+ 

+     req = tevent_req_create(mem_ctx, &state,

+                             struct ipa_hbac_get_hostgroups_state);

+     if (!req) return NULL;

+ 

+     if (queue_len == 0) {

+         /* This host is not in any hostgroups */

+         ret = ENOENT;

+         goto error;

+     }

+ 

+     state->ev = ev;

+     state->opts = opts;

+     state->sh = sh;

+ 

+     state->queued_parents = queued_parents;

+     state->queue_len = queue_len;

+     state->queue_iter = 0;

+     state->running = 0;

+ 

+     state->attrs = talloc_array(state, const char *, 6);

+     if (state->attrs == NULL) {

+         DEBUG(1, ("Failed to allocate hostgroup attribute list.\n"));

+         ret = ENOMEM;

+         goto error;

+     }

+     state->attrs[0] = "objectClass";

+     state->attrs[1] = IPA_UNIQUE_ID;

+     state->attrs[2] = IPA_MEMBER;

+     state->attrs[3] = IPA_MEMBEROF;

+     state->attrs[4] = IPA_CN;

+     state->attrs[5] = NULL;

+ 

+     /* Pre-create the result array assuming that all values

+      * return results (which they should, since FreeIPA is

+      * memberOf-guaranteed.

+      */

+     state->parents = talloc_array(state, struct sysdb_attrs *,

+                                   state->queue_len);

+     if (!state->parents) {

+         ret = ENOMEM;

+         goto error;

+     }

+     state->parent_count = 0;

+ 

+     /* Process the parents in parallel */

+     while (state->queue_iter < state->queue_len

+             && state->running < HOSTGROUP_REQ_PARALLEL) {

+         subreq = sdap_get_generic_send(

+                     state, state->ev, state->opts, state->sh,

+                     state->queued_parents[state->queue_iter],

+                     LDAP_SCOPE_BASE, NULL, state->attrs,

+                     hostgroup_map, HOSTGROUP_MAP_ATTRS_COUNT,

+                     dp_opt_get_int(state->opts->basic,

+                                    SDAP_ENUM_SEARCH_TIMEOUT),

+                     false);

+         if (!subreq) {

+             ret = ENOMEM;

+             goto error;

+         }

+         tevent_req_set_callback(subreq, ipa_hbac_get_hostgroups_done, req);

+         state->queue_iter++;

+         state->running++;

+     }

+ 

+     return req;

+ 

+ error:

+     tevent_req_error(req, ret);

+     tevent_req_post(req, ev);

+     return req;

+ }

+ 

+ static void

+ ipa_hbac_get_hostgroups_done(struct tevent_req *subreq)

+ {

+     errno_t ret;

+     struct tevent_req *req =

+             tevent_req_callback_data(subreq, struct tevent_req);

+     struct ipa_hbac_get_hostgroups_state *state =

+             tevent_req_data(req, struct ipa_hbac_get_hostgroups_state);

+     size_t count;

+     struct sysdb_attrs **hostgroup_attrs = NULL;

+ 

+     /* Get the results and add them to the result array */

+     state->running--;

+ 

+     ret = sdap_get_generic_recv(subreq, NULL, &count, &hostgroup_attrs);

+     talloc_zfree(subreq);

+     if (ret != EOK || count != 1) {

+         /* We got an error retrieving the host group.

+          * We'll log it and continue. The worst-case

+          * here is that we'll deny too aggressively.

+          */

+         if (ret == EOK) {

+             /* We got back something other than a single entry on a

+              * base search?

+              */

+             ret = ENOENT;

+         }

+ 

+         DEBUG(1, ("Error [%s] while processing hostgroups. Skipping.\n",

+                   strerror(ret)));

+         goto next;

+     }

+ 

+     /* Add this hostgroup to the array */

+     state->parents[state->parent_count] =

+             talloc_steal(state->parents, hostgroup_attrs[0]);

+     state->parent_count++;

+ 

+ next:

+     /* Check if there are more hostgroups to process */

+     if (state->queue_iter < state->queue_len) {

+         subreq = sdap_get_generic_send(

+                     state, state->ev, state->opts, state->sh,

+                     state->queued_parents[state->queue_iter],

+                     LDAP_SCOPE_BASE, NULL, state->attrs,

+                     hostgroup_map, HOSTGROUP_MAP_ATTRS_COUNT,

+                     dp_opt_get_int(state->opts->basic,

+                                    SDAP_ENUM_SEARCH_TIMEOUT),

+                     false);

+         if (!subreq) {

+             ret = ENOMEM;

+             goto done;

+         }

+         tevent_req_set_callback(subreq, ipa_hbac_get_hostgroups_done, req);

+         state->queue_iter++;

+         state->running++;

+     }

+ 

+     /* Continue processing until all parallel searches have

+      * completed successfully.

+      */

+     if (state->running != 0) {

+         /* There are still pending parallel requests.

+          * Re-enter the mainloop.

+          */

+         talloc_free(hostgroup_attrs);

+         return;

+     }

+ 

+     /* All searches are complete. Return the results */

+     ret = EOK;

+ 

+ done:

+     if (ret == EOK) {

+         tevent_req_done(req);

+     } else {

+         DEBUG(3, ("Error [%d][%s]\n", ret, strerror(ret)));

+         tevent_req_error(req, ret);

+     }

+ 

+     talloc_free(hostgroup_attrs);

+     return;

+ }

+ 

+ static errno_t

+ ipa_hbac_get_hostgroups_recv(struct tevent_req *req,

+                              TALLOC_CTX *mem_ctx,

+                              size_t *reply_count,

+                              struct sysdb_attrs ***parents)

+ {

+     struct ipa_hbac_get_hostgroups_state *state =

+             tevent_req_data(req, struct ipa_hbac_get_hostgroups_state);

+ 

+     TEVENT_REQ_RETURN_ON_ERROR(req);

+ 

+     *reply_count = state->parent_count;

+     *parents = talloc_steal(mem_ctx, state->parents);

+ 

+     return EOK;

+ }

+ 

+ static void

+ ipa_hbac_hostgroup_info_done(struct tevent_req *subreq)

+ {

+     errno_t ret;

+     struct tevent_req *req =

+             tevent_req_callback_data(subreq, struct tevent_req);

+     struct ipa_hbac_host_state *state =

+             tevent_req_data(req, struct ipa_hbac_host_state);

+ 

+     if (state->support_srchost) {

+         ret = sdap_get_generic_recv(subreq, state,

+                                     &state->hostgroup_count,

+                                     &state->hostgroups);

+     } else {

+         ret = ipa_hbac_get_hostgroups_recv(subreq, state,

+                                            &state->hostgroup_count,

+                                            &state->hostgroups);

+     }

+     talloc_zfree(subreq);

+ 

+     if (ret == ENOENT) {

+         /* No hostgroups were found */

+         state->hostgroup_count = 0;

+         state->hostgroups = NULL;

+         ret = EOK;

+     }

+ 

+     if (ret == EOK) {

+         tevent_req_done(req);

+     } else {

+         DEBUG(3, ("Error [%d][%s]\n", ret, strerror(ret)));

+         tevent_req_error(req, ret);

+     }

+ }

+ 

+ errno_t

+ ipa_hbac_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_hbac_host_state *state =

+             tevent_req_data(req, struct ipa_hbac_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]);

+     }

+ 

+     *hostgroup_count = state->hostgroup_count;

+     *hostgroups = talloc_steal(mem_ctx, state->hostgroups);

+ 

+     return EOK;

+ }

+ 

+ /*

+  * Functions to convert sysdb_attrs to the hbac_rule format

+  */

+ static errno_t hbac_host_attrs_to_rule(TALLOC_CTX *mem_ctx,

+                                        struct sysdb_ctx *sysdb,

+                                        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[] = { IPA_HOST_FQDN, IPA_CN, 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(1, ("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(1, ("sysdb_attrs_get_el failed.\n"));

+         goto done;

+     }

+     if (ret == ENOENT || el->num_values == 0) {

+         el->num_values = 0;

+         DEBUG(4, ("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, sysdb, 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(1, ("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],

+                                                IPA_HOST_FQDN,

+                                                NULL);

+             if (name == NULL) {

+                 DEBUG(1, ("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(8, ("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, sysdb, 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(1, ("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], IPA_CN, NULL);

+                 if (name == NULL) {

+                     DEBUG(1, ("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(8, ("Added hostgroup [%s] to rule [%s]\n",

+                           name, rule_name));

+                 num_hostgroups++;

+             } else { /* ret == ENOENT */

+                 /* Neither a host nor a hostgroup? Skip it */

+                 DEBUG(1, ("[%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 sysdb_ctx *sysdb,

+                          struct sss_domain_info *domain,

+                          const char *rule_name,

+                          struct sysdb_attrs *rule_attrs,

+                          struct hbac_rule_element **thosts)

+ {

+     DEBUG(7, ("Processing target hosts for rule [%s]\n", rule_name));

+ 

+     return hbac_host_attrs_to_rule(mem_ctx, sysdb, 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 sysdb_ctx *sysdb,

+                          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(7, ("Processing source hosts for rule [%s]\n", rule_name));

+ 

+     if (!support_srchost) {

+         DEBUG(8, ("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;

+     }

+ 

+     ret = hbac_host_attrs_to_rule(tmp_ctx, sysdb, 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(8, ("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.

+      */

+ 

+     if (hostgroupname) {

+         *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 = EINVAL;

+         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 = ENOENT;

+         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 = EINVAL;

+         goto done;

+     }

+ 

+     if (strcasecmp("cn", rdn_name) != 0) {

+         /* RDN has the wrong attribute name.

+          * It's not a host.

+          */

+         ret = ENOENT;

+         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 = ENOENT;

+         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 = ENOENT;

+         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 = ENOENT;

+         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 = ENOENT;

+         goto done;

+     }

+ 

+     /* Then the value of the RDN is the group name */

+     rdn_val = ldb_dn_get_rdn_val(dn);

+ 

+     if (hostgroupname) {

+         *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;

+ }

@@ -0,0 +1,207 @@

+ /*

+     SSSD

+ 

+     Authors:

+         Stephen Gallagher <sgallagh@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #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_HOST "ipaHost"

+ #define IPA_HOSTGROUP "ipaHostGroup"

+ 

+ #define IPA_HBAC_SERVICE "ipaHBACService"

+ #define IPA_HBAC_SERVICE_GROUP "ipaHBACServiceGroup"

+ 

+ #define IPA_HOST_SERVERHOSTNAME "serverHostName"

+ #define IPA_HOST_FQDN "fqdn"

+ #define IPA_UNIQUE_ID "ipauniqueid"

+ 

+ #define IPA_MEMBER "member"

+ #define SYSDB_ORIG_MEMBER "orig_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_HOST_BASE_TMPL "cn=computers,cn=accounts,%s"

+ #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_save_list(struct sysdb_ctx *sysdb, bool delete_subdir,

+                            const char *subdir, struct sss_domain_info *domain,

+                            const char *naming_attribute, size_t count,

+                            struct sysdb_attrs **list);

+ errno_t

+ ipa_hbac_sysdb_save(struct sysdb_ctx *sysdb, 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);

+ 

+ /* From ipa_hbac_hosts.c */

+ struct tevent_req *

+ ipa_hbac_host_info_send(TALLOC_CTX *mem_ctx,

+                         struct tevent_context *ev,

+                         struct sysdb_ctx *sysdb,

+                         struct sss_domain_info *dom,

+                         struct sdap_handle *sh,

+                         struct sdap_options *opts,

+                         bool support_srchost,

+                         const char *hostname,

+                         const char *search_base);

+ 

+ errno_t

+ ipa_hbac_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);

+ 

+ errno_t

+ hbac_thost_attrs_to_rule(TALLOC_CTX *mem_ctx,

+                          struct sysdb_ctx *sysdb,

+                          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 sysdb_ctx *sysdb,

+                          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 sysdb_ctx *sysdb,

+                            struct sss_domain_info *dom,

+                            struct sdap_handle *sh,

+                            struct sdap_options *opts,

+                            const char *search_base);

+ 

+ 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 sysdb_ctx *sysdb,

+                            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_rules.c */

+ struct tevent_req *

+ ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx,

+                         bool get_deny_rules,

+                         struct tevent_context *ev,

+                         struct sysdb_ctx *sysdb,

+                         struct sss_domain_info *dom,

+                         struct sdap_handle *sh,

+                         struct sdap_options *opts,

+                         const char *search_base,

+                         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);

+ 

+ /* From ipa_hbac_users.c */

+ errno_t

+ hbac_user_attrs_to_rule(TALLOC_CTX *mem_ctx,

+                         struct sysdb_ctx *sysdb,

+                         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_ */

@@ -0,0 +1,232 @@

+ /*

+     SSSD

+ 

+     Authors:

+         Stephen Gallagher <sgallagh@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #include "util/util.h"

+ #include "providers/ipa/ipa_hbac_private.h"

+ #include "providers/ldap/sdap_async.h"

+ 

+ struct ipa_hbac_rule_state {

+     struct sdap_options *opts;

+ 

+     size_t rule_count;

+     struct sysdb_attrs **rules;

+ };

+ 

+ static void

+ ipa_hbac_rule_info_done(struct tevent_req *subreq);

+ 

+ struct tevent_req *

+ ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx,

+                         bool get_deny_rules,

+                         struct tevent_context *ev,

+                         struct sysdb_ctx *sysdb,

+                         struct sss_domain_info *dom,

+                         struct sdap_handle *sh,

+                         struct sdap_options *opts,

+                         const char *search_base,

+                         struct sysdb_attrs *ipa_host)

+ {

+     errno_t ret;

+     size_t i;

+     struct tevent_req *req = NULL;

+     struct tevent_req *subreq;

+     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;

+     const char *rule_attrs[] = { OBJECTCLASS,

+                                  IPA_CN,

+                                  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 };

+ 

+     if (ipa_host == NULL) {

+         DEBUG(1, ("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(1, ("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(1, ("tevent_req_create failed.\n"));

+         return NULL;

+     }

+ 

+     state->opts = opts;

+ 

+     if (get_deny_rules) {

+         rule_filter = talloc_asprintf(tmp_ctx,

+                                       "(&(objectclass=%s)"

+                                       "(%s=%s)(|(%s=%s)(%s=%s)",

+                                       IPA_HBAC_RULE,

+                                       IPA_ENABLED_FLAG, IPA_TRUE_VALUE,

+                                       IPA_HOST_CATEGORY, "all",

+                                       IPA_MEMBER_HOST, host_dn_clean);

+     } else {

+         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(1, ("Could not identify "))

+     } 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;

+     }

+     talloc_steal(state, rule_filter);

+ 

+     subreq = sdap_get_generic_send(state, ev, opts, sh, search_base,

+                                    LDAP_SCOPE_SUB, rule_filter, rule_attrs,

+                                    NULL, 0,

+                                    dp_opt_get_int(state->opts->basic,

+                                                   SDAP_ENUM_SEARCH_TIMEOUT),

+                                    true);

+     if (subreq == NULL) {

+         DEBUG(1, ("sdap_get_generic_send failed.\n"));

+         ret = ENOMEM;

+         goto immediate;

+     }

+     tevent_req_set_callback(subreq, ipa_hbac_rule_info_done, req);

+ 

+     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 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);

+ 

+     ret = sdap_get_generic_recv(subreq, state,

+                                 &state->rule_count,

+                                 &state->rules);

+     if (ret != EOK) {

+         DEBUG(3, ("Could not retrieve HBAC rules\n"));

+         tevent_req_error(req, ret);

+         return;

+     } else if (state->rule_count == 0) {

+         DEBUG(3, ("No rules apply to this host\n"));

+         tevent_req_error(req, ENOENT);

+         return;

+     }

+ 

+     tevent_req_done(req);

+ }

+ 

+ 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;

+ }

@@ -0,0 +1,562 @@

+ /*

+     SSSD

+ 

+     Authors:

+         Stephen Gallagher <sgallagh@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #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 sysdb_ctx *sysdb;

+     struct sss_domain_info *dom;

+     struct sdap_handle *sh;

+     struct sdap_options *opts;

+     const char *search_base;

+     const char **attrs;

+ 

+     /* Return values */

+     size_t service_count;

+     struct sysdb_attrs **services;

+ 

+     size_t servicegroup_count;

+     struct sysdb_attrs **servicegroups;

+ };

+ 

+ static void

+ ipa_hbac_service_info_done(struct tevent_req *subreq);

+ 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 sysdb_ctx *sysdb,

+                            struct sss_domain_info *dom,

+                            struct sdap_handle *sh,

+                            struct sdap_options *opts,

+                            const char *search_base)

+ {

+     errno_t ret;

+     struct ipa_hbac_service_state *state;

+     struct tevent_req *req;

+     struct tevent_req *subreq;

+     char *service_filter;

+ 

+     req = tevent_req_create(mem_ctx, &state, struct ipa_hbac_service_state);

+     if (req == NULL) {

+         DEBUG(1, ("tevent_req_create failed.\n"));

+         return NULL;

+     }

+ 

+     state->ev = ev;

+     state->sysdb = sysdb;

+     state->dom = dom;

+     state->sh = sh;

+     state->opts = opts;

+     state->search_base = search_base;

+ 

+     service_filter = talloc_asprintf(state, "(objectClass=%s)",

+                                      IPA_HBAC_SERVICE);

+     if (service_filter == NULL) {

+         ret = ENOMEM;

+         goto immediate;

+     }

+ 

+     state->attrs = talloc_array(state, const char *, 6);

+     if (state->attrs == NULL) {

+         DEBUG(1, ("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;

+ 

+     subreq = sdap_get_generic_send(state, ev, opts, sh, search_base,

+                                    LDAP_SCOPE_SUB, service_filter,

+                                    state->attrs, NULL, 0,

+                                    dp_opt_get_int(opts->basic,

+                                                   SDAP_ENUM_SEARCH_TIMEOUT),

+                                    true);

+     if (subreq == NULL) {

+         DEBUG(1, ("Error requesting service info\n"));

+         ret = EIO;

+         goto immediate;

+     }

+     tevent_req_set_callback(subreq, ipa_hbac_service_info_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

+ 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->service_count = 0;

+         state->services = NULL;

+         ret = EOK;

+         goto done;

+     }

+ 

+     ret = replace_attribute_name(IPA_MEMBEROF, SYSDB_ORIG_MEMBEROF,

+                                  state->service_count,

+                                  state->services);

+     if (ret != EOK) {

+         DEBUG(1, ("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;

+     }

+ 

+     /* Look up service groups */

+     subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,

+                                    state->search_base, LDAP_SCOPE_SUB,

+                                    servicegroup_filter, state->attrs, NULL, 0,

+                                    dp_opt_get_int(state->opts->basic,

+                                                   SDAP_ENUM_SEARCH_TIMEOUT),

+                                    true);

+     if (subreq == NULL) {

+         DEBUG(1, ("Error requesting host info\n"));

+         ret = EIO;

+         goto done;

+     }

+     tevent_req_set_callback(subreq, ipa_hbac_servicegroup_info_done, req);

+ 

+     return;

+ 

+ done:

+     if (ret == EOK) {

+         tevent_req_done(req);

+     } else {

+         tevent_req_error(req, ret);

+     }

+ }

+ 

+ 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);

+ 

+     ret = sdap_get_generic_recv(subreq, state,

+                                 &state->servicegroup_count,

+                                 &state->servicegroups);

+     talloc_zfree(subreq);

+     if (ret != EOK) {

+         goto done;

+     }

+ 

+     ret = replace_attribute_name(IPA_MEMBER, SYSDB_ORIG_MEMBER,

+                                  state->servicegroup_count,

+                                  state->servicegroups);

+     if (ret != EOK) {

+         DEBUG(1, ("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(1, ("Could not replace attribute names\n"));

+         goto done;

+     }

+ 

+ done:

+     if (ret == EOK) {

+         tevent_req_done(req);

+     } else {

+         DEBUG(3, ("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 sysdb_ctx *sysdb,

+                            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(7, ("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(1, ("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(1, ("sysdb_attrs_get_el failed.\n"));

+         goto done;

+     }

+     if (ret == ENOENT || el->num_values == 0) {

+         el->num_values = 0;

+         DEBUG(4, ("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, sysdb, 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(1, ("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(1, ("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(8, ("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, sysdb, 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(1, ("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(1, ("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(8, ("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(1, ("[%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 = EINVAL;

+         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 = ENOENT;

+         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 = EINVAL;

+         goto done;

+     }

+ 

+     if (strcasecmp("cn", rdn_name) != 0) {

+         /* RDN has the wrong attribute name.

+          * It's not a service.

+          */

+         ret = ENOENT;

+         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 = ENOENT;

+         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 = ENOENT;

+         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 = ENOENT;

+         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 = ENOENT;

+         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;

+ }

@@ -0,0 +1,346 @@

+ /*

+     SSSD

+ 

+     Authors:

+         Stephen Gallagher <sgallagh@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #include "util/util.h"

+ #include "providers/ipa/ipa_hbac_private.h"

+ #include "providers/ldap/sdap_async.h"

+ 

+ struct hbac_update_groups_state {

+     struct hbac_ctx *hbac_ctx;

+     struct sysdb_ctx *sysdb;

+     struct sss_domain_info *domain;

+ };

+ 

+ 

+ /* 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 = EINVAL;

+         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 = ENOENT;

+         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 = EINVAL;

+         goto done;

+     }

+ 

+     if (strcasecmp("cn", rdn_name) != 0) {

+         /* RDN has the wrong attribute name.

+          * It's not a group.

+          */

+         ret = ENOENT;

+         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 = ENOENT;

+         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 = ENOENT;

+         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 = ENOENT;

+         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 = ENOENT;

+         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 sysdb_ctx *sysdb,

+                         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(7, ("Processing users for rule [%s]\n", rule_name));

+ 

+     ret = hbac_get_category(rule_attrs, IPA_USER_CATEGORY,

+                             &new_users->category);

+     if (ret != EOK) {

+         DEBUG(1, ("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(1, ("sysdb_attrs_get_el failed.\n"));

+         goto done;

+     }

+     if (ret == ENOENT || el->num_values == 0) {

+         el->num_values = 0;

+         DEBUG(4, ("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, sysdb, 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(1, ("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(1, ("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(8, ("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, sysdb, 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(1, ("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(1, ("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(8, ("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, sysdb, member_user,

+                                         &new_users->groups[num_groups]);

+                 if (ret == EOK) {

+                     DEBUG(8, ("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(1, ("[%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;

+ }

file modified
+12 -8
@@ -33,6 +33,7 @@

  #include "providers/ipa/ipa_auth.h"

  #include "providers/ipa/ipa_access.h"

  #include "providers/ipa/ipa_dyndns.h"

+ #include "providers/ldap/sdap_access.h"

  

  struct ipa_options *ipa_options = NULL;

  
@@ -61,7 +62,6 @@

  int common_ipa_init(struct be_ctx *bectx)

  {

      const char *ipa_servers;

-     const char *ipa_domain;

      int ret;

  

      ret = ipa_get_options(bectx, bectx->cdb,
@@ -76,13 +76,7 @@

          DEBUG(1, ("Missing ipa_server option - using service discovery!\n"));

      }

  

-     ipa_domain = dp_opt_get_string(ipa_options->basic, IPA_DOMAIN);

-     if (!ipa_domain) {

-         DEBUG(0, ("Missing ipa_domain option!\n"));

-         return EINVAL;

-     }

- 

-     ret = ipa_service_init(ipa_options, bectx, ipa_servers, ipa_domain,

+     ret = ipa_service_init(ipa_options, bectx, ipa_servers, ipa_options,

                             &ipa_options->service);

      if (ret != EOK) {

          DEBUG(0, ("Failed to init IPA failover service!\n"));
@@ -371,6 +365,16 @@

          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;

  

@@ -23,6 +23,8 @@

  */

  

  

+ #include <ctype.h>

+ 

  #include "providers/ipa/ipa_common.h"

  

  int domain_to_basedn(TALLOC_CTX *memctx, const char *domain, char **basedn)
@@ -52,6 +54,10 @@

          return ENOMEM;

      }

  

+     for (p=dn; *p; ++p) {

+         *p = tolower(*p);

+     }

+ 

      *basedn = dn;

      return EOK;

  }

file modified
+103 -37
@@ -146,11 +146,12 @@

      return EOK;

  }

  

- static int krb5_save_ccname(TALLOC_CTX *mem_ctx,

-                             struct sysdb_ctx *sysdb,

-                             struct sss_domain_info *domain,

-                             const char *name,

-                             const char *ccname)

+ 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;
@@ -161,7 +162,13 @@

          return EINVAL;

      }

  

-     DEBUG(9, ("Save ccname [%s] for user [%s].\n", ccname, name));

+     if (mod_op != SYSDB_MOD_REP && mod_op != SYSDB_MOD_DEL) {

+         DEBUG(1, ("Unsupported operation [%d].\n", mod_op));

+         return EINVAL;

+     }

+ 

+     DEBUG(9, ("%s ccname [%s] for user [%s].\n",

+               mod_op == SYSDB_MOD_REP ? "Save" : "Delete", ccname, name));

  

      tmpctx = talloc_new(mem_ctx);

      if (!tmpctx) {
@@ -187,7 +194,7 @@

      }

  

      ret = sysdb_set_user_attr(tmpctx, sysdb,

-                               domain, name, attrs, SYSDB_MOD_REP);

+                               domain, name, attrs, mod_op);

      if (ret != EOK) {

          DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));

          sysdb_transaction_cancel(sysdb);
@@ -204,6 +211,26 @@

      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 pam_data *pd;
@@ -297,6 +324,9 @@

      return EOK;

  }

  

+ static struct tevent_req *krb5_next_kdc(struct tevent_req *req);

+ static struct tevent_req *krb5_next_kpasswd(struct tevent_req *req);

+ 

  struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,

                                    struct tevent_context *ev,

                                    struct be_ctx *be_ctx,
@@ -484,16 +514,14 @@

  

      kr->srv = NULL;

      kr->kpasswd_srv = NULL;

-     subreq = be_resolve_server_send(state, state->ev, state->be_ctx,

-                                     krb5_ctx->service->name);

-     if (subreq == NULL) {

-         DEBUG(1, ("be_resolve_server_send failed.\n"));

-         ret = ENOMEM;

+ 

+     subreq = krb5_next_kdc(req);

+     if (!subreq) {

+         DEBUG(1, ("krb5_next_kdc failed.\n"));

+         ret = EIO;

          goto done;

      }

  

-     tevent_req_set_callback(subreq, krb5_resolve_kdc_done, req);

- 

      return req;

  

  done:
@@ -523,18 +551,13 @@

          be_mark_offline(state->be_ctx);

          kr->is_offline = true;

      } else {

-         if (state->pd->cmd == SSS_PAM_CHAUTHTOK &&

-             kr->krb5_ctx->kpasswd_service != NULL) {

-             subreq = be_resolve_server_send(state, state->ev, state->be_ctx,

-                                             kr->krb5_ctx->kpasswd_service->name);

+         if (kr->krb5_ctx->kpasswd_service != NULL) {

+             subreq = krb5_next_kpasswd(req);

              if (subreq == NULL) {

-                 DEBUG(1, ("be_resolve_server_send failed.\n"));

-                 ret = ENOMEM;

+                 DEBUG(1, ("krb5_next_kpasswd failed.\n"));

+                 ret = EIO;

                  goto failed;

              }

- 

-             tevent_req_set_callback(subreq, krb5_resolve_kpasswd_done, req);

- 

              return;

          }

      }
@@ -684,7 +707,6 @@

  }

  

  static struct tevent_req *krb5_next_server(struct tevent_req *req);

- static struct tevent_req *krb5_next_kdc(struct tevent_req *req);

  static struct tevent_req *krb5_next_kpasswd(struct tevent_req *req);

  

  static void krb5_child_done(struct tevent_req *subreq)
@@ -800,7 +822,8 @@

      /* If the child request failed, but did not return an offline error code,

       * return with the status */

      if (msg_status != PAM_SUCCESS && msg_status != PAM_AUTHINFO_UNAVAIL &&

-         msg_status != PAM_AUTHTOK_LOCK_BUSY) {

+         msg_status != PAM_AUTHTOK_LOCK_BUSY &&

+         msg_status != PAM_NEW_AUTHTOK_REQD) {

          state->pam_status = msg_status;

          state->dp_err = DP_ERR_OK;

          ret = EOK;
@@ -809,6 +832,33 @@

          state->pam_status = msg_status;

      }

  

+     /* 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 (msg_status == PAM_NEW_AUTHTOK_REQD) {

+         if (pd->cmd == SSS_PAM_AUTHENTICATE && !kr->active_ccache_present) {

+             if (kr->old_ccname != NULL) {

+                 ret = safe_remove_old_ccache_file(kr->old_ccname, "dummy");

+                 if (ret != EOK) {

+                     DEBUG(1, ("Failed to remove old ccache file [%s], "

+                               "please remove it manually.\n", kr->old_ccname));

+                 }

+ 

+                 ret = krb5_delete_ccname(state, state->be_ctx->sysdb,

+                                          state->be_ctx->domain,

+                                          pd->user, kr->old_ccname);

+                 if (ret != EOK) {

+                     DEBUG(1, ("krb5_delete_ccname failed.\n"));

+                 }

+             }

+         }

+ 

+         state->pam_status = msg_status;

+         state->dp_err = DP_ERR_OK;

+         ret = EOK;

+         goto done;

+     }

+ 

      /* If the child request was successful and we run the first pass of the

       * change password request just return success. */

      if (msg_status == PAM_SUCCESS && pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) {
@@ -822,14 +872,16 @@

      if (kr->kpasswd_srv != NULL) {

          /* ..which is unreachable by now.. */

          if (msg_status == PAM_AUTHTOK_LOCK_BUSY) {

-             fo_set_port_status(kr->kpasswd_srv, PORT_NOT_WORKING);

+             be_fo_set_port_status(state->be_ctx,

+                                   kr->kpasswd_srv, PORT_NOT_WORKING);

              /* ..try to resolve next kpasswd server */

              if (krb5_next_kpasswd(req) == NULL) {

                  tevent_req_error(req, ENOMEM);

              }

              return;

          } else {

-             fo_set_port_status(kr->kpasswd_srv, PORT_WORKING);

+             be_fo_set_port_status(state->be_ctx,

+                                   kr->kpasswd_srv, PORT_WORKING);

          }

      }

  
@@ -839,7 +891,7 @@

      if (msg_status == PAM_AUTHINFO_UNAVAIL ||

          (kr->kpasswd_srv == NULL && msg_status == PAM_AUTHTOK_LOCK_BUSY)) {

          if (kr->srv != NULL) {

-             fo_set_port_status(kr->srv, PORT_NOT_WORKING);

+             be_fo_set_port_status(state->be_ctx, kr->srv, PORT_NOT_WORKING);

              /* ..try to resolve next KDC */

              if (krb5_next_kdc(req) == NULL) {

                  tevent_req_error(req, ENOMEM);
@@ -847,7 +899,7 @@

              return;

          }

      } else if (kr->srv != NULL) {

-         fo_set_port_status(kr->srv, PORT_WORKING);

+         be_fo_set_port_status(state->be_ctx, kr->srv, PORT_WORKING);

      }

  

      /* Now only a successful authentication or password change is left.
@@ -918,17 +970,20 @@

      switch (pd->cmd) {

          case SSS_PAM_AUTHENTICATE:

          case SSS_CMD_RENEW:

-             fo_set_port_status(state->kr->srv, PORT_NOT_WORKING);

+             be_fo_set_port_status(state->be_ctx,

+                                   state->kr->srv, PORT_NOT_WORKING);

              next_req = krb5_next_kdc(req);

              break;

          case SSS_PAM_CHAUTHTOK:

          case SSS_PAM_CHAUTHTOK_PRELIM:

              if (state->kr->kpasswd_srv) {

-                 fo_set_port_status(state->kr->kpasswd_srv, PORT_NOT_WORKING);

+                 be_fo_set_port_status(state->be_ctx,

+                                       state->kr->kpasswd_srv, PORT_NOT_WORKING);

                  next_req = krb5_next_kpasswd(req);

                  break;

              } else {

-                 fo_set_port_status(state->kr->srv, PORT_NOT_WORKING);

+                 be_fo_set_port_status(state->be_ctx,

+                                       state->kr->srv, PORT_NOT_WORKING);

                  next_req = krb5_next_kdc(req);

                  break;

              }
@@ -946,7 +1001,8 @@

  

      next_req = be_resolve_server_send(state, state->ev,

                                        state->be_ctx,

-                                       state->krb5_ctx->service->name);

+                                       state->krb5_ctx->service->name,

+                                       state->kr->srv == NULL ? true : false);

      if (next_req == NULL) {

          DEBUG(1, ("be_resolve_server_send failed.\n"));

          return NULL;
@@ -963,7 +1019,8 @@

  

      next_req = be_resolve_server_send(state, state->ev,

                                  state->be_ctx,

-                                 state->krb5_ctx->kpasswd_service->name);

+                                 state->krb5_ctx->kpasswd_service->name,

+                                 state->kr->kpasswd_srv == NULL ? true : false);

      if (next_req == NULL) {

          DEBUG(1, ("be_resolve_server_send failed.\n"));

          return NULL;
@@ -1001,8 +1058,13 @@

          state->dp_err = DP_ERR_OK;

  

          switch(pd->cmd) {

-             case SSS_PAM_AUTHENTICATE:

              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:

                  password = talloc_size(state, pd->authtok_size + 1);

                  if (password != NULL) {
@@ -1022,8 +1084,11 @@

          }

  

          if (password == NULL) {

-             DEBUG(0, ("password not available, offline auth may not work.\n"));

-             ret = EOK; /* password caching failures are not fatal errors */

+             if (pd->cmd != SSS_CMD_RENEW) {

+                 DEBUG(0, ("password not available, offline auth may not work.\n"));

+                 /* password caching failures are not fatal errors */

+             }

+             ret = EOK;

              goto done;

          }

  
@@ -1035,6 +1100,7 @@

          if (ret) {

              DEBUG(2, ("Failed to cache password, offline auth may not work."

                        " (%d)[%s]!?\n", ret, strerror(ret)));

+             /* password caching failures are not fatal errors */

          }

      }

  

@@ -265,7 +265,7 @@

          fd_nonblocking(state->io->read_from_child_fd);

          fd_nonblocking(state->io->write_to_child_fd);

  

-         ret = child_handler_setup(state->ev, pid, NULL, NULL);

+         ret = child_handler_setup(state->ev, pid, NULL, NULL, NULL);

          if (ret != EOK) {

              DEBUG(1, ("Could not set up child signal handler\n"));

              return ret;

@@ -367,7 +367,7 @@

  static void krb5_resolve_callback(void *private_data, struct fo_server *server)

  {

      struct krb5_service *krb5_service;

-     struct hostent *srvaddr;

+     struct resolv_hostent *srvaddr;

      char *address;

      int ret;

  
@@ -380,20 +380,13 @@

      srvaddr = fo_get_server_hostent(server);

      if (!srvaddr) {

          DEBUG(1, ("FATAL: No hostent available for server (%s)\n",

-                   fo_get_server_name(server)));

+                   fo_get_server_str_name(server)));

          return;

      }

  

-     address = talloc_zero_size(krb5_service, 128);

+     address = resolv_get_string_address(krb5_service, srvaddr);

      if (address == NULL) {

-         DEBUG(1, ("talloc_zero failed.\n"));

-         return;

-     }

- 

-     if (inet_ntop(srvaddr->h_addrtype, srvaddr->h_addr_list[0],

-                   address, 128) == NULL) {

-         ret = errno;

-         DEBUG(1, ("inet_ntop failed [%d][%s].\n", ret, strerror(ret)));

+         DEBUG(1, ("resolv_get_string_address failed.\n"));

          return;

      }

  

@@ -26,6 +26,7 @@

  #include "util/util.h"

  #include "providers/krb5/krb5_common.h"

  #include "providers/krb5/krb5_auth.h"

+ #include "providers/krb5/krb5_utils.h"

  

  #define INITIAL_TGT_TABLE_SIZE 10

  
@@ -36,7 +37,6 @@

      struct krb5_ctx *krb5_ctx;

      time_t timer_interval;

      struct tevent_timer *te;

-     bool added_to_online_callbacks;

  };

  

  struct renew_data {
@@ -69,6 +69,10 @@

                           auth_data->krb5_ctx);

      if (req == NULL) {

          DEBUG(1, ("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;

      }
@@ -83,6 +87,7 @@

      int ret;

      int pam_status = PAM_SYSTEM_ERR;

      int dp_err;

+     hash_value_t value;

  

      ret = krb5_auth_recv(req, &pam_status, &dp_err);

      talloc_free(req);
@@ -90,13 +95,34 @@

          DEBUG(1, ("krb5_auth request failed.\n"));

          if (auth_data->renew_data != NULL) {

              DEBUG(5, ("Giving back pam data.\n"));

-             talloc_steal(auth_data->renew_data, auth_data->pd);

+             auth_data->renew_data->pd = talloc_steal(auth_data->renew_data,

+                                                      auth_data->pd);

          }

      } else {

          switch (pam_status) {

              case PAM_SUCCESS:

                  DEBUG(4, ("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(5, ("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(1, ("hash_delete failed.\n"));

+                         }

+                     }

+                 }

                  break;

              case PAM_AUTHINFO_UNAVAIL:

              case PAM_AUTHTOK_LOCK_BUSY:
@@ -105,7 +131,8 @@

                            auth_data->pd->user));

                  if (auth_data->renew_data != NULL) {

                      DEBUG(5, ("Giving back pam data.\n"));

-                     talloc_steal(auth_data->renew_data, auth_data->pd);

+                     auth_data->renew_data->pd = talloc_steal(auth_data->renew_data,

+                                                              auth_data->pd);

                  }

                  break;

              default:
@@ -144,12 +171,23 @@

          renew_data = talloc_get_type(entries[c].value.ptr, struct renew_data);

          DEBUG(9, ("Checking [%s] for renewal at [%.24s].\n", renew_data->ccfile,

                    ctime(&renew_data->start_renew_at)));

-         if (renew_data->start_renew_at < now) {

+         /* 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(1, ("talloc_zero failed.\n"));

              } else {

-                 auth_data->pd = talloc_steal(auth_data, renew_data->pd);

+ /* 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;
@@ -187,12 +225,19 @@

  

  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_tgt_ctx->added_to_online_callbacks = false;

      renew_handler(renew_tgt_ctx);

  }

  
@@ -203,6 +248,9 @@

      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);

  }

  
@@ -212,29 +260,22 @@

      int ret;

  

      if (be_is_offline(renew_tgt_ctx->be_ctx)) {

-         if (renew_tgt_ctx->added_to_online_callbacks) {

-             DEBUG(3, ("Renewal task was already added to online callbacks.\n"));

-             return;

-         }

-         DEBUG(7, ("Offline, adding renewal task to online callbacks.\n"));

-         ret = be_add_online_cb(renew_tgt_ctx->krb5_ctx, renew_tgt_ctx->be_ctx,

-                                renew_tgt_online_callback, renew_tgt_ctx, NULL);

-         if (ret == EOK) {

-             renew_tgt_ctx->added_to_online_callbacks = true;

-             return;

-         }

+         DEBUG(4, ("Offline, disable renew timer.\n"));

+         return;

+     }

  

-         DEBUG(1, ("Failed to add the renewal task to online callbacks, "

-                   "continue normal operation.\n"));

-     } else {

-         ret = renew_all_tgts(renew_tgt_ctx);

-         if (ret != EOK) {

-             DEBUG(1, ("renew_all_tgts failed. "

-                       "Disabling automatic TGT renewal\n"));

-             sss_log(SSS_LOG_ERR, "Disabling automatic TGT renewal.");

-             talloc_zfree(renew_tgt_ctx);

-             return;

-         }

+     ret = renew_all_tgts(renew_tgt_ctx);

+     if (ret != EOK) {

+         DEBUG(1, ("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(7, ("There is an active renewal timer, doing nothing.\n"));

+         return;

      }

  

      DEBUG(7, ("Adding new renew timer.\n"));
@@ -266,6 +307,139 @@

      DEBUG(1, ("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(6, ("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(9, ("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(1, ("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(7, ("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(1, ("add_tgt_to_renew_table failed, "

+                       "automatic renewal not possible.\n"));

+         }

+     } else {

+         DEBUG(9, ("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"=*)";

+     const char *ccache_attrs[] = { SYSDB_CCACHE_FILE, SYSDB_UPN, SYSDB_NAME,

+                                    NULL };

+     size_t msgs_count = 0;

+     struct ldb_message **msgs = NULL;

+     size_t c;

+     const char *ccache_file;

+     const char *upn;

+     const char *user_name;

+ 

+     tmp_ctx = talloc_new(NULL);

+     if (tmp_ctx == NULL) {

+         DEBUG(1, ("talloc_new failed.\n"));

+         return ENOMEM;

+     }

+ 

+     ret = sysdb_search_users(tmp_ctx, renew_tgt_ctx->be_ctx->sysdb,

+                              renew_tgt_ctx->be_ctx->domain, ccache_filter,

+                              ccache_attrs, &msgs_count, &msgs);

+     if (ret != EOK) {

+         DEBUG(1, ("sysdb_search_users failed.\n"));

+         goto done;

+     }

+ 

+     if (msgs_count == 0) {

+         DEBUG(9, ("No entries with ccache file found in cache.\n"));

+         ret = EOK;

+         goto done;

+     }

+     DEBUG(9, ("Found [%d] 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(1, ("No user name found, this is a severe error, "

+                       "but we ignore it here.\n"));

+             continue;

+         }

+ 

+         upn = ldb_msg_find_attr_as_string(msgs[c], SYSDB_UPN, NULL);

+         if (upn == NULL) {

+             ret = krb5_get_simple_upn(tmp_ctx, renew_tgt_ctx->krb5_ctx,

+                                       user_name, &upn);

+             if (ret != EOK) {

+                 DEBUG(1, ("krb5_get_simple_upn failed.\n"));

+                 continue;

+             }

+             DEBUG(9, ("No upn stored in cache, using [%s].\n", upn));

+         }

+ 

+         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(5, ("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)

  {
@@ -290,8 +464,11 @@

      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;

-     krb5_ctx->renew_tgt_ctx->added_to_online_callbacks = false;

  

+     ret = check_ccache_files(krb5_ctx->renew_tgt_ctx);

+     if (ret != EOK) {

+         DEBUG(1, ("Failed to read ccache files, continuing ...\n"));

+     }

  

      next = tevent_timeval_current_ofs(krb5_ctx->renew_tgt_ctx->timer_interval,

                                        0);
@@ -304,6 +481,24 @@

          goto fail;

      }

  

+     DEBUG(7, ("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(1, ("Failed to add offline callback.\n"));

+         goto fail;

+     }

+ 

+     DEBUG(7, ("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(1, ("Failed to add renewal task to online callbacks.\n"));

+         goto fail;

+     }

+ 

      return EOK;

  

  fail:

@@ -396,3 +396,103 @@

      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;

+ 

+     kerr = krb5_init_context(&ctx);

+     if (kerr != 0) {

+         DEBUG(1, ("krb5_init_context failed.\n"));

+         goto done;

+     }

+ 

+     kerr = krb5_parse_name(ctx, client_name, &client_princ);

+     if (kerr != 0) {

+         DEBUG(1, ("krb5_parse_name failed.\n"));

+         goto done;

+     }

+ 

+     server_name = talloc_asprintf(NULL, "krbtgt/%.*s@%.*s",

+                                   krb5_princ_realm(ctx, client_princ)->length,

+                                   krb5_princ_realm(ctx, client_princ)->data,

+                                   krb5_princ_realm(ctx, client_princ)->length,

+                                   krb5_princ_realm(ctx, client_princ)->data);

+     if (server_name == NULL) {

+         kerr = KRB5_CC_NOMEM;

+         DEBUG(1, ("talloc_asprintf failed.\n"));

+         goto done;

+     }

+ 

+     kerr = krb5_parse_name(ctx, server_name, &server_princ);

+     talloc_free(server_name);

+     if (kerr != 0) {

+         DEBUG(1, ("krb5_parse_name failed.\n"));

+         goto done;

+     }

+ 

+     kerr = krb5_cc_resolve(ctx, ccache_file, &cc);

+     if (kerr != 0) {

+         DEBUG(1, ("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) {

+         DEBUG(1, ("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) {

+         DEBUG(1, ("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;

+ }

@@ -40,4 +40,7 @@

  errno_t create_ccache_dir(TALLOC_CTX *mem_ctx, const char *filename,

                            pcre *illegal_re, uid_t uid, gid_t gid,

                            bool private_path);

+ 

+ errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,

+                              struct tgt_times *tgtt);

  #endif /* __KRB5_UTILS_H__ */

file modified
+56 -39
@@ -206,6 +206,7 @@

      if (ppolicy->grace > 0 || ppolicy->expire > 0) {

          uint32_t *data;

          uint32_t *ptr;

+         int ret;

  

          data = talloc_size(pd, 2* sizeof(uint32_t));

          if (data == NULL) {
@@ -224,8 +225,12 @@

              *ptr = ppolicy->expire;

          }

  

-         pam_add_response(pd, SSS_PAM_USER_INFO, 2* sizeof(uint32_t),

-                          (uint8_t*)data);

+         ret = pam_add_response(pd, SSS_PAM_USER_INFO, 2* sizeof(uint32_t),

+                                (uint8_t*)data);

+         if (ret != EOK) {

+             DEBUG(1, ("pam_add_response failed.\n"));

+             return ret;

+         }

      }

  

      *result = SDAP_AUTH_SUCCESS;
@@ -252,15 +257,6 @@

          return EINVAL;

      }

  

-     mark = ldb_msg_find_attr_as_string(msg, SYSDB_PWD_ATTRIBUTE, NULL);

-     if (mark != NULL) {

-         DEBUG(9, ("Found pwdAttribute, "

-                   "assuming LDAP password policies are active.\n"));

- 

-         *type = PWEXPIRE_LDAP_PASSWORD_POLICY;

-         return EOK;

-     }

- 

      if (strcasecmp(pwd_policy, PWD_POL_OPT_NONE) == 0) {

          DEBUG(9, ("No password policy requested.\n"));

          return EOK;
@@ -282,8 +278,9 @@

              }

          } else {

              DEBUG(1, ("No Kerberos password expiration attributes found, "

-                       "but MIT Kerberos password policy was requested.\n"));

-             return EINVAL;

+                       "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);
@@ -325,8 +322,9 @@

              return EOK;

          } else {

              DEBUG(1, ("No shadow password attributes found, "

-                       "but shadow password policy was requested.\n"));

-             return EINVAL;

+                       "but shadow password policy was requested. "

+                       "Access will be denied.\n"));

+             return EACCES;

          }

      }

  
@@ -519,7 +517,8 @@

      next_req = be_resolve_server_send(state,

                                        state->ev,

                                        state->ctx->be,

-                                       state->sdap_service->name);

+                                       state->sdap_service->name,

+                                       state->srv == NULL ? true : false);

      if (!next_req) {

          DEBUG(1, ("be_resolve_server_send failed.\n"));

          return NULL;
@@ -547,19 +546,28 @@

          return;

      }

  

-     /* 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.");

+     /* Determine whether we need to use TLS */

+     if (sdap_is_secure_uri(state->ctx->service->uri)) {

+         DEBUG(8, ("[%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, use_tls);

+                                state->sdap_service->uri,

+                                state->sdap_service->sockaddr, use_tls);

      if (!subreq) {

          tevent_req_error(req, ENOMEM);

          return;
@@ -581,7 +589,8 @@

      if (ret) {

          if (state->srv) {

              /* mark this server as bad if connection failed */

-             fo_set_port_status(state->srv, PORT_NOT_WORKING);

+             be_fo_set_port_status(state->ctx->be,

+                                   state->srv, PORT_NOT_WORKING);

          }

          if (ret == ETIMEDOUT) {

              if (auth_get_server(req) == NULL) {
@@ -593,7 +602,7 @@

          tevent_req_error(req, ret);

          return;

      } else if (state->srv) {

-         fo_set_port_status(state->srv, PORT_WORKING);

+         be_fo_set_port_status(state->ctx->be, state->srv, PORT_WORKING);

      }

  

      ret = get_user_dn(state, state->ctx->be->sysdb, state->ctx->opts,
@@ -656,6 +665,9 @@

              if (err == ETIMEDOUT) {

                  *result = SDAP_UNAVAIL;

                  return EOK;

+             } else if (err == EACCES) {

+                 *result = SDAP_AUTH_FAILED;

+                 return EOK;

              } else {

                  *result = SDAP_ERROR;

                  return err;
@@ -894,7 +906,7 @@

  

      ret = sdap_exop_modify_passwd_recv(req, state, &result, &user_error_message);

      talloc_zfree(req);

-     if (ret) {

+     if (ret && ret != EIO) {

          state->pd->pam_status = PAM_SYSTEM_ERR;

          goto done;

      }
@@ -904,19 +916,24 @@

          state->pd->pam_status = PAM_SUCCESS;

          dp_err = DP_ERR_OK;

          break;

+     case SDAP_AUTH_PW_CONSTRAINT_VIOLATION:

+         state->pd->pam_status = PAM_NEW_AUTHTOK_REQD;

+         break;

      default:

          state->pd->pam_status = PAM_AUTHTOK_ERR;

-         if (user_error_message != NULL) {

-             ret = pack_user_info_chpass_error(state->pd, user_error_message,

-                                               &msg_len, &msg);

+         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(1, ("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(1, ("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(1, ("pam_add_response failed.\n"));

-                 }

+                 DEBUG(1, ("pam_add_response failed.\n"));

              }

          }

      }

file modified
+159 -15
@@ -37,7 +37,7 @@

      { "ldap_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_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 },
@@ -85,7 +85,10 @@

      /* 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_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_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },

+     { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }

  };

  

  struct sdap_attr_map generic_attr_map[] = {
@@ -526,35 +529,67 @@

  

  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(1, ("talloc_new failed\n"));

+         return;

+     }

+ 

      service = talloc_get_type(private_data, struct sdap_service);

-     if (!service) return;

+     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(1, ("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(1, ("resolv_get_sockaddr_address failed.\n"));

+         talloc_free(tmp_ctx);

+         return;

+     }

+ 

      if (fo_is_srv_lookup(server)) {

          if (!tmp) {

              DEBUG(1, ("Unknown service, using ldap\n"));

              tmp = SSS_LDAP_SRV_NAME;

          }

+ 

+         srv_name = fo_get_server_name(server);

+         if (srv_name == NULL) {

+             DEBUG(1, ("Could not get server host name\n"));

+             talloc_free(tmp_ctx);

+             return;

+         }

+ 

          new_uri = talloc_asprintf(service, "%s://%s:%d",

-                                   tmp,

-                                   fo_get_server_name(server),

+                                   tmp, srv_name,

                                    fo_get_server_port(server));

      } else {

-         if (tmp && ldap_is_ldap_url(tmp)) {

-             new_uri = talloc_strdup(service, tmp);

-         } else {

-             new_uri = talloc_asprintf(service, "ldap://%s",

-                                     fo_get_server_name(server));

-         }

+         new_uri = talloc_strdup(service, tmp);

      }

  

      if (!new_uri) {

          DEBUG(2, ("Failed to copy URI ...\n"));

+         talloc_free(tmp_ctx);

          return;

      }

  
@@ -563,6 +598,9 @@

      /* 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,
@@ -680,6 +718,40 @@

      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(2, ("Failed to init kerberos context\n"));

+         goto done;

+     }

+ 

+     krberr = krb5_get_default_realm(context, &krb5_realm);

+     if (krberr) {

+         DEBUG(2, ("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(0, ("Out of memory\n"));

+         goto done;

+     }

+ 

+     DEBUG(7, ("Will use default realm %s\n", realm));

+ done:

+     if (context) krb5_free_context(context);

+     return realm;

+ }

+ 

  int sdap_gssapi_init(TALLOC_CTX *mem_ctx,

                       struct dp_option *opts,

                       struct be_ctx *bectx,
@@ -689,16 +761,33 @@

      int ret;

      const char *krb5_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);

      if (krb5_servers == NULL) {

          DEBUG(1, ("Missing krb5_server option, using service discovery!\n"));

      }

  

-     krb5_realm = dp_opt_get_string(opts, SDAP_KRB5_REALM);

-     if (krb5_realm == NULL) {

-         DEBUG(0, ("Missing krb5_realm option, will use libkrb default\n"));

+     krb5_opt_realm = dp_opt_get_string(opts, SDAP_KRB5_REALM);

+     if (krb5_opt_realm == NULL) {

+         DEBUG(2, ("Missing krb5_realm option, will use libkrb default\n"));

+         krb5_realm = sdap_gssapi_get_default_realm(tmp_ctx);

+         if (krb5_realm == NULL) {

+             DEBUG(0, ("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,
@@ -731,6 +820,7 @@

      ret = EOK;

      *krb5_service = service;

  done:

+     talloc_free(tmp_ctx);

      if (ret != EOK) talloc_free(service);

      return ret;

  }
@@ -814,16 +904,23 @@

              goto done;

          }

  

+         if (lud->lud_host == NULL) {

+             DEBUG(2, ("The LDAP URI (%s) did not contain a host name\n",

+                       list[i]));

+             ldap_free_urldesc(lud);

+             continue;

+         }

+ 

          DEBUG(6, ("Added URI %s\n", list[i]));

  

          talloc_steal(service, list[i]);

  

          ret = be_fo_add_server(ctx, service->name,

                                 lud->lud_host, lud->lud_port, list[i]);

+         ldap_free_urldesc(lud);

          if (ret) {

              goto done;

          }

-         ldap_free_urldesc(lud);

      }

  

      ret = be_fo_service_add_callback(memctx, ctx, service->name,
@@ -962,6 +1059,15 @@

              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
@@ -993,3 +1099,41 @@

      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;

+ }

+ 

+ errno_t msgs2attrs_array(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(1, ("talloc_array failed.\n"));

+         return ENOMEM;

+     }

+ 

+     for (i = 0; i < count; i++) {

+         a[i] = talloc(a, struct sysdb_attrs);

+         if (a[i] == NULL) {

+             DEBUG(1, ("talloc_array 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;

+ }

@@ -34,6 +34,10 @@

  

  #define SSS_LDAP_SRV_NAME "ldap"

  

+ #define LDAP_STANDARD_URI "ldap://"

+ #define LDAP_SSL_URI "ldaps://"

+ #define LDAP_LDAPI_URI "ldapi://"

+ 

  /* a fd the child process would log into */

  extern int ldap_child_debug_fd;

  
@@ -155,4 +159,11 @@

                             const char **expected_attrs,

                             struct sysdb_attrs *recvd_attrs,

                             char ***missing_attrs);

+ 

+ bool sdap_is_secure_uri(const char *uri);

+ 

+ errno_t msgs2attrs_array(TALLOC_CTX *mem_ctx, size_t count,

+                          struct ldb_message **msgs,

+                          struct sysdb_attrs ***attrs);

+ 

  #endif /* _LDAP_COMMON_H_ */

file modified
+29 -11
@@ -171,7 +171,8 @@

                                   sdap_id_op_handle(state->op),

                                   state->attrs, state->filter,

                                   dp_opt_get_int(state->ctx->opts->basic,

-                                                 SDAP_SEARCH_TIMEOUT));

+                                                 SDAP_SEARCH_TIMEOUT),

+                                  false); /* No enumeration */

      if (!subreq) {

          tevent_req_error(req, ENOMEM);

          return;
@@ -219,14 +220,14 @@

          case BE_FILTER_NAME:

              ret = sysdb_delete_user(state, state->sysdb,

                                      state->domain, state->name, 0);

-             if (ret) {

+             if (ret != EOK && ret != ENOENT) {

                  tevent_req_error(req, ret);

                  return;

              }

              break;

  

          case BE_FILTER_IDNUM:

-             uid = (uid_t) strtouint32(state->name, &endptr, 0);

+             uid = (uid_t) strtouint32(state->name, &endptr, 10);

              if (errno || *endptr || (state->name == endptr)) {

                  tevent_req_error(req, errno ? errno : EINVAL);

                  return;
@@ -234,7 +235,7 @@

  

              ret = sysdb_delete_user(state, state->sysdb,

                                      state->domain, NULL, uid);

-             if (ret) {

+             if (ret != EOK && ret != ENOENT) {

                  tevent_req_error(req, ret);

                  return;

              }
@@ -335,9 +336,14 @@

          goto fail;

      }

  

-     state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",

-                                     attr_name, clean_name,

-                                     ctx->opts->group_map[SDAP_OC_GROUP].name);

+     state->filter =

+             talloc_asprintf(state,

+                             "(&(%s=%s)(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))",

+                             attr_name, clean_name,

+                             ctx->opts->group_map[SDAP_OC_GROUP].name,

+                             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);

      if (!state->filter) {

          DEBUG(2, ("Failed to build filter\n"));

          ret = ENOMEM;
@@ -402,7 +408,8 @@

                                    state->ctx->opts, sdap_id_op_handle(state->op),

                                    state->attrs, state->filter,

                                    dp_opt_get_int(state->ctx->opts->basic,

-                                                  SDAP_SEARCH_TIMEOUT));

+                                                  SDAP_SEARCH_TIMEOUT),

+                                   false);   /* No enumeration */

      if (!subreq) {

          tevent_req_error(req, ENOMEM);

          return;
@@ -450,14 +457,14 @@

          case BE_FILTER_NAME:

              ret = sysdb_delete_group(state, state->sysdb,

                                       state->domain, state->name, 0);

-             if (ret) {

+             if (ret != EOK && ret != ENOENT) {

                  tevent_req_error(req, ret);

                  return;

              }

              break;

  

          case BE_FILTER_IDNUM:

-             gid = (gid_t) strtouint32(state->name, &endptr, 0);

+             gid = (gid_t) strtouint32(state->name, &endptr, 10);

              if (errno || *endptr || (state->name == endptr)) {

                  tevent_req_error(req, errno ? errno : EINVAL);

                  return;
@@ -465,7 +472,7 @@

  

              ret = sysdb_delete_group(state, state->sysdb,

                                       state->domain, NULL, gid);

-             if (ret) {

+             if (ret != EOK && ret != ENOENT) {

                  tevent_req_error(req, ret);

                  return;

              }
@@ -631,6 +638,17 @@

          return;

      }

  

+     if (ret == ENOENT) {

+         ret = sysdb_delete_user(state,

+                                 state->ctx->be->sysdb,

+                                 state->ctx->be->domain,

+                                 state->name, 0);

+         if (ret != EOK && ret != ENOENT) {

+             tevent_req_error(req, ret);

+             return;

+         }

+     }

+ 

      state->dp_error = DP_ERR_OK;

      tevent_req_done(req);

  }

@@ -374,6 +374,7 @@

      size_t u_count;

      int ret;

      int i;

+     const char *posix;

  

      tmpctx = talloc_new(memctx);

      if (!tmpctx) {
@@ -412,19 +413,18 @@

              goto done;

          }

  

-         gid = (gid_t) ldb_msg_find_attr_as_uint(msgs[i], SYSDB_GIDNUM, 0);

-         if (!gid) {

-             DEBUG(2, ("Entry has no GID\n"));

-             ret = EIO;

-             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

+              */

+             gid = (gid_t) ldb_msg_find_attr_as_uint(msgs[i], SYSDB_GIDNUM, 0);

+             subfilter = talloc_asprintf(tmpctx, "(|(%s=%s)(%s=%lu))",

+                                         SYSDB_MEMBEROF, dn,

+                                         SYSDB_GIDNUM, (long unsigned) gid);

+         } else {

+             subfilter = talloc_asprintf(tmpctx, "(%s=%s)", SYSDB_MEMBEROF, dn);

          }

- 

-         /* Search for users that are members of this group, or

-          * that have this group as their primary GID

-          */

-         subfilter = talloc_asprintf(tmpctx, "(|(%s=%s)(%s=%lu))",

-                                     SYSDB_MEMBEROF, dn,

-                                     SYSDB_GIDNUM, (long unsigned) gid);

          if (!subfilter) {

              DEBUG(2, ("Failed to build filter\n"));

              ret = ENOMEM;

@@ -441,19 +441,25 @@

      state->op = op;

  

      if (ctx->srv_opts && ctx->srv_opts->max_user_value && !purge) {

-         state->filter = talloc_asprintf(state,

-                                "(&(%s=*)(objectclass=%s)(%s>=%s)(!(%s=%s)))",

-                                ctx->opts->user_map[SDAP_AT_USER_NAME].name,

-                                ctx->opts->user_map[SDAP_OC_USER].name,

-                                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);

+         state->filter = talloc_asprintf(

+                 state,

+                 "(&(objectclass=%s)(%s=*)(%s=*)(%s=*)(%s>=%s)(!(%s=%s)))",

+                 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_GID].name,

+                 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);

      } else {

-         state->filter = talloc_asprintf(state,

-                                "(&(%s=*)(objectclass=%s))",

-                                ctx->opts->user_map[SDAP_AT_USER_NAME].name,

-                                ctx->opts->user_map[SDAP_OC_USER].name);

+         state->filter = talloc_asprintf(

+                 state,

+                 "(&(objectclass=%s)(%s=*)(%s=*)(%s=*))",

+                 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_GID].name);

      }

      if (!state->filter) {

          DEBUG(2, ("Failed to build filter\n"));
@@ -473,7 +479,8 @@

                                   sdap_id_op_handle(state->op),

                                   state->attrs, state->filter,

                                   dp_opt_get_int(state->ctx->opts->basic,

-                                                 SDAP_ENUM_SEARCH_TIMEOUT));

+                                                 SDAP_ENUM_SEARCH_TIMEOUT),

+                                  true); /* Enumeration */

      if (!subreq) {

          ret = ENOMEM;

          goto fail;
@@ -546,19 +553,25 @@

      state->op = op;

  

      if (ctx->srv_opts && ctx->srv_opts->max_group_value && !purge) {

-         state->filter = talloc_asprintf(state,

-                               "(&(%s=*)(objectclass=%s)(%s>=%s)(!(%s=%s)))",

-                               ctx->opts->group_map[SDAP_AT_GROUP_NAME].name,

-                               ctx->opts->group_map[SDAP_OC_GROUP].name,

-                               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);

+         state->filter = talloc_asprintf(

+                 state,

+                 "(&(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0)))(%s>=%s)(!(%s=%s)))",

+                 ctx->opts->group_map[SDAP_OC_GROUP].name,

+                 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,

+                 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);

      } else {

-         state->filter = talloc_asprintf(state,

-                               "(&(%s=*)(objectclass=%s))",

-                               ctx->opts->group_map[SDAP_AT_GROUP_NAME].name,

-                               ctx->opts->group_map[SDAP_OC_GROUP].name);

+         state->filter = talloc_asprintf(

+                 state,

+                 "(&(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))",

+                 ctx->opts->group_map[SDAP_OC_GROUP].name,

+                 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);

      }

      if (!state->filter) {

          DEBUG(2, ("Failed to build filter\n"));
@@ -577,7 +590,8 @@

                                   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_ENUM_SEARCH_TIMEOUT),

+                                  true); /* Enumeration */

      if (!subreq) {

          ret = ENOMEM;

          goto fail;

file modified
+54 -52
@@ -107,7 +107,7 @@

      ret = ldap_set_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);

      if (ret != LDAP_OPT_SUCCESS) {

          DEBUG(1, ("ldap_set_option failed [%s], ignored.\n",

-                   ldap_err2string(ret)));

+                   sss_ldap_err2string(ret)));

      }

  

      attrs = sysdb_new_attrs(memctx);
@@ -117,7 +117,7 @@

      if (!str) {

          ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);

          DEBUG(1, ("ldap_get_dn failed: %d(%s)\n",

-                   lerrno, ldap_err2string(lerrno)));

+                   lerrno, sss_ldap_err2string(lerrno)));

          ret = EIO;

          goto fail;

      }
@@ -165,7 +165,7 @@

      if (!str) {

          ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);

          DEBUG(1, ("Entry has no attributes [%d(%s)]!?\n",

-                   lerrno, ldap_err2string(lerrno)));

+                   lerrno, sss_ldap_err2string(lerrno)));

          if (map) {

              ret = EINVAL;

              goto fail;
@@ -204,7 +204,7 @@

                  ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);

                  if (lerrno != LDAP_SUCCESS) {

                      DEBUG(1, ("LDAP Library error: %d(%s)",

-                               lerrno, ldap_err2string(lerrno)));

+                               lerrno, sss_ldap_err2string(lerrno)));

                      ret = EIO;

                      goto fail;

                  }
@@ -236,7 +236,7 @@

      ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);

      if (lerrno) {

          DEBUG(1, ("LDAP Library error: %d(%s)",

-                   lerrno, ldap_err2string(lerrno)));

+                   lerrno, sss_ldap_err2string(lerrno)));

          ret = EIO;

          goto fail;

      }
@@ -291,14 +291,14 @@

      ret = ldap_set_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);

      if (ret != LDAP_OPT_SUCCESS) {

          DEBUG(1, ("ldap_set_option failed [%s], ignored.\n",

-                   ldap_err2string(ret)));

+                   sss_ldap_err2string(ret)));

      }

  

      str = ldap_get_dn(sh->ldap, sm->msg);

      if (!str) {

          ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno);

          DEBUG(1, ("ldap_get_dn failed: %d(%s)\n",

-                   lerrno, ldap_err2string(lerrno)));

+                   lerrno, sss_ldap_err2string(lerrno)));

          return EIO;

      }

  
@@ -340,7 +340,7 @@

          ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,

                                &ldap_opt_x_tls_require_cert);

          if (ret != LDAP_OPT_SUCCESS) {

-             DEBUG(1, ("ldap_set_option failed: %s\n", ldap_err2string(ret)));

+             DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret)));

              return EIO;

          }

      }
@@ -349,7 +349,7 @@

      if (tls_opt) {

          ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, tls_opt);

          if (ret != LDAP_OPT_SUCCESS) {

-             DEBUG(1, ("ldap_set_option failed: %s\n", ldap_err2string(ret)));

+             DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret)));

              return EIO;

          }

      }
@@ -358,7 +358,7 @@

      if (tls_opt) {

          ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR, tls_opt);

          if (ret != LDAP_OPT_SUCCESS) {

-             DEBUG(1, ("ldap_set_option failed: %s\n", ldap_err2string(ret)));

+             DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret)));

              return EIO;

          }

      }
@@ -367,7 +367,7 @@

      if (tls_opt) {

          ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, tls_opt);

          if (ret != LDAP_OPT_SUCCESS) {

-             DEBUG(1, ("ldap_set_option failed: %s\n", ldap_err2string(ret)));

+             DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret)));

              return EIO;

          }

      }
@@ -376,7 +376,7 @@

      if (tls_opt) {

          ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, tls_opt);

          if (ret != LDAP_OPT_SUCCESS) {

-             DEBUG(1, ("ldap_set_option failed: %s\n", ldap_err2string(ret)));

+             DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret)));

              return EIO;

          }

      }
@@ -385,7 +385,7 @@

      if (tls_opt) {

          ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, tls_opt);

          if (ret != LDAP_OPT_SUCCESS) {

-             DEBUG(1, ("ldap_set_option failed: %s\n", ldap_err2string(ret)));

+             DEBUG(1, ("ldap_set_option failed: %s\n", sss_ldap_err2string(ret)));

              return EIO;

          }

      }
@@ -606,46 +606,48 @@

  

      last_usn_name = opts->gen_map[SDAP_AT_LAST_USN].name;

      entry_usn_name = opts->gen_map[SDAP_AT_ENTRY_USN].name;

-     if (last_usn_name) {

-         ret = sysdb_attrs_get_string(rootdse,

-                                       last_usn_name, &last_usn_value);

-         if (ret != EOK) {

-             switch (ret) {

-             case ENOENT:

-                 DEBUG(1, ("%s configured but not found in rootdse!\n",

-                           opts->gen_map[SDAP_AT_LAST_USN].opt_name));

-                 break;

-             case ERANGE:

-                 DEBUG(1, ("Multiple values of %s found in rootdse!\n",

-                           opts->gen_map[SDAP_AT_LAST_USN].opt_name));

-                 break;

-             default:

-                 DEBUG(1, ("Unkown error (%d) checking rootdse!\n", ret));

-             }

-         } else {

-             if (!entry_usn_name) {

-                 DEBUG(1, ("%s found in rootdse but %s is not set!\n",

-                           last_usn_name,

-                           opts->gen_map[SDAP_AT_ENTRY_USN].opt_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(1, ("%s configured but not found in rootdse!\n",

+                               opts->gen_map[SDAP_AT_LAST_USN].opt_name));

+                     break;

+                 case ERANGE:

+                     DEBUG(1, ("Multiple values of %s found in rootdse!\n",

+                               opts->gen_map[SDAP_AT_LAST_USN].opt_name));

+                     break;

+                 default:

+                     DEBUG(1, ("Unkown error (%d) checking rootdse!\n", ret));

+                 }

              } else {

-                 so->supports_usn = true;

+                 if (!entry_usn_name) {

+                     DEBUG(1, ("%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;

+                 }

              }

-         }

-     } 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;

-                 last_usn_name = usn_attrs[i].last_name;

-                 break;

+         } 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;

+                     last_usn_name = usn_attrs[i].last_name;

+                     break;

+                 }

              }

          }

      }
@@ -746,7 +748,7 @@

          ret = sss_ldap_control_create(oid, iscritical, value, dupval, ctrlp);

          if (ret != LDAP_SUCCESS) {

              DEBUG(1, ("sss_ldap_control_create failed [%d][%s].\n",

-                       ret, ldap_err2string(ret)));

+                       ret, sss_ldap_err2string(ret)));

          }

      } else {

          DEBUG(3, ("Server does not support the requested control [%s].\n", oid));

file modified
+6 -10
@@ -26,16 +26,6 @@

  #include <ldap.h>

  #include "util/sss_ldap.h"

  

- #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

- 

  struct sdap_msg {

      struct sdap_msg *next;

      LDAPMessage *msg;
@@ -87,6 +77,7 @@

      bool connected;

      /* Authentication ticket expiration time (if any) */

      time_t expire_time;

+     ber_int_t page_size;

  

      struct sdap_fd_events *sdap_fd_events;

  
@@ -107,6 +98,7 @@

      char *name;

      char *uri;

      char *kinit_service_name;

+     struct sockaddr_storage *sockaddr;

  };

  

  struct sdap_ppolicy_data {
@@ -149,6 +141,7 @@

      SDAP_AUTH_SUCCESS,

      SDAP_AUTH_FAILED,

      SDAP_AUTH_PW_EXPIRED,

+     SDAP_AUTH_PW_CONSTRAINT_VIOLATION,

      SDAP_ACCT_EXPIRED

  };

  
@@ -201,6 +194,9 @@

      SDAP_CHPASS_DNS_SERVICE_NAME,

      SDAP_ENUM_SEARCH_TIMEOUT,

      SDAP_DISABLE_AUTH_TLS,

+     SDAP_PAGE_SIZE,

+     SDAP_SASL_CANONICALIZE,

+     SDAP_DISABLE_PAGING,

  

      SDAP_OPTS_BASIC /* opts counter */

  };

@@ -52,12 +52,6 @@

      }

  }

  

- static struct tevent_req *sdap_access_send(TALLOC_CTX *mem_ctx,

-                                            struct tevent_context *ev,

-                                            struct be_ctx *be_ctx,

-                                            struct sdap_access_ctx *access_ctx,

-                                            struct pam_data *pd);

- 

  static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,

                                               struct tevent_context *ev,

                                               struct be_ctx *be_ctx,
@@ -123,11 +117,12 @@

  };

  

  static errno_t select_next_rule(struct tevent_req *req);

- static struct tevent_req *sdap_access_send(TALLOC_CTX *mem_ctx,

-                                            struct tevent_context *ev,

-                                            struct be_ctx *be_ctx,

-                                            struct sdap_access_ctx *access_ctx,

-                                            struct pam_data *pd)

+ struct tevent_req *

+ sdap_access_send(TALLOC_CTX *mem_ctx,

+                  struct tevent_context *ev,

+                  struct be_ctx *be_ctx,

+                  struct sdap_access_ctx *access_ctx,

+                  struct pam_data *pd)

  {

      errno_t ret;

      struct sdap_access_req_ctx *state;
@@ -750,7 +745,8 @@

                                     state->filter, NULL,

                                     NULL, 0,

                                     dp_opt_get_int(state->sdap_ctx->opts->basic,

-                                                   SDAP_SEARCH_TIMEOUT));

+                                                   SDAP_SEARCH_TIMEOUT),

+                                    false);

      if (subreq == NULL) {

          DEBUG(1, ("Could not start LDAP communication\n"));

          state->pam_status = PAM_SYSTEM_ERR;
@@ -1001,13 +997,13 @@

  

      if (state->pam_status != PAM_SUCCESS) {

          DEBUG(4, ("No matching service rule found\n"));

-     }

  

-     ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,

-                            sizeof(AUTHR_SRV_NO_MATCH_MSG),

-                            (const uint8_t *) AUTHR_SRV_NO_MATCH_MSG);

-     if (ret != EOK) {

-         DEBUG(1, ("pam_add_response failed.\n"));

+         ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,

+                                sizeof(AUTHR_SRV_NO_MATCH_MSG),

+                                (const uint8_t *) AUTHR_SRV_NO_MATCH_MSG);

+         if (ret != EOK) {

+             DEBUG(1, ("pam_add_response failed.\n"));

+         }

      }

  

      ret = EOK;
@@ -1057,7 +1053,8 @@

      return;

  }

  

- static errno_t sdap_access_recv(struct tevent_req *req, int *pam_status)

+ errno_t

+ sdap_access_recv(struct tevent_req *req, int *pam_status)

  {

      struct sdap_access_req_ctx *state =

              tevent_req_data(req, struct sdap_access_req_ctx);

@@ -55,4 +55,13 @@

  

  void ldap_pam_access_handler(struct be_req *breq);

  

+ struct tevent_req *

+ sdap_access_send(TALLOC_CTX *mem_ctx,

+                  struct tevent_context *ev,

+                  struct be_ctx *be_ctx,

+                  struct sdap_access_ctx *access_ctx,

+                  struct pam_data *pd);

+ errno_t

+ sdap_access_recv(struct tevent_req *req, int *pam_status);

+ 

  #endif /* SDAP_ACCESS_H_ */

file modified
+248 -39
@@ -172,6 +172,7 @@

  

      if (!sh->connected || !sh->ldap) {

          DEBUG(2, ("ERROR: LDAP connection is not connected!\n"));

+         sdap_handle_release(sh);

          return;

      }

  
@@ -579,7 +580,7 @@

      }

  

      DEBUG(3, ("ldap_extended_operation result: %s(%d), %s\n",

-               ldap_err2string(state->result), state->result, errmsg));

+             sss_ldap_err2string(state->result), state->result, errmsg));

  

      if (state->result != LDAP_SUCCESS) {

          if (errmsg) {
@@ -614,15 +615,22 @@

      struct sdap_exop_modify_passwd_state *state = tevent_req_data(req,

                                           struct sdap_exop_modify_passwd_state);

  

-     *result = SDAP_ERROR;

      *user_error_message = talloc_steal(mem_ctx, state->user_error_message);

  

-     TEVENT_REQ_RETURN_ON_ERROR(req);

- 

-     if (state->result == LDAP_SUCCESS) {

-         *result = SDAP_SUCCESS;

+     switch (state->result) {

+         case LDAP_SUCCESS:

+             *result = SDAP_SUCCESS;

+             break;

+         case LDAP_CONSTRAINT_VIOLATION:

+             *result = SDAP_AUTH_PW_CONSTRAINT_VIOLATION;

+             break;

+         default:

+             *result = SDAP_ERROR;

+             break;

      }

  

+     TEVENT_REQ_RETURN_ON_ERROR(req);

+ 

      return EOK;

  }

  
@@ -673,7 +681,8 @@

                                     "", LDAP_SCOPE_BASE,

                                     "(objectclass=*)", attrs, NULL, 0,

                                     dp_opt_get_int(state->opts->basic,

-                                                   SDAP_SEARCH_TIMEOUT));

+                                                   SDAP_SEARCH_TIMEOUT),

+                                    false);

      if (!subreq) {

          talloc_zfree(req);

          return NULL;
@@ -748,21 +757,25 @@

      const char **attrs;

      struct sdap_attr_map *map;

      int map_num_attrs;

+     int timeout;

+     bool allow_paging;

  

      struct sdap_op *op;

  

+     struct berval cookie;

+ 

      size_t reply_max;

      size_t reply_count;

      struct sysdb_attrs **reply;

  };

  

+ static errno_t sdap_get_generic_step(struct tevent_req *req);

+ static void sdap_get_generic_done(struct sdap_op *op,

+                                  struct sdap_msg *reply,

+                                  int error, void *pvt);

  static errno_t add_to_reply(struct sdap_get_generic_state *state,

                              struct sysdb_attrs *msg);

  

- static void sdap_get_generic_done(struct sdap_op *op,

-                                   struct sdap_msg *reply,

-                                   int error, void *pvt);

- 

  struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx,

                                           struct tevent_context *ev,

                                           struct sdap_options *opts,
@@ -773,15 +786,12 @@

                                           const char **attrs,

                                           struct sdap_attr_map *map,

                                           int map_num_attrs,

-                                          int timeout)

+                                          int timeout,

+                                          bool allow_paging)

  {

-     struct tevent_req *req = NULL;

-     struct sdap_get_generic_state *state = NULL;

-     char *errmsg;

-     int lret;

-     int optret;

-     int ret;

-     int msgid;

+     errno_t ret;

+     struct sdap_get_generic_state *state;

+     struct tevent_req *req;

  

      req = tevent_req_create(memctx, &state, struct sdap_get_generic_state);

      if (!req) return NULL;
@@ -799,6 +809,48 @@

      state->reply_max = 0;

      state->reply_count = 0;

      state->reply = NULL;

+     state->timeout = timeout;

+     state->cookie.bv_len = 0;

+     state->cookie.bv_val = NULL;

+ 

+     /* Be extra careful and never allow paging for BASE searches,

+      * even if requested.

+      */

+     if (scope == LDAP_SCOPE_BASE) {

+         state->allow_paging = false;

+     } else {

+         state->allow_paging = allow_paging;

+     }

+ 

+     ret = sdap_get_generic_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_step(struct tevent_req *req)

+ {

+     struct sdap_get_generic_state *state =

+             tevent_req_data(req, struct sdap_get_generic_state);

+     char *errmsg;

+     int lret;

+     int optret;

+     errno_t ret;

+     int msgid;

+     bool disable_paging;

+ 

+     LDAPControl *page_control = NULL;

+     LDAPControl *m_controls[2] = { NULL, 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(6, ("calling ldap_search_ext with [%s][%s].\n", state->filter,

                                                            state->search_base));
@@ -812,52 +864,67 @@

          }

      }

  

+     disable_paging = dp_opt_get_bool(state->opts->basic, SDAP_DISABLE_PAGING);

+ 

+     if (!disable_paging && state->allow_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;

+         }

+         m_controls[0] = page_control;

+     }

+ 

      lret = ldap_search_ext(state->sh->ldap, state->search_base,

                             state->scope, state->filter,

                             discard_const(state->attrs),

-                            false, NULL, NULL, NULL, 0, &msgid);

+                            false, m_controls, NULL, NULL, 0, &msgid);

+     ldap_control_free(page_control);

+     m_controls[0] = NULL;

      if (lret != LDAP_SUCCESS) {

-         DEBUG(3, ("ldap_search_ext failed: %s\n", ldap_err2string(lret)));

+         DEBUG(3, ("ldap_search_ext failed: %s\n", sss_ldap_err2string(lret)));

          if (lret == LDAP_SERVER_DOWN) {

              ret = ETIMEDOUT;

-             optret = ldap_get_option(state->sh->ldap,

-                                      SDAP_DIAGNOSTIC_MESSAGE,

-                                      (void*)&errmsg);

+             optret = sss_ldap_get_diagnostic_msg(state, state->sh->ldap,

+                                                  &errmsg);

              if (optret == LDAP_SUCCESS) {

                  DEBUG(3, ("Connection error: %s\n", errmsg));

                  sss_log(SSS_LOG_ERR, "LDAP connection error: %s", errmsg);

-                 ldap_memfree(errmsg);

              }

              else {

                  sss_log(SSS_LOG_ERR, "LDAP connection error, %s",

-                                      ldap_err2string(lret));

+                                      sss_ldap_err2string(lret));

              }

          }

  

          else {

              ret = EIO;

          }

-         goto fail;

+         goto done;

      }

      DEBUG(8, ("ldap_search_ext called, msgid = %d\n", msgid));

  

      ret = sdap_op_add(state, state->ev, state->sh, msgid,

-                       sdap_get_generic_done, req, timeout,

+                       sdap_get_generic_done, req,

+                       state->timeout,

                        &state->op);

      if (ret != EOK) {

          DEBUG(1, ("Failed to set up operation!\n"));

-         goto fail;

+         goto done;

      }

  

-     return req;

- 

- fail:

-     tevent_req_error(req, ret);

-     tevent_req_post(req, ev);

-     return req;

+ done:

+     return ret;

  }

  

- 

  static void sdap_get_generic_done(struct sdap_op *op,

                                   struct sdap_msg *reply,

                                   int error, void *pvt)
@@ -869,6 +936,11 @@

      char *errmsg = 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);
@@ -906,7 +978,8 @@

  

      case LDAP_RES_SEARCH_RESULT:

          ret = ldap_parse_result(state->sh->ldap, reply->msg,

-                                 &result, NULL, &errmsg, NULL, NULL, 0);

+                                 &result, NULL, &errmsg, NULL,

+                                 &returned_controls, 0);

          if (ret != LDAP_SUCCESS) {

              DEBUG(2, ("ldap_parse_result failed (%d)\n", state->op->msgid));

              tevent_req_error(req, EIO);
@@ -914,14 +987,61 @@

          }

  

          DEBUG(6, ("Search result: %s(%d), %s\n",

-                   ldap_err2string(result), result, errmsg));

+                   sss_ldap_err2string(result), result, errmsg));

  

          if (result != LDAP_SUCCESS && result != LDAP_NO_SUCH_OBJECT) {

              DEBUG(2, ("Unexpected result from ldap: %s(%d), %s\n",

-                       ldap_err2string(result), result, errmsg));

+                       sss_ldap_err2string(result), result, errmsg));

          }

          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(1, ("Could not determine page control"));

+             tevent_req_error(req, EIO);

+             return;

+         }

+         DEBUG(7, ("Total count [%lu]\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_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;

  
@@ -967,3 +1087,92 @@

      return EOK;

  }

  

+ errno_t sdap_check_aliases(struct sysdb_ctx *sysdb,

+                            struct sysdb_attrs *user_attrs,

+                            struct sss_domain_info *dom,

+                            struct sdap_options *opts,

+                            bool steal_memberships)

+ {

+     errno_t ret;

+     const char **aliases = NULL;

+     const char *name = NULL;

+     struct ldb_message *msg;

+     TALLOC_CTX *tmp_ctx = NULL;

+     char **parents;

+     uid_t alias_uid;

+     int i;

+ 

+     tmp_ctx = talloc_new(NULL);

+     if (!tmp_ctx) return ENOMEM;

+ 

+     ret = sysdb_attrs_primary_name(sysdb, user_attrs,

+                                    opts->user_map[SDAP_AT_USER_NAME].name,

+                                    &name);

+     if (ret != EOK) {

+         DEBUG(1, ("Could not get the primary name\n"));

+         goto done;

+     }

+ 

+     ret = sysdb_attrs_get_aliases(tmp_ctx, user_attrs, name, &aliases);

+     if (ret != EOK) {

+         DEBUG(1, ("Failed to get the alias list\n"));

+         goto done;

+     }

+ 

+     for (i = 0; aliases[i]; i++) {

+         /* In RFC2307 schema, another group might be referencing user

+          * using secondary name, so there might be fake users in the cache

+          * from a previous getgr call */

+         ret = sysdb_search_user_by_name(tmp_ctx, sysdb, dom,

+                                         aliases[i], NULL, &msg);

+         if (ret && ret != ENOENT) {

+             DEBUG(1, ("Error searching the cache\n"));

+             goto done;

+         } else if (ret == ENOENT) {

+             DEBUG(9, ("No user with primary name same as alias %s\n", aliases[i]));

+             continue;

+         }

+ 

+         alias_uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0);

+         if (alias_uid) {

+             DEBUG(1, ("Cache contains non-fake user with same name "

+                       "as alias %s\n", aliases[i]));

+             ret = EIO;

+             goto done;

+         }

+         DEBUG(7, ("%s is a fake user\n", aliases[i]));

+ 

+         if (steal_memberships) {

+             /* Get direct sysdb parents */

+             ret = sysdb_get_direct_parents(tmp_ctx, sysdb, dom,

+                                            SYSDB_MEMBER_USER,

+                                            aliases[i], &parents);

+             if (ret) {

+                 DEBUG(1, ("Could not get direct parents for %s: %d [%s]\n",

+                           aliases[i], ret, strerror(ret)));

+                 goto done;

+             }

+ 

+             ret = sysdb_update_members(sysdb, dom, name, SYSDB_MEMBER_USER,

+                                        (const char *const *) parents,

+                                        NULL);

+             if (ret != EOK) {

+                 DEBUG(1, ("Membership update failed [%d]: %s\n",

+                           ret, strerror(ret)));

+                 goto done;

+             }

+         }

+ 

+         ret = sysdb_delete_user(tmp_ctx, sysdb, dom, aliases[i], alias_uid);

+         if (ret) {

+             DEBUG(1, ("Error deleting fake user %s\n", aliases[i]));

+             goto done;

+         }

+     }

+ 

+     ret = EOK;

+ done:

+     talloc_free(tmp_ctx);

+     return ret;

+ }

+ 

@@ -22,6 +22,8 @@

  #ifndef _SDAP_ASYNC_H_

  #define _SDAP_ASYNC_H_

  

+ #include <sys/types.h>

+ #include <sys/socket.h>

  #include <talloc.h>

  #include <tevent.h>

  #include "providers/dp_backend.h"
@@ -32,6 +34,7 @@

                                       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,
@@ -45,7 +48,8 @@

                                         struct sdap_handle *sh,

                                         const char **attrs,

                                         const char *wildcard,

-                                        int timeout);

+                                        int timeout,

+                                        bool enumeration);

  int sdap_get_users_recv(struct tevent_req *req,

                          TALLOC_CTX *mem_ctx, char **timestamp);

  
@@ -57,7 +61,8 @@

                                         struct sdap_handle *sh,

                                         const char **attrs,

                                         const char *wildcard,

-                                        int timeout);

+                                        int timeout,

+                                        bool enumeration);

  int sdap_get_groups_recv(struct tevent_req *req,

                           TALLOC_CTX *mem_ctx, char **timestamp);

  
@@ -144,8 +149,16 @@

                                           const char **attrs,

                                           struct sdap_attr_map *map,

                                           int map_num_attrs,

-                                          int timeout);

+                                          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);

+ 

+ errno_t sdap_check_aliases(struct sysdb_ctx *sysdb,

+                            struct sysdb_attrs *user_attrs,

+                            struct sss_domain_info *dom,

+                            struct sdap_options *opts,

+                            bool steal_memberships);

+ 

  #endif /* _SDAP_ASYNC_H_ */

@@ -40,7 +40,7 @@

  {

      struct ldb_message_element *el;

      int ret;

-     const char *name;

+     const char *name = NULL;

      const char *pwd;

      const char *gecos;

      const char *homedir;
@@ -49,25 +49,36 @@

      gid_t gid;

      struct sysdb_attrs *user_attrs;

      char *upn = NULL;

-     int i;

+     size_t i;

      char *val = NULL;

      int cache_timeout;

      char *usn_value = NULL;

      size_t c;

      char **missing = NULL;

+     const char **aliases = NULL;

+     TALLOC_CTX *tmpctx = NULL;

  

      DEBUG(9, ("Save user\n"));

  

-     ret = sysdb_attrs_get_el(attrs,

-                              opts->user_map[SDAP_AT_USER_NAME].sys_name, &el);

-     if (el->num_values == 0) {

-         ret = EINVAL;

+     tmpctx = talloc_new(memctx);

+     if (!tmpctx) {

+         ret = ENOMEM;

+         goto fail;

      }

-     if (ret) {

+ 

+     user_attrs = sysdb_new_attrs(tmpctx);

+     if (user_attrs == NULL) {

+         ret = ENOMEM;

+         goto fail;

+     }

+ 

+     ret = sysdb_attrs_primary_name(ctx, attrs,

+                                    opts->user_map[SDAP_AT_USER_NAME].name,

+                                    &name);

+     if (ret != EOK) {

          DEBUG(1, ("Failed to save the user - entry has no name attribute\n"));

-         return ret;

+         goto fail;

      }

-     name = (const char *)el->values[0].data;

  

      ret = sysdb_attrs_get_el(attrs,

                               opts->user_map[SDAP_AT_USER_PWD].sys_name, &el);
@@ -81,6 +92,15 @@

      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 fail;

+         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 fail;
@@ -129,12 +149,6 @@

          goto fail;

      }

  

-     user_attrs = sysdb_new_attrs(memctx);

-     if (user_attrs == NULL) {

-         ret = ENOMEM;

-         goto fail;

-     }

- 

      ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);

      if (ret) {

          goto fail;
@@ -268,10 +282,24 @@

          }

      }

  

+     ret = sysdb_attrs_get_aliases(tmpctx, attrs, name, &aliases);

+     if (ret != EOK) {

+         DEBUG(1, ("Failed to get the alias list"));

+         goto fail;

+     }

+ 

+     for (i = 0; aliases[i]; i++) {

+         ret = sysdb_attrs_add_string(user_attrs, SYSDB_NAME_ALIAS,

+                                      aliases[i]);

+         if (ret) {

+             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(NULL, opts->user_map, SDAP_OPTS_USER,

+     ret = list_missing_attrs(user_attrs, opts->user_map, SDAP_OPTS_USER,

                               ldap_attrs, attrs, &missing);

      if (ret != EOK) {

          goto fail;
@@ -285,21 +313,23 @@

  

      DEBUG(6, ("Storing info for user %s\n", name));

  

-     ret = sysdb_store_user(memctx, ctx, dom,

+     ret = sysdb_store_user(user_attrs, ctx, dom,

                             name, pwd, uid, gid, gecos, homedir, shell,

                             user_attrs, missing, cache_timeout);

      if (ret) goto fail;

-     talloc_zfree(missing);

  

      if (_usn_value) {

          *_usn_value = usn_value;

      }

  

+     talloc_steal(memctx, user_attrs);

+     talloc_free(tmpctx);

      return EOK;

  

  fail:

-     DEBUG(2, ("Failed to save user %s\n", name));

-     talloc_free(missing);

+     DEBUG(2, ("Failed to save user [%s]\n",

+               name ? name : "Unknown"));

+     talloc_free(tmpctx);

      return ret;

  }

  
@@ -351,6 +381,12 @@

              DEBUG(9, ("User %d processed!\n", i));

          }

  

+         ret = sdap_check_aliases(sysdb, users[i], dom,

+                                  opts, true);

+         if (ret) {

+             DEBUG(2, ("Failed to check aliases for user %d. Ignoring.\n", i));

+         }

+ 

          if (usn_value) {

              if (higher_usn) {

                  if ((strlen(usn_value) > strlen(higher_usn)) ||
@@ -392,6 +428,7 @@

      struct sysdb_ctx *sysdb;

      const char **attrs;

      const char *filter;

+     bool enumeration;

  

      char *higher_usn;

      struct sysdb_attrs **users;
@@ -408,7 +445,8 @@

                                         struct sdap_handle *sh,

                                         const char **attrs,

                                         const char *filter,

-                                        int timeout)

+                                        int timeout,

+                                        bool enumeration)

  {

      struct tevent_req *req, *subreq;

      struct sdap_get_users_state *state;
@@ -426,6 +464,7 @@

      state->higher_usn = NULL;

      state->users =  NULL;

      state->count = 0;

+     state->enumeration = enumeration;

  

      subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,

                                     dp_opt_get_string(state->opts->basic,
@@ -433,7 +472,7 @@

                                     LDAP_SCOPE_SUBTREE,

                                     state->filter, state->attrs,

                                     state->opts->user_map, SDAP_OPTS_USER,

-                                    timeout);

+                                    timeout, state->enumeration);

      if (!subreq) {

          talloc_zfree(req);

          return NULL;
@@ -512,13 +551,20 @@

      struct ldb_message **msgs;

      size_t num_msgs;

      int ret;

+     char *sanitized_dn;

  

      tmpctx = talloc_new(NULL);

      if (!tmpctx) {

          return ENOMEM;

      }

  

-     filter = talloc_asprintf(tmpctx, "%s=%s", SYSDB_ORIG_DN, orig_dn);

+     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;
@@ -530,6 +576,7 @@

          goto done;

      }

  

+     DEBUG(9, ("Searching cache for [%s].\n", sanitized_dn));

      ret = sysdb_search_entry(tmpctx, ctx,

                               base_dn, LDB_SCOPE_SUBTREE, filter, no_attrs,

                               &num_msgs, &msgs);
@@ -640,6 +687,39 @@

      /* FIXME: support non legacy */

      /* FIXME: support storing additional attributes */

  

+ static errno_t

+ sdap_store_group_with_gid(TALLOC_CTX *mem_ctx,

+                           struct sysdb_ctx *ctx,

+                           struct sss_domain_info *domain,

+                           const char *name,

+                           gid_t gid,

+                           struct sysdb_attrs *group_attrs,

+                           uint64_t cache_timeout,

+                           bool posix_group)

+ {

+     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(2, ("Could not set explicit GID 0 for %s\n", name));

+             return ret;

+         }

+     }

+ 

+     ret = sysdb_store_group(mem_ctx, ctx, domain,

+                             name, gid, group_attrs,

+                             cache_timeout);

+     if (ret) {

+         DEBUG(2, ("Could not store group %s\n", name));

+         return ret;

+     }

+ 

+     return ret;

+ }

+ 

  static int sdap_save_group(TALLOC_CTX *memctx,

                             struct sysdb_ctx *ctx,

                             struct sdap_options *opts,
@@ -654,16 +734,44 @@

      const char *name = NULL;

      gid_t gid;

      int ret;

+     int i;

      char *usn_value = NULL;

+     TALLOC_CTX *tmpctx = NULL;

+     bool posix_group;

+     const char **aliases = NULL;

  

-     ret = sysdb_attrs_get_el(attrs,

-                           opts->group_map[SDAP_AT_GROUP_NAME].sys_name, &el);

-     if (ret) goto fail;

-     if (el->num_values == 0) {

-         ret = EINVAL;

+     tmpctx = talloc_new(memctx);

+     if (!tmpctx) {

+         ret = ENOMEM;

+         goto fail;

+     }

+ 

+     group_attrs = sysdb_new_attrs(tmpctx);

+     if (group_attrs == NULL) {

+         ret = ENOMEM;

+         goto fail;

+     }

+ 

+     ret = sysdb_attrs_primary_name(ctx, attrs,

+                                    opts->group_map[SDAP_AT_GROUP_NAME].name,

+                                    &name);

+     if (ret != EOK) {

+         DEBUG(1, ("Failed to save the group - entry has no name attribute\n"));

+         goto fail;

+     }

+ 

+     ret = sysdb_attrs_get_bool(attrs, SYSDB_POSIX, &posix_group);

+     if (ret == ENOENT) {

+         posix_group = true;

+     } else if (ret != EOK) {

+         goto fail;

+     }

+ 

+     DEBUG(8, ("This is%s a posix group\n", (posix_group)?"":" not"));

+     ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, posix_group);

+     if (ret != EOK) {

          goto fail;

      }

-     name = (const char *)el->values[0].data;

  

      ret = sysdb_attrs_get_uint32_t(attrs,

                                     opts->group_map[SDAP_AT_GROUP_GID].sys_name,
@@ -676,17 +784,14 @@

      }

  

      /* check that the gid is valid for this domain */

-     if (OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {

+     if (posix_group) {

+         if (OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {

              DEBUG(2, ("Group [%s] filtered out! (id out of range)\n",

                        name));

-         ret = EINVAL;

-         goto fail;

-     }

- 

-     group_attrs = sysdb_new_attrs(memctx);

-     if (!group_attrs) {

-         ret = ENOMEM;

-         goto fail;

+             ret = EINVAL;

+             goto fail;

+         }

+         /* Group ID OK */

      }

  

      ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
@@ -699,7 +804,7 @@

          DEBUG(7, ("Adding original DN [%s] to attributes of [%s].\n",

                    el->values[0].data, name));

          ret = sysdb_attrs_add_string(group_attrs, SYSDB_ORIG_DN,

-                                      (const char *)el->values[0].data);

+                                      (const char *) el->values[0].data);

          if (ret) {

              goto fail;

          }
@@ -737,7 +842,7 @@

          if (ret) {

              goto fail;

          }

-         usn_value = talloc_strdup(memctx, (const char*)el->values[0].data);

+         usn_value = talloc_strdup(tmpctx, (const char*)el->values[0].data);

          if (!usn_value) {

              ret = ENOMEM;

              goto fail;
@@ -776,22 +881,41 @@

          }

      }

  

+     ret = sysdb_attrs_get_aliases(tmpctx, attrs, name, &aliases);

+     if (ret != EOK) {

+         DEBUG(1, ("Failed to get the alias list\n"));

+         goto fail;

+     }

+ 

+     for (i = 0; aliases[i]; i++) {

+         ret = sysdb_attrs_add_string(group_attrs, SYSDB_NAME_ALIAS,

+                                         aliases[i]);

+         if (ret) {

+             goto fail;

+         }

+     }

+ 

      DEBUG(6, ("Storing info for group %s\n", name));

  

-     ret = sysdb_store_group(memctx, ctx, dom,

-                             name, gid, group_attrs,

-                             dp_opt_get_int(opts->basic,

-                                            SDAP_ENTRY_CACHE_TIMEOUT));

+     ret = sdap_store_group_with_gid(group_attrs, ctx, dom,

+                                     name, gid, group_attrs,

+                                     dp_opt_get_int(opts->basic,

+                                                    SDAP_ENTRY_CACHE_TIMEOUT),

+                                     posix_group);

      if (ret) goto fail;

  

      if (_usn_value) {

-         *_usn_value = usn_value;

+         *_usn_value = talloc_steal(memctx, usn_value);

      }

  

+     talloc_steal(memctx, group_attrs);

+     talloc_free(tmpctx);

      return EOK;

  

  fail:

-     DEBUG(2, ("Failed to save user %s\n", name));

+     DEBUG(2, ("Failed to save group [%s]\n",

+               name ? name : "Unknown"));

+     talloc_free(tmpctx);

      return ret;

  }

  
@@ -812,9 +936,9 @@

      const char *name;

      int ret;

  

-     ret = sysdb_attrs_get_string(attrs,

-                                 opts->group_map[SDAP_AT_GROUP_NAME].sys_name,

-                                 &name);

+     ret = sysdb_attrs_primary_name(ctx, attrs,

+                                    opts->group_map[SDAP_AT_GROUP_NAME].name,

+                                    &name);

      if (ret != EOK) {

          goto fail;

      }
@@ -876,6 +1000,8 @@

      bool twopass;

      int ret;

      int i;

+     struct sysdb_attrs **saved_groups = NULL;

+     int nsaved_groups = 0;

  

      switch (opts->schema_type) {

      case SDAP_SCHEMA_RFC2307:
@@ -902,6 +1028,15 @@

          goto done;

      }

  

+     if (twopass && !populate_members) {

+         saved_groups = talloc_array(tmpctx, struct sysdb_attrs *,

+                                     num_groups);

+         if (!saved_groups) {

+             ret = ENOMEM;

+             goto done;

+         }

+     }

+ 

      for (i = 0; i < num_groups; i++) {

          usn_value = NULL;

  
@@ -916,6 +1051,10 @@

              DEBUG(2, ("Failed to store group %d. Ignoring.\n", i));

          } else {

              DEBUG(9, ("Group %d processed!\n", i));

+             if (twopass && !populate_members) {

+                 saved_groups[nsaved_groups] = groups[i];

+                 nsaved_groups++;

+             }

          }

  

          if (usn_value) {
@@ -935,9 +1074,9 @@

  

      if (twopass && !populate_members) {

  

-         for (i = 0; i < num_groups; i++) {

+         for (i = 0; i < nsaved_groups; i++) {

  

-             ret = sdap_save_grpmem(tmpctx, sysdb, opts, dom, groups[i]);

+             ret = sdap_save_grpmem(tmpctx, sysdb, opts, dom, saved_groups[i]);

              /* Do not fail completely on errors.

               * Just report the failure to save and go on */

              if (ret) {
@@ -1112,6 +1251,10 @@

                                      int num_users);

  

  static int

+ sdap_add_group_member_2307(struct sdap_process_group_state *state,

+                            const char *username);

+ 

+ static int

  sdap_process_group_members_2307bis(struct tevent_req *req,

                                     struct sdap_process_group_state *state,

                                     struct ldb_message_element *memberel)
@@ -1205,33 +1348,31 @@

      struct ldb_message *msg;

      bool in_transaction = false;

      char *member_name;

-     char *strdn;

      int ret;

+     errno_t sret;

      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->sysdb,

                                          state->dom, member_name,

                                          NULL, &msg);

          if (ret == EOK) {

-             strdn = sysdb_user_strdn(state->sysdb_dns->values,

-                                      state->dom->name,

-                                      member_name);

-             if (!strdn) {

-                 ret = ENOMEM;

+             /*

+              * User already cached in sysdb. Remember the sysdb DN for later

+              * use by sdap_save_groups()

+              */

+             DEBUG(7, ("Member already cached in sysdb: %s\n", member_name));

+ 

+             ret = sdap_add_group_member_2307(state, member_name);

+             if (ret != EOK) {

+                 DEBUG(1, ("Could not add member %s into sysdb\n", member_name));

                  goto done;

              }

-             /*

-             * User already cached in sysdb. Remember the sysdb DN for later

-             * use by sdap_save_groups()

-             */

-             DEBUG(7,("Member already cached in sysdb: %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) {

              /* The user is not in sysdb, need to add it */

              DEBUG(7, ("member #%d (%s): not found in sysdb\n",
@@ -1258,12 +1399,22 @@

              DEBUG(2, ("Cannot commit sysdb transaction\n"));

              goto done;

          }

+         in_transaction = false;

      }

  

      ret = EOK;

      memberel->values = talloc_steal(state->group, state->sysdb_dns->values);

      memberel->num_values = state->sysdb_dns->num_values;

+ 

  done:

+     if (in_transaction) {

+         /* If the transaction is still active here, we need to cancel it */

+         sret = sysdb_transaction_cancel(state->sysdb);

+         if (sret != EOK) {

+             DEBUG(0, ("Unable to cancel transaction! [%d][%s]\n",

+                       sret, strerror(sret)));

+         }

+     }

      return ret;

  }

  
@@ -1310,7 +1461,8 @@

                                         grp_state->opts->user_map,

                                         SDAP_OPTS_USER,

                                         dp_opt_get_int(grp_state->opts->basic,

-                                                       SDAP_SEARCH_TIMEOUT));

+                                                       SDAP_SEARCH_TIMEOUT),

+                                        false);

          if (!subreq) {

              return ENOMEM;

          }
@@ -1322,17 +1474,73 @@

  }

  

  static int

- sdap_process_missing_member_2307(struct sdap_process_group_state *state,

-                                  char *username, bool *in_transaction)

+ sdap_add_group_member_2307(struct sdap_process_group_state *state,

+                            const char *username)

  {

-     int ret;

-     struct ldb_dn *dn;

-     char* dn_string;

+     char *strdn;

  

-     DEBUG(7, ("Adding a dummy entry\n"));

+     strdn = sysdb_user_strdn(state->sysdb_dns->values,

+                              state->dom->name, username);

+     if (!strdn) {

+         return ENOMEM;

+     }

+ 

+     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++;

+ 

+     return EOK;

+ }

+ 

+ static int

+ sdap_process_missing_member_2307(struct sdap_process_group_state *state,

+                                  char *member_name, bool *in_transaction)

+ {

+     int ret, sret;

+     TALLOC_CTX *tmp_ctx;

+     const char *filter;

+     const char *username;

+     size_t count;

+     struct ldb_message **msgs = NULL;

+     static const char *attrs[] = { SYSDB_NAME, NULL };

  

      if (!in_transaction) return EINVAL;

  

+     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 fail;

+     }

+ 

+     ret = sysdb_search_users(tmp_ctx, state->sysdb, 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(1, ("More than one entry with this alias?\n"));

+             ret = EIO;

+             goto fail;

+         }

+ 

+         /* fill username with primary name */

+         username = ldb_msg_find_attr_as_string(msgs[0], SYSDB_NAME, NULL);

+         goto done;

+     } else if (ret != EOK && ret != ENOENT) {

+         ret = EIO;

+         goto fail;

+     }

+ 

+     username = member_name;

+     /* The entry really does not exist, add a fake entry */

+     DEBUG(7, ("Adding a dummy entry\n"));

+ 

      if (!*in_transaction) {

          ret = sysdb_transaction_start(state->sysdb);

          if (ret != EOK) {
@@ -1354,29 +1562,25 @@

       * Convert the just received DN into the corresponding sysdb DN

       * for saving into member attribute of the group

       */

-     dn = sysdb_user_dn(state->sysdb, state, state->dom->name,

-                        (char*) username);

-     if (!dn) {

-         ret = ENOMEM;

-         goto fail;

-     }

- 

-     dn_string = ldb_dn_alloc_linearized(state->sysdb_dns->values, dn);

-     if (!dn_string) {

-         ret = ENOMEM;

+ done:

+     ret = sdap_add_group_member_2307(state, username);

+     if (ret != EOK) {

+         DEBUG(1, ("Could not add group member %s\n", username));

          goto fail;

      }

  

-     state->sysdb_dns->values[state->sysdb_dns->num_values].data =

-             (uint8_t *) dn_string;

-     state->sysdb_dns->values[state->sysdb_dns->num_values].length =

-             strlen(dn_string);

-     state->sysdb_dns->num_values++;

- 

+     talloc_free(tmp_ctx);

      return EOK;

  fail:

+     talloc_free(tmp_ctx);

      if (*in_transaction) {

-         sysdb_transaction_cancel(state->sysdb);

+         sret = sysdb_transaction_cancel(state->sysdb);

+         if (sret == EOK) {

+             *in_transaction = false;

+         } else {

+             DEBUG(0, ("Unable to cancel transaction! [%d][%s]\n",

+                        sret, strerror(sret)));

+         }

      }

      return ret;

  }
@@ -1459,7 +1663,8 @@

                                         state->opts->user_map,

                                         SDAP_OPTS_USER,

                                         dp_opt_get_int(state->opts->basic,

-                                                       SDAP_SEARCH_TIMEOUT));

+                                                       SDAP_SEARCH_TIMEOUT),

+                                        false);

          if (!subreq) {

              tevent_req_error(req, ENOMEM);

              return;
@@ -1511,6 +1716,7 @@

      struct sysdb_ctx *sysdb;

      const char **attrs;

      const char *filter;

+     bool enumeration;

  

      char *higher_usn;

      struct sysdb_attrs **groups;
@@ -1532,7 +1738,8 @@

                                         struct sdap_handle *sh,

                                         const char **attrs,

                                         const char *filter,

-                                        int timeout)

+                                        int timeout,

+                                        bool enumeration)

  {

      struct tevent_req *req, *subreq;

      struct sdap_get_groups_state *state;
@@ -1550,6 +1757,7 @@

      state->higher_usn = NULL;

      state->groups =  NULL;

      state->count = 0;

+     state->enumeration = enumeration;

  

      subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,

                                     dp_opt_get_string(state->opts->basic,
@@ -1557,7 +1765,7 @@

                                     LDAP_SCOPE_SUBTREE,

                                     state->filter, state->attrs,

                                     state->opts->group_map, SDAP_OPTS_GROUP,

-                                    timeout);

+                                    timeout, state->enumeration);

      if (!subreq) {

          talloc_zfree(req);

          return NULL;
@@ -1700,7 +1908,7 @@

      talloc_zfree(subreq);

      if (ret) {

          sysret = sysdb_transaction_cancel(state->sysdb);

-         if (ret != EOK) {

+         if (sysret != EOK) {

              DEBUG(0, ("Could not cancel sysdb transaction\n"));

          }

          tevent_req_error(req, ret);
@@ -1834,6 +2042,7 @@

  

  /* ==Save-fake-group-list=====================================*/

  static errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,

+                                           struct sdap_options *opts,

                                            struct sss_domain_info *dom,

                                            char **groupnames,

                                            struct sysdb_attrs **ldap_groups,
@@ -1843,10 +2052,12 @@

      struct ldb_message *msg;

      int i, mi, ai;

      const char *name;

+     const char *original_dn;

      char **missing;

      gid_t gid;

      int ret;

      bool in_transaction = false;

+     bool posix;

  

      /* There are no groups in LDAP but we should add user to groups ?? */

      if (ldap_groups_count == 0) return EOK;
@@ -1897,26 +2108,41 @@

      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 = sysdb_attrs_get_string(ldap_groups[ai],

-                                          SYSDB_NAME,

-                                          &name);

-             if (ret) {

+             ret = sysdb_attrs_primary_name(sysdb, ldap_groups[ai],

+                                            opts->group_map[SDAP_AT_GROUP_NAME].name,

+                                            &name);

+             if (ret != EOK) {

                  DEBUG(1, ("The group has no name attribute\n"));

                  goto fail;

              }

  

              if (strcmp(name, missing[i]) == 0) {

+                 posix = true;

                  ret = sysdb_attrs_get_uint32_t(ldap_groups[ai],

                                                 SYSDB_GIDNUM,

                                                 &gid);

-                 if (ret) {

-                     DEBUG(1, ("The GID attribute is missing or malformed\n"));

+                 if (ret == ENOENT || (ret == EOK && gid == 0)) {

+                     DEBUG(9, ("The group %s gid was %s\n",

+                               name, ret == ENOENT ? "missing" : "zero"));

+                     DEBUG(8, ("Marking group %s as non-posix and setting GID=0!\n", name));

+                     gid = 0;

+                     posix = false;

+                 } else if (ret) {

+                     DEBUG(1, ("The GID attribute is malformed\n"));

                      goto fail;

                  }

  

+                 ret = sysdb_attrs_get_string(ldap_groups[ai],

+                                              SYSDB_ORIG_DN,

+                                              &original_dn);

+                 if (ret) {

+                     DEBUG(5, ("The group has no name original DN\n"));

+                     original_dn = NULL;

+                 }

  

                  DEBUG(8, ("Adding fake group %s to sysdb\n", name));

-                 ret = sysdb_add_incomplete_group(sysdb, dom, name, gid);

+                 ret = sysdb_add_incomplete_group(sysdb, dom, name,

+                                                  gid, original_dn, posix);

                  if (ret != EOK) {

                      goto fail;

                  }
@@ -1943,6 +2169,82 @@

      if (in_transaction) {

          sysdb_transaction_cancel(sysdb);

      }

+     talloc_free(tmp_ctx);

+     return ret;

+ }

+ 

+ static int sdap_initgr_common_store(struct sysdb_ctx *sysdb,

+                                     struct sdap_options *opts,

+                                     struct sss_domain_info *dom,

+                                     const char *name,

+                                     enum sysdb_member_type type,

+                                     char **sysdb_grouplist,

+                                     struct sysdb_attrs **ldap_groups,

+                                     int ldap_groups_count,

+                                     bool add_fake)

+ {

+     TALLOC_CTX *tmp_ctx;

+     char **ldap_grouplist = NULL;

+     char **add_groups;

+     char **del_groups;

+     int ret;

+ 

+     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(1, ("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;

+ 

+     /* Add fake entries for any groups the user should be added as

+      * member of but that are not cached in sysdb

+      */

+     if (add_fake && add_groups && add_groups[0]) {

+         ret = sdap_add_incomplete_groups(sysdb, opts, dom,

+                                          add_groups, ldap_groups,

+                                          ldap_groups_count);

+         if (ret != EOK) {

+             DEBUG(1, ("Adding incomplete users failed\n"));

+             goto done;

+         }

+     }

+ 

+     DEBUG(8, ("Updating memberships for %s\n", name));

+     ret = sysdb_update_members(sysdb, dom, name,

+                                type,

+                                (const char *const *) add_groups,

+                                (const char *const *) del_groups);

+     if (ret != EOK) {

+         DEBUG(1, ("Membership update failed [%d]: %s\n",

+                   ret, strerror(ret)));

+         goto done;

+     }

+ 

+     ret = EOK;

+ done:

+     talloc_zfree(tmp_ctx);

      return ret;

  }

  
@@ -2007,10 +2309,14 @@

          return NULL;

      }

  

-     filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",

+     filter = talloc_asprintf(state,

+                              "(&(%s=%s)(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))",

                               opts->group_map[SDAP_AT_GROUP_MEMBER].name,

                               clean_name,

-                              opts->group_map[SDAP_OC_GROUP].name);

+                              opts->group_map[SDAP_OC_GROUP].name,

+                              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 (!filter) {

          talloc_zfree(req);

          return NULL;
@@ -2022,7 +2328,8 @@

                                     filter, attrs,

                                     state->opts->group_map, SDAP_OPTS_GROUP,

                                     dp_opt_get_int(state->opts->basic,

-                                                   SDAP_SEARCH_TIMEOUT));

+                                                   SDAP_SEARCH_TIMEOUT),

+                                    true);

      if (!subreq) {

          talloc_zfree(req);

          return NULL;
@@ -2037,10 +2344,7 @@

      struct tevent_req *req;

      struct sdap_initgr_rfc2307_state *state;

      struct sysdb_attrs **ldap_groups;

-     char **ldap_grouplist = NULL;

      char **sysdb_grouplist = NULL;

-     char **add_groups;

-     char **del_groups;

      struct ldb_message *msg;

      struct ldb_message_element *groups;

      size_t count;
@@ -2058,22 +2362,6 @@

          return;

      }

  

-     if (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_to_list(state, ldap_groups, count,

-                                   SYSDB_NAME,

-                                   &ldap_grouplist);

-         if (ret != EOK) {

-             tevent_req_error(req, ret);

-             return;

-         }

-     }

- 

      /* Search for all groups for which this user is a member */

      attrs[0] = SYSDB_MEMBEROF;

      attrs[1] = NULL;
@@ -2109,48 +2397,146 @@

          sysdb_grouplist[groups->num_values] = NULL;

      }

  

-     /* 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(state, ldap_grouplist, sysdb_grouplist,

-                             &add_groups, &del_groups, NULL);

+     /* There are no nested groups here so we can just update the

+      * memberships */

+     ret = sdap_initgr_common_store(state->sysdb, state->opts,

+                                    state->dom, state->name,

+                                    SYSDB_MEMBER_USER, sysdb_grouplist,

+                                    ldap_groups, count, true);

      if (ret != EOK) {

          tevent_req_error(req, ret);

          return;

      }

  

-     /* 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(state->sysdb, state->dom,

-                                          add_groups, ldap_groups, count);

+     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 *dom,

+                          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) {

-             tevent_req_error(req, ret);

-             return;

+             DEBUG(3, ("sysdb_attrs_primary_name_list failed [%d]: %s\n",

+                     ret, strerror(ret)));

+             goto done;

          }

      }

  

-     ret = sysdb_update_members(state->sysdb, state->dom, state->name,

-                                SYSDB_MEMBER_USER,

-                                (const char *const *)add_groups,

-                                (const char *const *)del_groups);

+     ret = sysdb_transaction_start(sysdb);

      if (ret != EOK) {

-         tevent_req_error(req, ret);

-         return;

+         DEBUG(1, ("Failed to start transaction\n"));

+         goto done;

      }

+     in_transaction = true;

  

-     tevent_req_done(req);

+     ret = sdap_add_incomplete_groups(sysdb, opts, dom, groupnamelist,

+                                      groups, count);

+     if (ret != EOK) {

+         DEBUG(6, ("Could not add incomplete groups [%d]: %s\n",

+                    ret, strerror(ret)));

+         goto done;

+     }

+ 

+     ret = sysdb_transaction_commit(sysdb);

+     if (ret != EOK) {

+         DEBUG(1, ("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(1, ("Failed to cancel transaction\n"));

+         }

+     }

+ 

+     talloc_free(tmp_ctx);

+     return ret;

  }

  

- static int sdap_initgr_rfc2307_recv(struct tevent_req *req)

+ 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)

  {

-     TEVENT_REQ_RETURN_ON_ERROR(req);

+     TALLOC_CTX *tmp_ctx;

+     struct membership_diff *mdiff;

+     errno_t ret;

+     char **add_groups;

+     char **del_groups;

  

-     return EOK;

- }

+     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=============== */

  
@@ -2161,6 +2547,9 @@

      struct sss_domain_info *dom;

      struct sdap_handle *sh;

  

+     struct sysdb_attrs *user;

+     const char *username;

+ 

      const char **grp_attrs;

  

      char *filter;
@@ -2188,7 +2577,8 @@

      struct tevent_req *req, *subreq;

      struct sdap_initgr_nested_state *state;

      struct ldb_message_element *el;

-     int i, ret;

+     int i;

+     errno_t ret;

  

      req = tevent_req_create(memctx, &state, struct sdap_initgr_nested_state);

      if (!req) return NULL;
@@ -2199,10 +2589,21 @@

      state->dom = dom;

      state->sh = sh;

      state->grp_attrs = grp_attrs;

+     state->user = user;

      state->op = NULL;

  

-     state->filter = talloc_asprintf(state, "(objectclass=%s)",

-                                     opts->group_map[SDAP_OC_GROUP].name);

+     ret = sysdb_attrs_primary_name(sysdb, user,

+                                    opts->user_map[SDAP_AT_USER_NAME].name,

+                                    &state->username);

+     if (ret != EOK) {

+         DEBUG(1, ("User entry had no username\n"));

+         talloc_free(req);

+         return NULL;

+     }

+ 

+     state->filter = talloc_asprintf(state, "(&(objectclass=%s)(%s=*))",

+                                     opts->group_map[SDAP_OC_GROUP].name,

+                                     opts->group_map[SDAP_AT_GROUP_NAME].name);

      if (!state->filter) {

          talloc_zfree(req);

          return NULL;
@@ -2214,8 +2615,11 @@

      ret = sysdb_attrs_get_el(user, SYSDB_MEMBEROF, &el);

      if (ret || !el || el->num_values == 0) {

          DEBUG(4, ("User entry lacks original memberof ?\n"));

-         /* user with no groups ? */

-         tevent_req_error(req, ENOENT);

+         /* We can't find any groups for this user, so we'll

+          * have to assume there aren't any. Just return

+          * success here.

+          */

+         tevent_req_done(req);

          tevent_req_post(req, ev);

          return req;

      }
@@ -2251,7 +2655,8 @@

                                     state->filter, state->grp_attrs,

                                     state->opts->group_map, SDAP_OPTS_GROUP,

                                     dp_opt_get_int(state->opts->basic,

-                                                   SDAP_SEARCH_TIMEOUT));

+                                                   SDAP_SEARCH_TIMEOUT),

+                                    false);

      if (!subreq) {

          talloc_zfree(req);

          return NULL;
@@ -2280,7 +2685,8 @@

      }

  

      if (count == 1) {

-         state->groups[state->groups_cur] = groups[0];

+         state->groups[state->groups_cur] = talloc_steal(state->groups,

+                                                         groups[0]);

          state->groups_cur++;

      } else {

          DEBUG(2, ("Search for group %s, returned %d results. Skipping\n",
@@ -2288,6 +2694,9 @@

      }

  

      state->cur++;

+     /* note that state->count 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->count) {

          subreq = sdap_get_generic_send(state, state->ev,

                                         state->opts, state->sh,
@@ -2297,7 +2706,8 @@

                                         state->opts->group_map,

                                         SDAP_OPTS_GROUP,

                                         dp_opt_get_int(state->opts->basic,

-                                                       SDAP_SEARCH_TIMEOUT));

+                                                       SDAP_SEARCH_TIMEOUT),

+                                        false);

          if (!subreq) {

              tevent_req_error(req, ENOMEM);

              return;
@@ -2308,21 +2718,450 @@

      }

  }

  

+ 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;

-     int ret;

+     bool in_transaction = false;

+     errno_t tret;

  

      state = tevent_req_data(req, struct sdap_initgr_nested_state);

  

-     ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts,

-                            state->groups, state->groups_cur, false, NULL);

-     if (ret) {

-         tevent_req_error(req, ret);

-         return;

+     ret = sysdb_transaction_start(state->sysdb);

+     if (ret != EOK) {

+         DEBUG(1, ("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(3, ("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(3, ("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(3, ("Could not save user memberships [%d]: %s\n",

+                   ret, strerror(ret)));

+         goto fail;

+     }

+ 

+     ret = sysdb_transaction_commit(state->sysdb);

+     if (ret != EOK) {

+         DEBUG(1, ("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(1, ("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;

+     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(3, ("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(1, ("Failed to start transaction\n"));

+         goto done;

+     }

+     in_transaction = true;

+ 

+     DLIST_FOR_EACH(miter, memberships) {

+         ret = sysdb_update_members(state->sysdb, state->dom,

+                                    miter->name,

+                                    SYSDB_MEMBER_GROUP,

+                                    (const char *const *) miter->add,

+                                    (const char *const *) miter->del);

+         if (ret != EOK) {

+             DEBUG(3, ("Failed to update memberships\n"));

+             goto done;

+         }

+     }

+ 

+     ret = sysdb_transaction_commit(state->sysdb);

+     if (ret != EOK) {

+         DEBUG(1, ("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(1, ("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(2, ("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(3, ("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(7, ("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(1, ("sysdb_attrs_primary_name_list failed [%d]: %s\n",

+                       ret, strerror(ret)));

+             goto done;

+         }

+     }

+ 

+     ret = sysdb_get_direct_parents(tmp_ctx, state->sysdb, state->dom,

+                                    SYSDB_MEMBER_USER,

+                                    state->username, &sysdb_parent_name_list);

+     if (ret) {

+         DEBUG(1, ("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(1, ("Failed to start transaction\n"));

+         goto done;

+     }

+     in_transaction = true;

+ 

+     DEBUG(8, ("Updating memberships for %s\n", state->username));

+     ret = sysdb_update_members(state->sysdb, state->dom,

+                                state->username, SYSDB_MEMBER_USER,

+                                (const char *const *) add_groups,

+                                (const char *const *) del_groups);

+     if (ret != EOK) {

+         DEBUG(1, ("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(1, ("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 = sysdb_attrs_primary_name(sysdb, group,

+                                    opts->group_map[SDAP_AT_GROUP_NAME].name,

+                                    &group_name);

+     if (ret != EOK) {

+         goto done;

+     }

+ 

+     ret = sysdb_get_direct_parents(tmp_ctx, sysdb, dom,

+                                    SYSDB_MEMBER_GROUP,

+                                    group_name, &sysdb_parents_names_list);

+     if (ret) {

+         DEBUG(1, ("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(1, ("Cannot get parent groups for %s [%d]: %s\n",

+                   group_name, ret, strerror(ret)));

+         goto done;

+     }

+     DEBUG(7, ("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(1, ("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(3, ("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(3, ("Missing originalDN\n"));

+         goto done;

+     }

+     DEBUG(9, ("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(7, ("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(9, ("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)
@@ -2364,6 +3203,7 @@

      const char *base_dn;

      char *filter;

      int ret;

+     char *clean_name;

  

      DEBUG(9, ("Retrieving info for initgroups call\n"));

  
@@ -2380,9 +3220,14 @@

      state->grp_attrs = grp_attrs;

      state->orig_user = NULL;

  

+     ret = sss_filter_sanitize(state, name, &clean_name);

+     if (ret != EOK) {

+         return NULL;

+     }

+ 

      filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",

                          state->opts->user_map[SDAP_AT_USER_NAME].name,

-                         state->name,

+                         clean_name,

                          state->opts->user_map[SDAP_OC_USER].name);

      if (!filter) {

          talloc_zfree(req);
@@ -2409,7 +3254,8 @@

                                     filter, state->ldap_attrs,

                                     state->opts->user_map, SDAP_OPTS_USER,

                                     dp_opt_get_int(state->opts->basic,

-                                                   SDAP_SEARCH_TIMEOUT));

+                                                   SDAP_SEARCH_TIMEOUT),

+                                    false);

      if (!subreq) {

          talloc_zfree(req);

          return NULL;
@@ -2487,6 +3333,13 @@

  

      switch (state->opts->schema_type) {

      case SDAP_SCHEMA_RFC2307:

+         ret = sdap_check_aliases(state->sysdb, state->orig_user, state->dom,

+                                  state->opts, false);

+         if (ret != EOK) {

+             tevent_req_error(req, ret);

+             return;

+         }

+ 

          subreq = sdap_initgr_rfc2307_send(state, state->ev, state->opts,

                                      state->sysdb, state->dom, state->sh,

                                      dp_opt_get_string(state->opts->basic,
@@ -2669,6 +3522,7 @@

      const char *groupname;

      hash_key_t key;

      hash_value_t value;

+     gid_t gid;

  

      req = tevent_req_create(mem_ctx, &state, struct sdap_nested_group_ctx);

      if (!req) {
@@ -2695,11 +3549,12 @@

       */

      key.type = HASH_KEY_STRING;

  

-     ret = sysdb_attrs_get_string(

-             group,

-             opts->group_map[SDAP_AT_GROUP_NAME].sys_name,

-             &groupname);

-     if (ret != EOK) goto immediate;

+     ret = sysdb_attrs_primary_name(sysdb, group,

+                                    opts->group_map[SDAP_AT_GROUP_NAME].sys_name,

+                                    &groupname);

+     if (ret != EOK) {

+         goto immediate;

+     }

  

      key.str = talloc_strdup(state, groupname);

      if (!key.str) {
@@ -2716,6 +3571,32 @@

          goto immediate;

      }

  

+     ret = sysdb_attrs_get_uint32_t(group,

+                                    opts->group_map[SDAP_AT_GROUP_GID].sys_name,

+                                    &gid);

+     if (ret == ENOENT || (ret == EOK && gid == 0)) {

+         DEBUG(9, ("The group's gid was %s\n", ret == ENOENT ? "missing" : "zero"));

+         DEBUG(8, ("Marking group as non-posix and setting GID=0!\n"));

+ 

+         if (ret == ENOENT) {

+             ret = sysdb_attrs_add_uint32(group,

+                                       opts->group_map[SDAP_AT_GROUP_GID].sys_name,

+                                       0);

+             if (ret != EOK) {

+                 DEBUG(1, ("Failed to add a GID to non-posix group!\n"));

+                 goto immediate;

+             }

+         }

+ 

+         ret = sysdb_attrs_add_bool(group, SYSDB_POSIX, false);

+         if (ret != EOK) {

+             DEBUG(2, ("Error: Failed to mark group as non-posix!\n"));

+             goto immediate;

+         }

+     } else if (ret) {

+         goto immediate;

+     }

+ 

      value.type = HASH_VALUE_PTR;

      value.ptr = talloc_steal(groups, group);

  
@@ -2858,7 +3739,7 @@

              if (ret != EOK && ret != ENOENT) {

                  ret = EIO;

                  goto error;

-             } else if (ret == ENOENT || count == 9) {

+             } else if (ret == ENOENT || count == 0) {

                  if (ret == EOK) talloc_zfree(msgs);

  

                  /* It wasn't found in the groups either
@@ -2869,7 +3750,7 @@

                  ret = sdap_nested_group_lookup_user(

                          req, sdap_nested_group_process_ldap_user);

                  if (ret != EOK) {

-                     tevent_req_error(req, ret);

+                     goto error;

                  }

                  return EAGAIN;

              }
@@ -2966,7 +3847,8 @@

                                     state->opts->user_map,

                                     SDAP_OPTS_USER,

                                     dp_opt_get_int(state->opts->basic,

-                                                   SDAP_SEARCH_TIMEOUT));

+                                                   SDAP_SEARCH_TIMEOUT),

+                                    false);

      if (!subreq) {

          talloc_free(sdap_attrs);

          return EIO;
@@ -2994,8 +3876,9 @@

      }

  

      filter = talloc_asprintf(

-             sdap_attrs, "(objectclass=%s)",

-             state->opts->group_map[SDAP_OC_GROUP].name);

+             sdap_attrs, "(&(objectclass=%s)(%s=*))",

+             state->opts->group_map[SDAP_OC_GROUP].name,

+             state->opts->group_map[SDAP_AT_GROUP_NAME].name);

      if (!filter) {

          talloc_free(sdap_attrs);

          return ENOMEM;
@@ -3008,7 +3891,8 @@

                                     state->opts->group_map,

                                     SDAP_OPTS_GROUP,

                                     dp_opt_get_int(state->opts->basic,

-                                                   SDAP_SEARCH_TIMEOUT));

+                                                   SDAP_SEARCH_TIMEOUT),

+                                    false);

      if (!subreq) {

          talloc_free(sdap_attrs);

          return EIO;
@@ -3179,6 +4063,7 @@

      talloc_zfree(subreq);

      if (ret != EOK) {

          tevent_req_error(req, ret);

+         return;

      }

  

      state->member_index++;
@@ -3282,6 +4167,27 @@

      return EOK;

  }

  

+ 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;

+ 

+     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 void sdap_initgr_rfc2307bis_process(struct tevent_req *subreq);

  static struct tevent_req *sdap_initgr_rfc2307bis_send(

          TALLOC_CTX *memctx,
@@ -3297,12 +4203,13 @@

      errno_t ret;

      struct tevent_req *req;

      struct tevent_req *subreq;

-     struct sdap_initgr_rfc2307_state *state;

+     struct sdap_initgr_rfc2307bis_state *state;

      const char *filter;

      const char **attrs;

      char *clean_orig_dn;

  

-     req = tevent_req_create(memctx, &state, struct sdap_initgr_rfc2307_state);

+     req = tevent_req_create(memctx, &state,

+                             struct sdap_initgr_rfc2307bis_state);

      if (!req) return NULL;

  

      state->ev = ev;
@@ -3313,6 +4220,12 @@

      state->op = NULL;

      state->name = name;

  

+     ret = sss_hash_create(state, 32, &state->group_hash);

+     if (ret != EOK) {

+         talloc_free(req);

+         return NULL;

+     }

+ 

      ret = build_attrs_from_map(state, opts->group_map,

                                 SDAP_OPTS_GROUP, &attrs);

      if (ret != EOK) {
@@ -3326,10 +4239,11 @@

          return NULL;

      }

  

-     filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",

+     filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s)(%s=*))",

                               opts->group_map[SDAP_AT_GROUP_MEMBER].name,

                               clean_orig_dn,

-                              opts->group_map[SDAP_OC_GROUP].name);

+                              opts->group_map[SDAP_OC_GROUP].name,

+                              opts->group_map[SDAP_AT_GROUP_NAME].name);

      if (!filter) {

          talloc_zfree(req);

          return NULL;
@@ -3342,7 +4256,8 @@

                                     filter, attrs,

                                     state->opts->group_map, SDAP_OPTS_GROUP,

                                     dp_opt_get_int(state->opts->basic,

-                                                   SDAP_SEARCH_TIMEOUT));

+                                                   SDAP_SEARCH_TIMEOUT),

+                                    true);

      if (!subreq) {

          talloc_zfree(req);

          return NULL;
@@ -3354,33 +4269,33 @@

  }

  

  errno_t save_rfc2307bis_user_memberships(

-         struct sdap_initgr_rfc2307_state *state);

+         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 sysdb_attrs **groups, size_t num_groups,

-         size_t nesting);

+         hash_table_t *group_hash, size_t nesting);

  static void sdap_initgr_rfc2307bis_done(struct tevent_req *subreq);

  static void sdap_initgr_rfc2307bis_process(struct tevent_req *subreq)

  {

      struct tevent_req *req;

-     struct sdap_initgr_rfc2307_state *state;

+     struct sdap_initgr_rfc2307bis_state *state;

      int ret;

  

      req = tevent_req_callback_data(subreq, struct tevent_req);

-     state = tevent_req_data(req, struct sdap_initgr_rfc2307_state);

+     state = tevent_req_data(req, struct sdap_initgr_rfc2307bis_state);

  

      ret = sdap_get_generic_recv(subreq, state,

-                                 &state->ldap_groups_count,

-                                 &state->ldap_groups);

+                                 &state->num_direct_parents,

+                                 &state->direct_groups);

      talloc_zfree(subreq);

      if (ret) {

          tevent_req_error(req, ret);

          return;

      }

  

-     if (state->ldap_groups_count == 0) {

+     if (state->num_direct_parents == 0) {

          /* Start a transaction to look up the groups in the sysdb

           * and update them with LDAP data

           */
@@ -3395,8 +4310,9 @@

  

      subreq = rfc2307bis_nested_groups_send(state, state->ev, state->opts,

                                             state->sysdb, state->dom,

-                                            state->sh, state->ldap_groups,

-                                            state->ldap_groups_count, 0);

+                                            state->sh, state->direct_groups,

+                                            state->num_direct_parents,

+                                            state->group_hash, 0);

      if (!subreq) {

          tevent_req_error(req, EIO);

          return;
@@ -3404,103 +4320,310 @@

      tevent_req_set_callback(subreq, sdap_initgr_rfc2307bis_done, req);

  }

  

- errno_t save_rfc2307bis_user_memberships(

-         struct sdap_initgr_rfc2307_state *state)

+ static errno_t rfc2307bis_nested_groups_recv(struct tevent_req *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, tret;

-     char *member_dn;

-     char *filter;

-     const char **attrs;

-     size_t reply_count, i;

-     struct ldb_message **replies;

-     char **ldap_grouplist;

-     char **sysdb_grouplist;

-     char **add_groups;

-     char **del_groups;

-     const char *tmp_str;

+     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;

  

-     TALLOC_CTX *tmp_ctx = talloc_new(NULL);

-     if(!tmp_ctx) {

-         return ENOMEM;

+     ret = rfc2307bis_nested_groups_recv(subreq);

+     talloc_zfree(subreq);

+     if (ret != EOK) {

+         tevent_req_error(req, ret);

+         return;

      }

  

-     DEBUG(7, ("Save parent groups to sysdb\n"));

      ret = sysdb_transaction_start(state->sysdb);

      if (ret != EOK) {

-         goto error;

+         DEBUG(1, ("Failed to start transaction\n"));

+         goto fail;

      }

      in_transaction = true;

  

-     /* Save this user and their memberships */

-     attrs = talloc_array(tmp_ctx, const char *, 2);

-     if (!attrs) {

+     /* save the groups if they are not cached */

+     ret = save_rfc2307bis_groups(state);

+     if (ret != EOK) {

+         DEBUG(3, ("Could not save groups memberships [%d]", ret));

+         goto fail;

+     }

+ 

+     /* save the group membership */

+     ret = save_rfc2307bis_group_memberships(state);

+     if (ret != EOK) {

+         DEBUG(3, ("Could not save group memberships [%d]", ret));

+         goto fail;

+     }

+ 

+     /* save the user memberships */

+     ret = save_rfc2307bis_user_memberships(state);

+     if (ret != EOK) {

+         DEBUG(3, ("Could not save user memberships [%d]", ret));

+         goto fail;

+     }

+ 

+     ret = sysdb_transaction_commit(state->sysdb);

+     if (ret != EOK) {

+         DEBUG(1, ("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(1, ("Failed to cancel transaction\n"));

+         }

+     }

+     tevent_req_error(req, ret);

+     return;

+ }

+ 

+ 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 error;

+         goto done;

      }

  

-     attrs[0] = SYSDB_NAME;

-     attrs[1] = NULL;

+     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(3, ("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;

+     bool in_transaction = false;

  

-     member_dn = sysdb_user_strdn(tmp_ctx, state->dom->name, state->name);

-     if (!member_dn) {

+     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 error;

+         goto done;

      }

  

-     filter = talloc_asprintf(tmp_ctx, "(member=%s)", member_dn);

-     if (!filter) {

+     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(1, ("Failed to start transaction\n"));

+         goto done;

+     }

+     in_transaction = true;

+ 

+     DLIST_FOR_EACH(iter, membership_state->memberships) {

+         ret = sysdb_update_members(state->sysdb,

+                                    state->dom,

+                                    iter->name,

+                                    SYSDB_MEMBER_GROUP,

+                                   (const char *const *) iter->add,

+                                   (const char *const *) iter->del);

+         if (ret != EOK) {

+             DEBUG(3, ("Failed to update memberships\n"));

+             goto done;

+         }

+     }

+ 

+     ret = sysdb_transaction_commit(state->sysdb);

+     if (ret != EOK) {

+         DEBUG(1, ("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(1, ("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 error;

+         goto done;

      }

  

-     ret = sysdb_search_groups(tmp_ctx, state->sysdb, state->dom,

-                               filter, attrs, &reply_count, &replies);

-     if (ret != EOK && ret != ENOENT) {

-         goto error;

-     } if (ret == ENOENT) {

-         reply_count = 0;

+     ret = sysdb_get_direct_parents(tmp_ctx, mstate->sysdb, mstate->dom,

+                                    SYSDB_MEMBER_GROUP,

+                                    group_name, &sysdb_parents_names_list);

+     if (ret) {

+         DEBUG(1, ("Could not get direct sysdb parents for %s: %d [%s]\n",

+                   group_name, ret, strerror(ret)));

+         goto done;

      }

  

-     if (reply_count == 0) {

-         DEBUG(6, ("User [%s] is not a direct member of any groups\n",

-                   state->name));

-         sysdb_grouplist = NULL;

-     } else {

-         sysdb_grouplist = talloc_array(tmp_ctx, char *, reply_count+1);

-         if (!sysdb_grouplist) {

-             ret = ENOMEM;

-             goto error;

+     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;

          }

+     }

  

-         for (i = 0; i < reply_count; i++) {

-             tmp_str = ldb_msg_find_attr_as_string(replies[i],

-                                                   SYSDB_NAME,

-                                                   NULL);

-             if (!tmp_str) {

-                 /* This should never happen, but if it

-                  * does, just skip it.

-                  */

-                 continue;

-             }

+     ret = build_membership_diff(tmp_ctx, group_name, ldap_parents_names_list,

+                                 sysdb_parents_names_list, &mdiff);

+     if (ret != EOK) {

+         DEBUG(3, ("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;

+ 

+     TALLOC_CTX *tmp_ctx = talloc_new(NULL);

+     if(!tmp_ctx) {

+         return ENOMEM;

+     }

+ 

+     DEBUG(7, ("Save parent groups to sysdb\n"));

+     ret = sysdb_transaction_start(state->sysdb);

+     if (ret != EOK) {

+         goto error;

+     }

+     in_transaction = true;

  

-             sysdb_grouplist[i] = talloc_strdup(sysdb_grouplist, tmp_str);

-             if (!sysdb_grouplist[i]) {

-                 ret = ENOMEM;

-                 goto error;

-             }

-         }

-         sysdb_grouplist[i] = NULL;

+     ret = sysdb_get_direct_parents(tmp_ctx, state->sysdb, state->dom,

+                                    SYSDB_MEMBER_USER,

+                                    state->name, &sysdb_parent_name_list);

+     if (ret) {

+         DEBUG(1, ("Could not get direct sysdb parents for %s: %d [%s]\n",

+                    state->name, ret, strerror(ret)));

+         goto error;

      }

  

-     if (state->ldap_groups_count == 0) {

+     if (state->num_direct_parents == 0) {

          ldap_grouplist = NULL;

      }

      else {

-         ret = sysdb_attrs_to_list(tmp_ctx,

-                                   state->ldap_groups, state->ldap_groups_count,

-                                   SYSDB_NAME,

-                                   &ldap_grouplist);

+         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;

          }
@@ -3511,14 +4634,15 @@

       * groups in the sysdb only must be removed.

       */

      ret = diff_string_lists(tmp_ctx,

-                             ldap_grouplist, sysdb_grouplist,

+                             ldap_grouplist, sysdb_parent_name_list,

                              &add_groups, &del_groups, NULL);

      if (ret != EOK) {

          goto error;

      }

  

-     ret = sysdb_update_members(state->sysdb, state->dom, state->name,

-                                SYSDB_MEMBER_USER,

+     DEBUG(8, ("Updating memberships for %s\n", state->name));

+     ret = sysdb_update_members(state->sysdb, state->dom,

+                                state->name, SYSDB_MEMBER_USER,

                                 (const char *const *)add_groups,

                                 (const char *const *)del_groups);

      if (ret != EOK) {
@@ -3529,7 +4653,9 @@

      if (ret != EOK) {

          goto error;

      }

+     in_transaction = false;

  

+     talloc_free(tmp_ctx);

      return EOK;

  

  error:
@@ -3542,33 +4668,6 @@

      talloc_free(tmp_ctx);

      return ret;

  }

- 

- static errno_t rfc2307bis_nested_groups_recv(struct tevent_req *req);

- 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_rfc2307_state *state =

-             tevent_req_data(req, struct sdap_initgr_rfc2307_state);

- 

-     ret = rfc2307bis_nested_groups_recv(subreq);

-     talloc_zfree(subreq);

-     if (ret != EOK) {

-         tevent_req_error(req, ret);

-         return;

-     }

- 

-     /* save the user memberships */

-     ret = save_rfc2307bis_user_memberships(state);

-     if (ret != EOK) {

-         tevent_req_error(req, ret);

-     } else {

-         tevent_req_done(req);

-     }

-     return;

- }

- 

  struct sdap_rfc2307bis_nested_ctx {

      struct tevent_context *ev;

      struct sdap_options *opts;
@@ -3581,8 +4680,11 @@

      size_t nesting_level;

  

      size_t group_iter;

-     struct sysdb_attrs **ldap_groups;

-     size_t ldap_groups_count;

+     struct sysdb_attrs **ldap_parents;

+     size_t parents_count;

+ 

+     hash_table_t *group_hash;

+     const char *primary_name;

  

      struct sysdb_handle *handle;

  };
@@ -3593,7 +4695,7 @@

          struct sdap_options *opts, struct sysdb_ctx *sysdb,

          struct sss_domain_info *dom, struct sdap_handle *sh,

          struct sysdb_attrs **groups, size_t num_groups,

-         size_t nesting)

+         hash_table_t *group_hash, size_t nesting)

  {

      errno_t ret;

      struct tevent_req *req;
@@ -3606,9 +4708,8 @@

      if ((num_groups == 0) ||

          (nesting > dp_opt_get_int(opts->basic, SDAP_NESTING_LEVEL))) {

          /* No parent groups to process or too deep*/

-         tevent_req_done(req);

-         tevent_req_post(req, ev);

-         return req;

+         ret = EOK;

+         goto done;

      }

  

      state->ev = ev;
@@ -3620,29 +4721,46 @@

      state->num_groups = num_groups;

      state->group_iter = 0;

      state->nesting_level = nesting;

+     state->group_hash = group_hash;

  

-     ret = rfc2307bis_nested_groups_step(req);

-     if (ret != EOK) {

+     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;

+         }

+     }

+ 

+ done:

+     if (ret == EOK) {

+         /* All groups on that level had been processed. Quit. */

+         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 void rfc2307bis_nested_groups_process(struct tevent_req *subreq);

  static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req)

  {

-     errno_t ret, tret;

+     errno_t ret;

      struct tevent_req *subreq;

-     const char *name;

-     struct sysdb_attrs **grouplist;

-     char **groupnamelist;

-     bool in_transaction = false;

      TALLOC_CTX *tmp_ctx = NULL;

      char *filter;

      const char *orig_dn;

      const char **attrs;

      char *clean_orig_dn;

+     hash_key_t key;

      struct sdap_rfc2307bis_nested_ctx *state =

              tevent_req_data(req, struct sdap_rfc2307bis_nested_ctx);

  
@@ -3652,58 +4770,32 @@

          goto error;

      }

  

-     ret = sysdb_attrs_get_string(state->groups[state->group_iter],

-                                  SYSDB_NAME, &name);

-     if (ret != EOK) {

-         goto error;

-     }

- 

-     DEBUG(6, ("Processing group [%s]\n", name));

- 

-     ret = sysdb_transaction_start(state->sysdb);

+     ret = sysdb_attrs_primary_name(

+             state->sysdb,

+             state->groups[state->group_iter],

+             state->opts->group_map[SDAP_AT_GROUP_NAME].name,

+             &state->primary_name);

      if (ret != EOK) {

          goto error;

      }

-     in_transaction = true;

- 

-     /* First, save the group we're processing to the sysdb

-      * sdap_add_incomplete_groups_send will add them if needed

-      */

- 

-     /* sdap_add_incomplete_groups_send expects a list of groups */

-     grouplist = talloc_array(tmp_ctx, struct sysdb_attrs *, 1);

-     if (!grouplist) {

-         ret = ENOMEM;

-         goto error;

-     }

-     grouplist[0] = state->groups[state->group_iter];

  

-     groupnamelist = talloc_array(tmp_ctx, char *, 2);

-     if (!groupnamelist) {

-         ret = ENOMEM;

-         goto error;

-     }

-     groupnamelist[0] = talloc_strdup(groupnamelist, name);

-     if (!groupnamelist[0]) {

+     key.type = HASH_KEY_STRING;

+     key.str = talloc_strdup(state, state->primary_name);

+     if (!key.str) {

          ret = ENOMEM;

          goto error;

      }

-     groupnamelist[1] = NULL;

  

-     DEBUG(6, ("Saving incomplete group [%s] to the sysdb\n",

-               groupnamelist[0]));

-     ret = sdap_add_incomplete_groups(state->sysdb, state->dom, groupnamelist,

-                                      grouplist, 1);

-     if (ret != EOK) {

-         goto error;

-     }

+     DEBUG(6, ("Processing group [%s]\n", state->primary_name));

  

-     ret = sysdb_transaction_commit(state->sysdb);

-     if (ret != EOK) {

-         goto error;

+     if (hash_has_key(state->group_hash, &key)) {

+         DEBUG(6, ("Group was already processed, taking a shortcut\n"));

+         talloc_free(key.str);

+         talloc_free(tmp_ctx);

+         return EOK;

      }

  

-     /* Get any parent groups for this group */

+    /* Get any parent groups for this group */

      ret = sysdb_attrs_get_string(state->groups[state->group_iter],

                                   SYSDB_ORIG_DN,

                                   &orig_dn);
@@ -3717,16 +4809,17 @@

          goto error;

      }

  

-     ret = sss_filter_sanitize(state, orig_dn, &clean_orig_dn);

+     ret = sss_filter_sanitize(tmp_ctx, orig_dn, &clean_orig_dn);

      if (ret != EOK) {

          goto error;

      }

  

      filter = talloc_asprintf(

-             tmp_ctx, "(&(%s=%s)(objectclass=%s))",

+             tmp_ctx, "(&(%s=%s)(objectclass=%s)(%s=*))",

              state->opts->group_map[SDAP_AT_GROUP_MEMBER].name,

              clean_orig_dn,

-             state->opts->group_map[SDAP_OC_GROUP].name);

+             state->opts->group_map[SDAP_OC_GROUP].name,

+             state->opts->group_map[SDAP_AT_GROUP_NAME].name);

      if (!filter) {

          ret = ENOMEM;

          goto error;
@@ -3742,7 +4835,8 @@

                                     filter, attrs,

                                     state->opts->group_map, SDAP_OPTS_GROUP,

                                     dp_opt_get_int(state->opts->basic,

-                                                   SDAP_SEARCH_TIMEOUT));

+                                                   SDAP_SEARCH_TIMEOUT),

+                                    true);

      if (!subreq) {

          ret = EIO;

          goto error;
@@ -3752,22 +4846,14 @@

                              rfc2307bis_nested_groups_process,

                              req);

  

-     return EOK;

+     talloc_free(tmp_ctx);

+     return EAGAIN;

  

  error:

-     if (in_transaction) {

-         tret = sysdb_transaction_cancel(state->sysdb);

-         if (tret != EOK) {

-             DEBUG(1, ("Failed to cancel transaction\n"));

-         }

-     }

- 

      talloc_free(tmp_ctx);

      return ret;

  }

  

- static errno_t rfc2307bis_nested_groups_update_sysdb(

-         struct sdap_rfc2307bis_nested_ctx *state);

  static void rfc2307bis_nested_groups_done(struct tevent_req *subreq);

  static void rfc2307bis_nested_groups_process(struct tevent_req *subreq)

  {
@@ -3776,34 +4862,70 @@

              tevent_req_callback_data(subreq, struct tevent_req);

      struct sdap_rfc2307bis_nested_ctx *state =

              tevent_req_data(req, struct sdap_rfc2307bis_nested_ctx);

+     struct sdap_nested_group *ngr;

+     hash_value_t value;

+     hash_key_t key;

+     int hret;

  

      ret = sdap_get_generic_recv(subreq, state,

-                                 &state->ldap_groups_count,

-                                 &state->ldap_groups);

+                                 &state->parents_count,

+                                 &state->ldap_parents);

      talloc_zfree(subreq);

      if (ret) {

          tevent_req_error(req, ret);

          return;

      }

  

-     if (state->ldap_groups_count == 0) {

-         /* No parent groups for this group in LDAP

-          * We need to ensure that there are no groups

-          * in the sysdb either.

-          */

+     ngr = talloc_zero(state->group_hash, struct sdap_nested_group);

+     if (!ngr) {

+         tevent_req_error(req, ENOMEM);

+         return;

+     }

  

-         ret = rfc2307bis_nested_groups_update_sysdb(state);

-         if (ret != EOK) {

-             tevent_req_error(req, ret);

-         }

+     ngr->group = talloc_steal(ngr, state->groups[state->group_iter]);

+     ngr->ldap_parents = talloc_steal(ngr, state->ldap_parents);

+     ngr->parents_count = state->parents_count;

+ 

+     key.type = HASH_KEY_STRING;

+     key.str = talloc_strdup(state, state->primary_name);

+     if (!key.str) {

+         tevent_req_error(req, ENOMEM);

+         return;

+     }

+ 

+     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 (state->parents_count == 0) {

+         /* No parent groups for this group in LDAP

+          * Move on to the next group

+          */

          state->group_iter++;

-         if (state->group_iter < state->num_groups) {

+         while (state->group_iter < state->num_groups) {

              ret = rfc2307bis_nested_groups_step(req);

-             if (ret != EOK) {

+             if (ret == EAGAIN) {

+                 /* Looking up parent groups.. */

+                 return;

+             } else if (ret != EOK) {

                  tevent_req_error(req, ret);

+                 return;

              }

-         } else {

+ 

+             /* 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);

          }

          return;
@@ -3813,8 +4935,9 @@

      subreq = rfc2307bis_nested_groups_send(

              state, state->ev, state->opts, state->sysdb,

              state->dom, state->sh,

-             state->ldap_groups,

-             state->ldap_groups_count,

+             state->ldap_parents,

+             state->parents_count,

+             state->group_hash,

              state->nesting_level+1);

      if (!subreq) {

          tevent_req_error(req, EIO);
@@ -3846,175 +4969,27 @@

          return;

      }

  

-     /* All of the parent groups have been added

-      * Now add the memberships

-      */

- 

-     ret = rfc2307bis_nested_groups_update_sysdb(state);

-     if (ret != EOK) {

-         tevent_req_error(req, ret);

-         return;

-     }

- 

      state->group_iter++;

-     if (state->group_iter < state->num_groups) {

+     while (state->group_iter < state->num_groups) {

          ret = rfc2307bis_nested_groups_step(req);

-         if (ret != EOK) {

+         if (ret == EAGAIN) {

+             /* Looking up parent groups.. */

+             return;

+         } else if (ret != EOK) {

              tevent_req_error(req, ret);

+             return;

          }

-     } else {

-         tevent_req_done(req);

-     }

- }

- 

- static errno_t rfc2307bis_nested_groups_update_sysdb(

-         struct sdap_rfc2307bis_nested_ctx *state)

- {

-     errno_t ret, tret;

-     const char *name;

-     bool in_transaction = false;

-     char *member_dn;

-     char *filter;

-     const char **attrs;

-     size_t reply_count, i;

-     struct ldb_message **replies;

-     char **sysdb_grouplist;

-     char **ldap_grouplist;

-     char **add_groups;

-     char **del_groups;

-     const char *tmp_str;

- 

-     TALLOC_CTX *tmp_ctx = talloc_new(state);

-     if (!tmp_ctx) {

-         return ENOMEM;

-     }

- 

-     /* Start a transaction to look up the groups in the sysdb

-      * and update them with LDAP data

-      */

-     ret = sysdb_transaction_start(state->sysdb);

-     if (ret != EOK) {

-         goto error;

-     }

-     in_transaction = true;

- 

-     ret = sysdb_attrs_get_string(state->groups[state->group_iter],

-                                  SYSDB_NAME, &name);

-     if (ret != EOK) {

-         goto error;

-     }

- 

-     attrs = talloc_array(tmp_ctx, const char *, 2);

-     if (!attrs) {

-         ret = ENOMEM;

-         goto error;

-     }

-     attrs[0] = SYSDB_NAME;

-     attrs[1] = NULL;

- 

-     member_dn = sysdb_group_strdn(tmp_ctx, state->dom->name, name);

-     if (!member_dn) {

-         ret = ENOMEM;

-         goto error;

-     }

- 

-     filter = talloc_asprintf(tmp_ctx, "(member=%s)", member_dn);

-     if (!filter) {

-         ret = ENOMEM;

-         goto error;

-     }

-     talloc_free(member_dn);

- 

-     ret = sysdb_search_groups(tmp_ctx, state->sysdb, state->dom,

-                               filter, attrs,

-                               &reply_count, &replies);

-     if (ret != EOK && ret != ENOENT) {

-         goto error;

-     } else if (ret == ENOENT) {

-         reply_count = 0;

-     }

- 

-     if (reply_count == 0) {

-         DEBUG(6, ("User [%s] is not a direct member of any groups\n", name));

-         sysdb_grouplist = NULL;

-     } else {

-         sysdb_grouplist = talloc_array(tmp_ctx, char *, reply_count+1);

-         if (!sysdb_grouplist) {

-             ret = ENOMEM;

-             goto error;

-         }

- 

-         for (i = 0; i < reply_count; i++) {

-             tmp_str = ldb_msg_find_attr_as_string(replies[i],

-                                                   SYSDB_NAME,

-                                                   NULL);

-             if (!tmp_str) {

-                 /* This should never happen, but if it

-                  * does, just skip it.

-                  */

-                 continue;

-             }

- 

-             sysdb_grouplist[i] = talloc_strdup(sysdb_grouplist, tmp_str);

-             if (!sysdb_grouplist[i]) {

-                 ret = ENOMEM;

-                 goto error;

-             }

-         }

-         sysdb_grouplist[i] = NULL;

-     }

- 

-     if (state->ldap_groups_count == 0) {

-         ldap_grouplist = NULL;

-     }

-     else {

-         ret = sysdb_attrs_to_list(tmp_ctx,

-                                   state->ldap_groups, state->ldap_groups_count,

-                                   SYSDB_NAME,

-                                   &ldap_grouplist);

-         if (ret != EOK) {

-             goto error;

-         }

-     }

  

-     /* 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(state,

-                             ldap_grouplist, sysdb_grouplist,

-                             &add_groups, &del_groups, NULL);

-     if (ret != EOK) {

-         goto error;

-     }

-     talloc_free(ldap_grouplist);

-     talloc_free(sysdb_grouplist);

- 

-     ret = sysdb_update_members(state->sysdb, state->dom, name,

-                                SYSDB_MEMBER_GROUP,

-                                (const char *const *)add_groups,

-                                (const char *const *)del_groups);

-     if (ret != EOK) {

-         goto error;

-     }

- 

-     ret = sysdb_transaction_commit(state->sysdb);

-     if (ret != EOK) {

-         goto error;

+         /* EOK means this group has already been processed

+          * in another nesting level */

+         state->group_iter++;

      }

-     in_transaction = false;

  

-     ret = EOK;

- 

- error:

-     if (in_transaction) {

-         tret = sysdb_transaction_cancel(state->sysdb);

-         if (tret != EOK) {

-             DEBUG(1, ("Failed to cancel transaction\n"));

-         }

+     if (state->group_iter == state->num_groups) {

+         /* All groups processed. Done. */

+         tevent_req_done(req);

+         return;

      }

-     talloc_free(tmp_ctx);

-     return ret;

  }

  

  static int sdap_initgr_rfc2307bis_recv(struct tevent_req *req)

@@ -20,12 +20,14 @@

      along with this program.  If not, see <http://www.gnu.org/licenses/>.

  */

  

+ #include <unistd.h>

+ #include <fcntl.h>

  #include <sasl/sasl.h>

  #include "util/util.h"

  #include "util/sss_krb5.h"

+ #include "util/sss_ldap.h"

  #include "providers/ldap/sdap_async_private.h"

- 

- #define LDAP_X_SSSD_PASSWORD_EXPIRED 0x555D

+ #include "providers/ldap/ldap_common.h"

  

  errno_t deref_string_to_val(const char *str, int *val)

  {
@@ -60,6 +62,8 @@

      struct tevent_context *ev;

      struct sdap_options *opts;

      struct sdap_handle *sh;

+     const char *uri;

+     bool use_start_tls;

  

      struct sdap_op *op;

  
@@ -67,6 +71,7 @@

      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);
@@ -75,21 +80,14 @@

                                       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;

-     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 ret;

+     int timeout;

  

      req = tevent_req_create(memctx, &state, struct sdap_connect_state);

      if (!req) return NULL;
@@ -102,18 +100,88 @@

  

      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;

      }

-     /* Initialize LDAP handler */

-     lret = ldap_initialize(&state->sh->ldap, uri);

-     if (lret != LDAP_SUCCESS) {

-         DEBUG(1, ("ldap_initialize failed: %s\n", ldap_err2string(lret)));

+ 

+     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(1, ("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;

+ 

+     ret = sss_ldap_init_recv(subreq, &state->sh->ldap, &sd);

+     talloc_zfree(subreq);

+     if (ret != EOK) {

+         DEBUG(1, ("sdap_async_connect_call request failed.\n"));

+         tevent_req_error(req, ret);

+         return;

+     }

+ 

+     ret = setup_ldap_connection_callbacks(state->sh, state->ev);

+     if (ret != EOK) {

+         DEBUG(1, ("setup_ldap_connection_callbacks failed.\n"));

+         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(1, ("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);
@@ -130,27 +198,27 @@

      }

  

      /* Set Network Timeout */

-     tv.tv_sec = dp_opt_get_int(opts->basic, SDAP_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(1, ("Failed to set network timeout to %d\n",

-                   dp_opt_get_int(opts->basic, SDAP_NETWORK_TIMEOUT)));

+                   dp_opt_get_int(state->opts->basic, SDAP_NETWORK_TIMEOUT)));

          goto fail;

      }

  

      /* Set Default Timeout */

-     tv.tv_sec = dp_opt_get_int(opts->basic, SDAP_OPT_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(1, ("Failed to set default timeout to %d\n",

-                   dp_opt_get_int(opts->basic, SDAP_OPT_TIMEOUT)));

+                   dp_opt_get_int(state->opts->basic, SDAP_OPT_TIMEOUT)));

          goto fail;

      }

  

      /* Set Referral chasing */

-     ldap_referrals = dp_opt_get_bool(opts->basic, SDAP_REFERRALS);

+     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) {
@@ -168,9 +236,9 @@

              goto fail;

          }

  

-         rebind_proc_params->opts = opts;

+         rebind_proc_params->opts = state->opts;

          rebind_proc_params->sh = state->sh;

-         rebind_proc_params->use_start_tls = use_start_tls;

+         rebind_proc_params->use_start_tls = state->use_start_tls;

  

          lret = ldap_set_rebind_proc(state->sh->ldap, sdap_rebind_proc,

                                      rebind_proc_params);
@@ -181,7 +249,7 @@

      }

  

      /* Set alias dereferencing */

-     ldap_deref = dp_opt_get_string(opts->basic, SDAP_DEREF);

+     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) {
@@ -197,37 +265,44 @@

  

      }

  

-     ret = setup_ldap_connection_callbacks(state->sh, state->ev);

-     if (ret != EOK) {

-         DEBUG(1, ("setup_ldap_connection_callbacks failed.\n"));

-         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(3,

+               ("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");

      }

  

      /* 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 (!use_start_tls) {

+     if (!state->use_start_tls) {

          tevent_req_done(req);

-         tevent_req_post(req, ev);

-         return req;

+         return;

      }

  

      DEBUG(4, ("Executing START TLS\n"));

  

      lret = ldap_start_tls(state->sh->ldap, NULL, NULL, &msgid);

      if (lret != LDAP_SUCCESS) {

-         optret = ldap_get_option(state->sh->ldap,

-                                  SDAP_DIAGNOSTIC_MESSAGE,

-                                  (void*)&errmsg);

+         optret = sss_ldap_get_diagnostic_msg(state, state->sh->ldap,

+                                              &errmsg);

          if (optret == LDAP_SUCCESS) {

              DEBUG(3, ("ldap_start_tls failed: [%s] [%s]\n",

-                       ldap_err2string(lret),

+                       sss_ldap_err2string(lret),

                        errmsg));

              sss_log(SSS_LOG_ERR, "Could not start TLS. %s", errmsg);

-             ldap_memfree(errmsg);

          }

          else {

              DEBUG(3, ("ldap_start_tls failed: [%s]\n",

-                       ldap_err2string(lret)));

+                       sss_ldap_err2string(lret)));

              sss_log(SSS_LOG_ERR, "Could not start TLS. "

                                   "Check for certificate issues.");

          }
@@ -238,14 +313,14 @@

      if (ret) goto fail;

  

      /* FIXME: get timeouts from configuration, for now 5 secs. */

-     ret = sdap_op_add(state, ev, state->sh, msgid,

+     ret = sdap_op_add(state, state->ev, state->sh, msgid,

                        sdap_connect_done, req, 5, &state->op);

      if (ret) {

          DEBUG(1, ("Failed to set up operation!\n"));

          goto fail;

      }

  

-     return req;

+     return;

  

  fail:

      if (ret) {
@@ -257,8 +332,7 @@

              tevent_req_error(req, EIO);

          }

      }

-     tevent_req_post(req, ev);

-     return req;

+     return;

  }

  

  static void sdap_connect_done(struct sdap_op *op,
@@ -289,7 +363,7 @@

      }

  

      DEBUG(3, ("START TLS result: %s(%d), %s\n",

-               ldap_err2string(state->result), state->result, errmsg));

+               sss_ldap_err2string(state->result), state->result, errmsg));

      ldap_memfree(errmsg);

  

      if (ldap_tls_inplace(state->sh->ldap)) {
@@ -302,19 +376,17 @@

      ret = ldap_install_tls(state->sh->ldap);

      if (ret != LDAP_SUCCESS) {

  

-         optret = ldap_get_option(state->sh->ldap,

-                                  SDAP_DIAGNOSTIC_MESSAGE,

-                                  (void*)&tlserr);

+         optret = sss_ldap_get_diagnostic_msg(state, state->sh->ldap,

+                                              &tlserr);

          if (optret == LDAP_SUCCESS) {

              DEBUG(3, ("ldap_install_tls failed: [%s] [%s]\n",

-                       ldap_err2string(ret),

+                       sss_ldap_err2string(ret),

                        tlserr));

              sss_log(SSS_LOG_ERR, "Could not start TLS encryption. %s", tlserr);

-             ldap_memfree(tlserr);

          }

          else {

              DEBUG(3, ("ldap_install_tls failed: [%s]\n",

-                       ldap_err2string(ret)));

+                       sss_ldap_err2string(ret)));

              sss_log(SSS_LOG_ERR, "Could not start TLS encryption. "

                                   "Check for certificate issues.");

          }
@@ -390,10 +462,10 @@

      state->user_dn = user_dn;

      state->pw = pw;

  

-     ret = sdap_control_create(state->sh, LDAP_CONTROL_PASSWORDPOLICYREQUEST,

-                               0, NULL, 0, &ctrls[0]);

+     ret = sss_ldap_control_create(LDAP_CONTROL_PASSWORDPOLICYREQUEST,

+                                   0, NULL, 0, &ctrls[0]);

      if (ret != LDAP_SUCCESS && ret != LDAP_NOT_SUPPORTED) {

-         DEBUG(1, ("sdap_control_create failed to create "

+         DEBUG(1, ("sss_ldap_control_create failed to create "

                    "Password Policy control.\n"));

          goto fail;

      }
@@ -412,7 +484,7 @@

              ret = LDAP_LOCAL_ERROR;

          } else {

              DEBUG(1, ("ldap_bind failed (%d)[%s]\n",

-                       ldap_err, ldap_err2string(ldap_err)));

+                       ldap_err, sss_ldap_err2string(ldap_err)));

              ret = ldap_err;

          }

          goto fail;
@@ -528,7 +600,7 @@

      }

  

      DEBUG(3, ("Bind result: %s(%d), %s\n",

-               ldap_err2string(state->result), state->result, errmsg));

+               sss_ldap_err2string(state->result), state->result, errmsg));

  

      ret = LDAP_SUCCESS;

  done:
@@ -607,7 +679,7 @@

      state->result = ret;

      if (ret != LDAP_SUCCESS) {

          DEBUG(1, ("ldap_sasl_bind failed (%d)[%s]\n",

-                   ret, ldap_err2string(ret)));

+                   ret, sss_ldap_err2string(ret)));

          goto fail;

      }

  
@@ -780,7 +852,8 @@

  

      next_req = be_resolve_server_send(state, state->ev,

                                        state->be,

-                                       state->krb_service_name);

+                                       state->krb_service_name,

+                                       state->kdc_srv == NULL ? true : false);

      if (next_req == NULL) {

          DEBUG(1, ("be_resolve_server_send failed.\n"));

          return NULL;
@@ -837,7 +910,18 @@

      ret = sdap_get_tgt_recv(subreq, state, &result,

                              &kerr, &ccname, &expire_time);

      talloc_zfree(subreq);

-     if (ret != EOK) {

+     if (ret == ETIMEDOUT) {

+         /* The child didn't even respond. Perhaps the KDC is too busy,

+          * retry with another KDC */

+         DEBUG(4, ("Communication with KDC timed out, trying the next one\n"));

+         be_fo_set_port_status(state->be, 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. */

          state->result = SDAP_AUTH_FAILED;

          DEBUG(1, ("child failed (%d [%s])\n", ret, strerror(ret)));

          tevent_req_error(req, ret);
@@ -858,7 +942,7 @@

          return;

      } else {

          if (kerr == KRB5_KDC_UNREACH) {

-             fo_set_port_status(state->kdc_srv, PORT_NOT_WORKING);

+             be_fo_set_port_status(state->be, state->kdc_srv, PORT_NOT_WORKING);

              nextreq = sdap_kinit_next_kdc(req);

              if (!nextreq) {

                  tevent_req_error(req, ENOMEM);
@@ -1084,7 +1168,6 @@

      state->be = be;

      state->srv = NULL;

      state->srv_opts = NULL;

-     state->be = be;

      state->use_rootdse = !skip_rootdse;

  

      ret = sdap_cli_resolve_next(req);
@@ -1107,7 +1190,8 @@

      /* 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->be, state->service->name,

+                                     state->srv == NULL ? true : false);

      if (!subreq) {

          return ENOMEM;

      }
@@ -1123,6 +1207,8 @@

      struct sdap_cli_connect_state *state = tevent_req_data(req,

                                               struct sdap_cli_connect_state);

      int ret;

+     bool use_tls = dp_opt_get_bool(state->opts->basic,

+                                    SDAP_ID_TLS);

  

      ret = be_resolve_server_recv(subreq, &state->srv);

      talloc_zfree(subreq);
@@ -1134,10 +1220,16 @@

          return;

      }

  

+     if (use_tls && sdap_is_secure_uri(state->service->uri)) {

+         DEBUG(8, ("[%s] is a secure channel. No need to run START_TLS\n",

+                   state->service->uri));

+         use_tls = false;

+     }

+ 

      subreq = sdap_connect_send(state, state->ev, state->opts,

                                 state->service->uri,

-                                dp_opt_get_bool(state->opts->basic,

-                                                SDAP_ID_TLS));

+                                state->service->sockaddr,

+                                use_tls);

      if (!subreq) {

          tevent_req_error(req, ENOMEM);

          return;
@@ -1158,16 +1250,12 @@

      ret = sdap_connect_recv(subreq, state, &state->sh);

      talloc_zfree(subreq);

      if (ret) {

-         if (ret == ETIMEDOUT) { /* retry another server */

-             fo_set_port_status(state->srv, PORT_NOT_WORKING);

-             ret = sdap_cli_resolve_next(req);

-             if (ret != EOK) {

-                 tevent_req_error(req, ret);

-             }

-             return;

+         /* retry another server */

+         be_fo_set_port_status(state->be, state->srv, PORT_NOT_WORKING);

+         ret = sdap_cli_resolve_next(req);

+         if (ret != EOK) {

+             tevent_req_error(req, ret);

          }

- 

-         tevent_req_error(req, ret);

          return;

      }

  
@@ -1237,7 +1325,7 @@

      talloc_zfree(subreq);

      if (ret) {

          if (ret == ETIMEDOUT) { /* retry another server */

-             fo_set_port_status(state->srv, PORT_NOT_WORKING);

+             be_fo_set_port_status(state->be, state->srv, PORT_NOT_WORKING);

              ret = sdap_cli_resolve_next(req);

              if (ret != EOK) {

                  tevent_req_error(req, ret);
@@ -1253,6 +1341,7 @@

               * work properly.

               */

              state->use_rootdse = false;

+             rootdse = NULL;

          }

  

          else {
@@ -1261,19 +1350,22 @@

          }

      }

  

-     /* save rootdse data about supported features */

-     ret = sdap_set_rootdse_supported_lists(rootdse, state->sh);

-     if (ret) {

-         tevent_req_error(req, ret);

-         return;

-     }

+     if (state->use_rootdse) {

+         /* save rootdse data about supported features */

+         ret = sdap_set_rootdse_supported_lists(rootdse, state->sh);

+         if (ret) {

+             tevent_req_error(req, ret);

+             return;

+         }

+ 

+         ret = sdap_set_config_options_with_rootdse(rootdse, state->sh,

+                                                    state->opts);

+         if (ret) {

+             DEBUG(1, ("sdap_set_config_options_with_rootdse failed.\n"));

+             tevent_req_error(req, ret);

+             return;

+         }

  

-     ret = sdap_set_config_options_with_rootdse(rootdse, state->sh,

-                                                state->opts);

-     if (ret) {

-         DEBUG(1, ("sdap_set_config_options_with_rootdse failed.\n"));

-         tevent_req_error(req, ret);

-         return;

      }

  

      ret = sdap_get_server_opts_from_rootdse(state,
@@ -1344,20 +1436,10 @@

  

      ret = sdap_kinit_recv(subreq, &result, &expire_time);

      talloc_zfree(subreq);

-     if (ret) {

-         if (ret == ETIMEDOUT) { /* child timed out, retry another server */

-             fo_set_port_status(state->srv, PORT_NOT_WORKING);

-             ret = sdap_cli_resolve_next(req);

-             if (ret != EOK) {

-                 tevent_req_error(req, ret);

-             }

-             return;

-         }

- 

-         tevent_req_error(req, ret);

-         return;

-     }

-     if (result != SDAP_AUTH_SUCCESS) {

+     if (ret != EOK || result != SDAP_AUTH_SUCCESS) {

+         /* We're not able to authenticate to the LDAP server.

+          * There's not much we can do except for going offline */

+         DEBUG(6, ("Cannot get a TGT: ret [%d] result [%d]\n", ret, result));

          tevent_req_error(req, EACCES);

          return;

      }
@@ -1430,7 +1512,7 @@

      if (tevent_req_is_error(req, &tstate, &err)) {

          /* mark the server as bad if connection failed */

          if (state->srv) {

-             fo_set_port_status(state->srv, PORT_NOT_WORKING);

+             be_fo_set_port_status(state->be, state->srv, PORT_NOT_WORKING);

          } else {

              if (can_retry) {

                  *can_retry = false;
@@ -1442,7 +1524,7 @@

          }

          return EIO;

      } else if (state->srv) {

-         fo_set_port_status(state->srv, PORT_WORKING);

+         be_fo_set_port_status(state->be, state->srv, PORT_WORKING);

      }

  

      if (gsh) {
@@ -1472,69 +1554,76 @@

      int msgid;

      char *errmsg = NULL;

      LDAPMessage *result;

+     TALLOC_CTX *tmp_ctx;

  

      DEBUG(4, ("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 = ldap_get_option(ldap, SDAP_DIAGNOSTIC_MESSAGE, (void*)&errmsg);

+         optret = sss_ldap_get_diagnostic_msg(tmp_ctx, ldap, &errmsg);

          if (optret == LDAP_SUCCESS) {

              DEBUG(3, ("ldap_start_tls failed: [%s] [%s]\n",

-                       ldap_err2string(lret), errmsg));

+                       sss_ldap_err2string(lret), errmsg));

              sss_log(SSS_LOG_ERR, "Could not start TLS. %s", errmsg);

-             ldap_memfree(errmsg);

          } else {

-             DEBUG(3, ("ldap_start_tls failed: [%s]\n", ldap_err2string(lret)));

+             DEBUG(3, ("ldap_start_tls failed: [%s]\n", sss_ldap_err2string(lret)));

              sss_log(SSS_LOG_ERR, "Could not start TLS. "

                                   "Check for certificate issues.");

          }

-         return lret;

+         goto done;

      }

  

      lret = ldap_result(ldap, msgid, 1, NULL, &result);

      if (lret != LDAP_RES_EXTENDED) {

          DEBUG(2, ("Unexpected ldap_result, expected [%d] got [%d].\n",

                    LDAP_RES_EXTENDED, lret));

-         return LDAP_PARAM_ERROR;

+         lret = LDAP_PARAM_ERROR;

+         goto done;

      }

  

      lret = ldap_parse_result(ldap, result, &ldaperr, NULL, &errmsg, NULL, NULL,

                               0);

      if (lret != LDAP_SUCCESS) {

          DEBUG(2, ("ldap_parse_result failed (%d) [%d][%s]\n", msgid, lret,

-                   ldap_err2string(lret)));

-         return lret;

+                   sss_ldap_err2string(lret)));

+         goto done;

      }

  

      DEBUG(3, ("START TLS result: %s(%d), %s\n",

-               ldap_err2string(ldaperr), ldaperr, errmsg));

+               sss_ldap_err2string(ldaperr), ldaperr, errmsg));

      ldap_memfree(errmsg);

  

      if (ldap_tls_inplace(ldap)) {

          DEBUG(9, ("SSL/TLS handler already in place.\n"));

-         return LDAP_SUCCESS;

+         lret = LDAP_SUCCESS;

+         goto done;

      }

  

      lret = ldap_install_tls(ldap);

      if (lret != LDAP_SUCCESS) {

  

-         optret = ldap_get_option(ldap, SDAP_DIAGNOSTIC_MESSAGE, (void*)&errmsg);

+         optret = sss_ldap_get_diagnostic_msg(tmp_ctx, ldap, &errmsg);

          if (optret == LDAP_SUCCESS) {

              DEBUG(3, ("ldap_install_tls failed: [%s] [%s]\n",

-                       ldap_err2string(lret), errmsg));

+                       sss_ldap_err2string(lret), errmsg));

              sss_log(SSS_LOG_ERR, "Could not start TLS encryption. %s", errmsg);

-             ldap_memfree(errmsg);

          } else {

              DEBUG(3, ("ldap_install_tls failed: [%s]\n",

-                       ldap_err2string(lret)));

+                       sss_ldap_err2string(lret)));

              sss_log(SSS_LOG_ERR, "Could not start TLS encryption. "

                                   "Check for certificate issues.");

          }

  

-         return lret;

+         goto done;

      }

  

-     return LDAP_SUCCESS;

+     lret = LDAP_SUCCESS;

+ done:

+     talloc_zfree(tmp_ctx);

+     return lret;

  }

  

  static int sdap_rebind_proc(LDAP *ldap, LDAP_CONST char *url, ber_tag_t request,
@@ -1553,7 +1642,7 @@

  

      if (p->use_start_tls) {

          ret = synchronous_tls_setup(ldap);

-         if (ret != EOK) {

+         if (ret != LDAP_SUCCESS) {

              DEBUG(1, ("synchronous_tls_setup failed.\n"));

              return ret;

          }
@@ -1568,10 +1657,10 @@

      sasl_mech = dp_opt_get_string(p->opts->basic, SDAP_SASL_MECH);

  

      if (sasl_mech == NULL) {

-         ret = sdap_control_create(p->sh, LDAP_CONTROL_PASSWORDPOLICYREQUEST,

-                                   0, NULL, 0, &ctrls[0]);

+         ret = sss_ldap_control_create(LDAP_CONTROL_PASSWORDPOLICYREQUEST,

+                                       0, NULL, 0, &ctrls[0]);

          if (ret != LDAP_SUCCESS && ret != LDAP_NOT_SUPPORTED) {

-             DEBUG(1, ("sdap_control_create failed to create "

+             DEBUG(1, ("sss_ldap_control_create failed to create "

                        "Password Policy control.\n"));

              goto done;

          }
@@ -1596,7 +1685,7 @@

                                 request_controls, NULL, NULL);

          if (ret != LDAP_SUCCESS) {

              DEBUG(1, ("ldap_sasl_bind_s failed (%d)[%s]\n", ret,

-                       ldap_err2string(ret)));

+                       sss_ldap_err2string(ret)));

          }

      } else {

          sasl_bind_state = talloc_zero(tmp_ctx, struct sasl_bind_state);
@@ -1614,7 +1703,7 @@

                                             sasl_bind_state);

          if (ret != LDAP_SUCCESS) {

              DEBUG(1, ("ldap_sasl_interactive_bind_s failed (%d)[%s]\n", ret,

-                       ldap_err2string(ret)));

+                       sss_ldap_err2string(ret)));

          }

      }

  

@@ -469,7 +469,8 @@

                                     cn_attr, state->opts->netgroup_map,

                                     SDAP_OPTS_NETGROUP,

                                     dp_opt_get_int(state->opts->basic,

-                                                   SDAP_SEARCH_TIMEOUT));

+                                                   SDAP_SEARCH_TIMEOUT),

+                                    false);

      if (!subreq) {

          DEBUG(1, ("sdap_get_generic_send failed.\n"));

          return ENOMEM;
@@ -610,7 +611,7 @@

                                     LDAP_SCOPE_SUBTREE,

                                     state->filter, state->attrs,

                                     state->opts->netgroup_map,

-                                    SDAP_OPTS_NETGROUP, timeout);

+                                    SDAP_OPTS_NETGROUP, timeout, false);

      if (!subreq) {

          talloc_zfree(req);

          return NULL;

@@ -40,6 +40,8 @@

  

  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,

@@ -121,7 +121,7 @@

          fd_nonblocking(child->read_from_child_fd);

          fd_nonblocking(child->write_to_child_fd);

  

-         ret = child_handler_setup(ev, pid, NULL, NULL);

+         ret = child_handler_setup(ev, pid, NULL, NULL, NULL);

          if (ret != EOK) {

              return ret;

          }

@@ -38,7 +38,7 @@

      int ret;

  

      ret = ldap_get_option(ldap, LDAP_OPT_DESC, fd);

-     if (ret != LDAP_OPT_SUCCESS) {

+     if (ret != LDAP_OPT_SUCCESS || *fd < 0) {

          DEBUG(1, ("Failed to get fd from ldap!!\n"));

          *fd = -1;

          return EIO;
@@ -273,3 +273,42 @@

  

      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(1, ("ber_sockbuf_alloc failed.\n"));

+         return ENOMEM;

+     }

+ 

+     ret = ber_sockbuf_ctrl(sb, LBER_SB_OPT_SET_FD, &fd);

+     if (ret != 1) {

+         DEBUG(1, ("ber_sockbuf_ctrl failed.\n"));

+         return EFAULT;

+     }

+ 

+     ret = ldap_url_parse(uri, &lud);

+     if (ret != 0) {

+         ber_sockbuf_free(sb);

+         DEBUG(1, ("ldap_url_parse failed to validate [%s] on fd [%ld].\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(9, ("LDAP connection callbacks are not supported.\n"));

+     return EOK;

+ #endif

+ }

@@ -1078,7 +1078,7 @@

              break;

  

          case BE_FILTER_IDNUM:

-             uid = (uid_t) strtouint32(ar->filter_value, &endptr, 0);

+             uid = (uid_t) strtouint32(ar->filter_value, &endptr, 10);

              if (errno || *endptr || (ar->filter_value == endptr)) {

                  return proxy_reply(breq, DP_ERR_FATAL,

                                     EINVAL, "Invalid attr type");
@@ -1100,7 +1100,7 @@

              ret = get_gr_name(breq, ctx, sysdb, domain, ar->filter_value);

              break;

          case BE_FILTER_IDNUM:

-             gid = (gid_t) strtouint32(ar->filter_value, &endptr, 0);

+             gid = (gid_t) strtouint32(ar->filter_value, &endptr, 10);

              if (errno || *endptr || (ar->filter_value == endptr)) {

                  return proxy_reply(breq, DP_ERR_FATAL,

                                     EINVAL, "Invalid attr type");

@@ -465,7 +465,7 @@

      }

  

      ret = sbus_new_server(ctx, bectx->ev, sbus_address, &proxy_interface,

-                           &ctx->sbus_srv, proxy_client_init, ctx);

+                           false, &ctx->sbus_srv, proxy_client_init, ctx);

      if (ret != EOK) {

          DEBUG(0, ("Could not set up sbus server.\n"));

          goto done;

@@ -158,22 +158,28 @@

      if (ret != EOK) {

          DEBUG(1, ("Could not look up primary group [%lu]: [%d][%s]\n",

                    gid, ret, strerror(ret)));

-         goto done;

-     }

+         /* 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 {

+         primary_group = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);

+         if (!primary_group) {

+             ret = EINVAL;

+             goto done;

+         }

  

-     primary_group = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);

-     if (!primary_group) {

-         ret = EINVAL;

-         goto done;

-     }

+         groups[j] = talloc_strdup(tmp_ctx, primary_group);

+         if (!groups[j]) {

+             ret = ENOMEM;

+             goto done;

+         }

+         j++;

  

-     groups[j] = talloc_strdup(tmp_ctx, primary_group);

-     if (!groups[j]) {

-         ret = ENOMEM;

-         goto done;

+         talloc_zfree(msg);

      }

-     groups[j+1] = NULL;

-     talloc_zfree(msg);

+ 

+     groups[j] = NULL;

  

      /* Now process allow and deny group rules

       * If access was already granted above, we'll skip

file added
+1957
The added file is too large to be shown here, see it at: src/python/pyhbac.c
@@ -143,11 +143,11 @@

            srv_last = srv_curr;

  

            vptr = aptr;

-           srv_curr->priority = ntohs (*((const unsigned short *)vptr));

+           srv_curr->priority = DNS__16BIT(vptr);

            vptr += sizeof(const unsigned short);

-           srv_curr->weight = ntohs (*((const unsigned short *)vptr));

+           srv_curr->weight = DNS__16BIT(vptr);

            vptr += sizeof(const unsigned short);

-           srv_curr->port = ntohs (*((const unsigned short *)vptr));

+           srv_curr->port = DNS__16BIT(vptr);

            vptr += sizeof(const unsigned short);

  

            status = ares_expand_name (vptr, abuf, alen, &srv_curr->host, &len);

file modified
+792 -131
@@ -53,6 +53,19 @@

      _ares_malloc_data(data)

  #endif /* HAVE_ARES_DATA */

  

+ #ifndef HAVE_STRUCT_ARES_ADDRTTL

+ #define ares_addrttl addrttl

+ #endif

+ 

+ #ifndef HAVE_STRUCT_ARES_ADDR6TTL

+ #define ares_addr6ttl addr6ttl

+ #endif

+ 

+ #define DNS__16BIT(p)                   (((p)[0] << 8) | (p)[1])

+ #define DNS_HEADER_ANCOUNT(h)           DNS__16BIT((h) + 6)

+ 

+ enum host_database default_host_dbs[] = { DB_FILES, DB_DNS, DB_SENTINEL };

+ 

  struct fd_watch {

      struct fd_watch *prev;

      struct fd_watch *next;
@@ -330,8 +343,9 @@

      options.sock_state_cb = fd_event;

      options.sock_state_cb_data = ctx;

      options.timeout = ctx->timeout * 1000;

-     options.lookups = discard_const("fb");

-     options.tries = 0;

+     /* 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 |
@@ -398,57 +412,170 @@

      }

  }

  

- struct hostent *

- resolv_copy_hostent(TALLOC_CTX *mem_ctx, struct hostent *src)

+ 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)

  {

-     struct hostent *ret;

+     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 hostent);

+     ret = talloc_zero(mem_ctx, struct resolv_hostent);

      if (ret == NULL) {

          return NULL;

      }

  

      if (src->h_name != NULL) {

-         ret->h_name = talloc_strdup(ret, src->h_name);

-         if (ret->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->h_aliases = talloc_size(ret, sizeof(char *) * (len + 1));

-         if (ret->h_aliases == NULL) {

+ 

+         ret->aliases = talloc_array(ret, char *, len + 1);

+         if (ret->aliases == NULL) {

              goto fail;

          }

+ 

          for (i = 0; i < len; i++) {

-             ret->h_aliases[i] = talloc_strdup(ret->h_aliases, src->h_aliases[i]);

-             if (ret->h_aliases[i] == NULL) {

+             ret->aliases[i] = talloc_strdup(ret->aliases, src->h_aliases[i]);

+             if (ret->aliases[i] == NULL) {

                  goto fail;

              }

          }

-         ret->h_aliases[len] = NULL;

+         ret->aliases[len] = NULL;

      }

-     ret->h_addrtype = src->h_addrtype;

-     ret->h_length = src->h_length;

+ 

+     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->h_addr_list = talloc_size(ret, sizeof(char *) * (len + 1));

-         if (ret->h_addr_list == NULL) {

+ 

+         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->h_addr_list[i] = talloc_memdup(ret->h_addr_list,

-                                                 src->h_addr_list[i],

-                                                 ret->h_length);

-             if (ret->h_addr_list[i] == NULL) {

+             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(1, ("Unknown address family %d\n"));

+                 goto fail;

+             }

+ 

+             if (cret != EOK) {

+                 DEBUG(1, ("Could not copy address\n"));

                  goto fail;

              }

          }

-         ret->h_addr_list[len] = NULL;

+         ret->addr_list[num_ares_ttl_data] = NULL;

      }

  

+     ret->family = family;

      return ret;

  

  fail:
@@ -456,35 +583,135 @@

      return NULL;

  }

  

- /*******************************************************************

-  * Get host by name.                                               *

-  *******************************************************************/

+ /* =================== Resolve host name in files =========================*/

+ struct gethostbyname_files_state {

+     struct resolv_ctx *resolv_ctx;

  

- struct gethostbyname_state {

+     /* 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(4, ("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;

-     /* In which order to use IPv4, or v6 */

-     enum restrict_family family_order;

-     /* These are returned by ares. The hostent struct will be freed

-      * when the user callback returns. */

-     struct hostent *hostent;

+ 

+     /* query result */

+     struct resolv_hostent *rhostent;

+ 

+     /* These are returned by ares. */

      int status;

      int timeouts;

      int retrying;

  };

  

  static void

- ares_gethostbyname_wakeup(struct tevent_req *req);

+ 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,

+                                int timeouts, unsigned char *abuf, int alen);

  

- 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)

+ 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_state *state;

+     struct gethostbyname_dns_state *state;

      struct timeval tv = { 0, 0 };

  

      if (ctx->channel == NULL) {
@@ -492,25 +719,22 @@

          return NULL;

      }

  

-     req = tevent_req_create(mem_ctx, &state, struct gethostbyname_state);

-     if (req == 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->hostent = NULL;

+     state->rhostent = NULL;

      state->status = 0;

      state->timeouts = 0;

      state->retrying = 0;

-     state->family_order = family_order;

-     state->family = (family_order < IPV6_ONLY) ? AF_INET : AF_INET6;

- 

-     DEBUG(4, ("Trying to resolve %s record of '%s'\n",

-               state->family == AF_INET ? "A" : "AAAA",

-               state->name));

+     state->family = family;

  

-     /* We need to have a wrapper around ares_gethostbyname(), because

-      * ares_gethostbyname() can in some cases call it's callback immediately.

+     /* 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) {
@@ -518,116 +742,516 @@

          talloc_zfree(req);

          return NULL;

      }

-     tevent_req_set_callback(subreq, ares_gethostbyname_wakeup, req);

+     tevent_req_set_callback(subreq, resolv_gethostbyname_dns_wakeup, req);

      schedule_timeout_watcher(ev, ctx);

  

      return req;

  }

  

  static void

- resolv_gethostbyname_next_done(void *arg, int status, int timeouts, struct hostent *hostent);

+ 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(1, ("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)

+ {

+     DEBUG(4, ("Trying to resolve %s record of '%s' in DNS\n",

+               state->family == AF_INET ? "A" : "AAAA", state->name));

+ 

+     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, req);

+ }

  

  static void

- resolv_gethostbyname_done(void *arg, int status, int timeouts, struct hostent *hostent)

+ resolv_gethostbyname_dns_query_done(void *arg, int status, int timeouts,

+                                     unsigned char *abuf, int alen)

  {

      struct tevent_req *req = talloc_get_type(arg, struct tevent_req);

-     struct gethostbyname_state *state = tevent_req_data(req, struct gethostbyname_state);

+     struct gethostbyname_dns_state *state = tevent_req_data(req,

+                                         struct gethostbyname_dns_state);

+     errno_t ret;

+ 

+     unschedule_timeout_watcher(state->resolv_ctx);

+ 

+     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->resolv_ctx->channel != NULL) {

          state->retrying = 1;

-         ares_gethostbyname(state->resolv_ctx->channel, state->name,

-                            state->family, resolv_gethostbyname_done, req);

+         schedule_timeout_watcher(state->ev, state->resolv_ctx);

+         resolv_gethostbyname_dns_query(req, state);

          return;

      }

  

-     unschedule_timeout_watcher(state->resolv_ctx);

- 

-     if (hostent != NULL) {

-         state->hostent = resolv_copy_hostent(req, hostent);

-         if (state->hostent == NULL) {

-             tevent_req_error(req, ENOMEM);

-             return;

-         }

-     } else {

-         state->hostent = NULL;

+     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;

      }

-     state->status = status;

-     state->timeouts = timeouts;

  

      if (status != ARES_SUCCESS) {

-         if (status == ARES_ENOTFOUND || status == ARES_ENODATA) {

-             if (state->family_order == IPV4_FIRST) {

-                 state->family = AF_INET6;

-             } else if (state->family_order == IPV6_FIRST) {

-                 state->family = AF_INET;

-             } else {

-                 tevent_req_error(req, return_code(status));

-                 return;

-             }

- 

-             state->retrying = 0;

-             state->timeouts = 0;

-             DEBUG(4, ("Trying to resolve %s record of '%s'\n",

-                       state->family == AF_INET ? "A" : "AAAA",

-                       state->name));

-             schedule_timeout_watcher(state->resolv_ctx->ev_ctx,

-                                      state->resolv_ctx);

-             ares_gethostbyname(state->resolv_ctx->channel, state->name,

-                                state->family, resolv_gethostbyname_next_done,

-                                req);

-             return;

-         }

- 

          /* 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, timeouts, 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, int timeouts,

+                                unsigned char *abuf, int alen)

+ {

+     TALLOC_CTX *tmp_ctx;

+     struct hostent *hostent;

+     int naddrttls;

+     errno_t ret;

+     void *addr;

+ 

+     tmp_ctx = talloc_new(NULL);

+     if (!tmp_ctx) return ENOMEM;

+ 

+     naddrttls = DNS_HEADER_ANCOUNT(abuf);

+ 

+     switch (state->family) {

+         case AF_INET:

+             DEBUG(7, ("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(7, ("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(1, ("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);

+         free(hostent);

+         if (state->rhostent == NULL) {

+             ret = ENOMEM;

+             goto fail;

+         }

+     }

+ 

+     talloc_free(tmp_ctx);

+     return return_code(status);

+ 

+ fail:

+     talloc_free(tmp_ctx);

+     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;

+     }

+     if (rhostent) {

+         *rhostent = talloc_steal(mem_ctx, state->rhostent);

+     }

+ 

+     TEVENT_REQ_RETURN_ON_ERROR(req);

+ 

+     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(1, ("Invalid ares channel - this is likely a bug\n"));

+         return NULL;

      }

-     else {

+ 

+     req = tevent_req_create(mem_ctx, &state, struct gethostbyname_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_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(1, ("Canot create a fake hostent structure\n"));

+             talloc_zfree(req);

+             return NULL;

+         }

+ 

          tevent_req_done(req);

+         tevent_req_post(req, ev);

+         return req;

      }

+ 

+     ret = resolv_gethostbyname_step(req);

+     if (ret != EOK) {

+         DEBUG(1, ("Cannot start the resolving\n"));

+         talloc_zfree(req);

+         return NULL;

+     }

+ 

+     return req;

  }

  

- static void

- resolv_gethostbyname_next_done(void *arg, int status, int timeouts, struct hostent *hostent)

+ static bool

+ resolv_is_address(const char *name)

  {

-     struct tevent_req *req = talloc_get_type(arg, struct tevent_req);

-     struct gethostbyname_state *state = tevent_req_data(req, struct gethostbyname_state);

+     struct addrinfo hints;

+     struct addrinfo *res = NULL;

+     int ret;

  

-     if (state->retrying == 0 && status == ARES_EDESTRUCTION) {

-         state->retrying = 1;

-         ares_gethostbyname(state->resolv_ctx->channel, state->name,

-                            state->family, resolv_gethostbyname_next_done, req);

-         return;

+     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);

+     freeaddrinfo(res);

+     if (ret != 0) {

+         if (ret == -2) {

+             DEBUG(9, ("[%s] does not look like an IP address\n", name));

+         } else {

+             DEBUG(2, ("getaddrinfo failed [%d]: %s\n",

+                       ret, gai_strerror(ret)));

+         }

      }

  

-     unschedule_timeout_watcher(state->resolv_ctx);

+     return ret == 0;

+ }

  

-     if (hostent != NULL) {

-         state->hostent = resolv_copy_hostent(req, hostent);

-         if (state->hostent == NULL) {

-             tevent_req_error(req, ENOMEM);

-             return;

+ 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(1, ("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(1, ("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 {

-         state->hostent = NULL;

+         /* No more address families for this DB, check if

+          * there is another DB to try */

+         DEBUG(5, ("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;

+         }

      }

-     state->status = status;

-     state->timeouts = timeouts;

  

-     if (status != ARES_SUCCESS) {

-         tevent_req_error(req, return_code(status));

+     DEBUG(4, ("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(8, ("Querying files\n"));

+             subreq = resolv_gethostbyname_files_send(state, state->ev,

+                                                      state->resolv_ctx,

+                                                      state->name,

+                                                      state->family);

+             break;

+         case DB_DNS:

+             DEBUG(8, ("Querying DNS\n"));

+             subreq = resolv_gethostbyname_dns_send(state, state->ev,

+                                                    state->resolv_ctx,

+                                                    state->name,

+                                                    state->family);

+             break;

+         default:

+             DEBUG(1, ("Invalid hosts database\n"));

+             return EINVAL;

      }

-     else {

-         tevent_req_done(req);

+ 

+     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(1, ("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;

      }

+ 

+     if (ret != EOK) {

+         DEBUG(2, ("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 hostent **hostent)

+                           struct resolv_hostent **rhostent)

  {

      struct gethostbyname_state *state = tevent_req_data(req, struct gethostbyname_state);

  
@@ -639,8 +1263,8 @@

      if (timeouts) {

          *timeouts = state->timeouts;

      }

-     if (hostent) {

-         *hostent = talloc_steal(mem_ctx, state->hostent);

+     if (rhostent) {

+         *rhostent = talloc_steal(mem_ctx, state->rhostent);

      }

  

      TEVENT_REQ_RETURN_ON_ERROR(req);
@@ -648,27 +1272,64 @@

      return EOK;

  }

  

- static void

- ares_gethostbyname_wakeup(struct tevent_req *subreq)

+ char *

+ resolv_get_string_address(TALLOC_CTX *mem_ctx, struct resolv_hostent *hostent)

  {

-     struct tevent_req *req = tevent_req_callback_data(subreq,

-                                                 struct tevent_req);

-     struct gethostbyname_state *state = tevent_req_data(req,

-                                                 struct gethostbyname_state);

+     char *address;

  

-     if (!tevent_wakeup_recv(subreq)) {

-         return;

+     if (!hostent) return NULL;

+ 

+     address = talloc_zero_size(mem_ctx, 128);

+     if (address == NULL) {

+         DEBUG(1, ("talloc_zero failed.\n"));

+         return NULL;

      }

-     talloc_zfree(subreq);

  

-     if (state->resolv_ctx->channel == NULL) {

-         DEBUG(1, ("Invalid ares channel - this is likely a bug\n"));

-         tevent_req_error(req, EIO);

-         return;

+     errno = 0;

+     if (inet_ntop(hostent->family, hostent->addr_list[0]->ipaddr,

+                   address, 128) == NULL) {

+         DEBUG(1, ("inet_ntop failed [%d][%s].\n", errno, strerror(errno)));

+         talloc_free(address);

+         return NULL;

+     }

+ 

+     return address;

+ }

+ 

+ struct sockaddr_storage *

+ resolv_get_sockaddr_address(TALLOC_CTX *mem_ctx, struct resolv_hostent *hostent,

+                             int port)

+ {

+     struct sockaddr_storage *sockaddr;

+ 

+     if (!hostent) return NULL;

+ 

+     sockaddr = talloc_zero(mem_ctx, struct sockaddr_storage);

+     if (sockaddr == NULL) {

+         DEBUG(1, ("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[0]->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[0]->ipaddr, sizeof(struct in6_addr));

+             ((struct sockaddr_in6 *) sockaddr)->sin6_port = (in_port_t) htons(port);

+             break;

+         default:

+             DEBUG(1, ("Unknown address family %d\n"));

+             return NULL;

      }

  

-     ares_gethostbyname(state->resolv_ctx->channel, state->name,

-                        state->family, resolv_gethostbyname_done, req);

+     return sockaddr;

  }

  

  /*

file modified
+50 -8
@@ -37,6 +37,10 @@

  #include "resolv/ares/ares_data.h"

  #endif /* HAVE_ARES_DATA */

  

+ #ifndef RESOLV_DEFAULT_TTL

+ #define RESOLV_DEFAULT_TTL 7200

+ #endif  /* RESOLV_DEFAULT_TTL */

+ 

  /*

   * An opaque structure which holds context for a module using the async

   * resolver. Is should be used as a "local-global" variable - in sssd,
@@ -53,10 +57,22 @@

  

  const char *resolv_strerror(int ares_code);

  

- struct hostent *resolv_copy_hostent(TALLOC_CTX *mem_ctx,

-                                     struct hostent *src);

+ 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,
@@ -64,17 +80,43 @@

      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 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(TALLOC_CTX *mem_ctx, struct resolv_hostent *hostent);

  

- int resolv_gethostbyname_recv(struct tevent_req *req,

-                               TALLOC_CTX *mem_ctx,

-                               int *status,

-                               int *timeouts,

-                               struct hostent **hostent);

+ struct sockaddr_storage *

+ resolv_get_sockaddr_address(TALLOC_CTX *mem_ctx, struct resolv_hostent *hostent,

+                             int port);

  

  /** Get SRV record **/

  struct tevent_req *resolv_getsrv_send(TALLOC_CTX *mem_ctx,

@@ -71,6 +71,8 @@

      char *ep;

      int ret;

  

+     DEBUG(8, ("Checking negative cache for [%s]\n", str));

+ 

      ret = string_to_tdb_data(str, &key);

      if (ret != EOK) goto done;

  
@@ -88,7 +90,7 @@

      }

  

      errno = 0;

-     timestamp = strtoull((const char *)data.dptr, &ep, 0);

+     timestamp = strtoull((const char *)data.dptr, &ep, 10);

      if (errno != 0 || *ep != '\0') {

          /* Malformed entry, remove it and return no entry */

          expired = true;
@@ -141,6 +143,9 @@

      ret = string_to_tdb_data(timest, &data);

      if (ret != EOK) goto done;

  

+     DEBUG(6, ("Adding [%s] to negative cache%s\n",

+               str, permanent?" permanently":""));

+ 

      ret = tdb_store(ctx->tdb, key, data, TDB_REPLACE);

      if (ret != 0) {

          DEBUG(1, ("Negative cache failed to set entry: [%s]\n",
@@ -325,7 +330,7 @@

      }

  

      errno = 0;

-     timestamp = strtoull((const char *)data.dptr, &ep, 0);

+     timestamp = strtoull((const char *)data.dptr, &ep, 10);

      if (errno != 0 || *ep != '\0') {

          /* Malformed entry, remove it */

          remove_key = true;

@@ -25,6 +25,7 @@

  #include <stdint.h>

  #include <sys/un.h>

  #include <pcre.h>

+ #include <sys/resource.h>

  #include "config.h"

  #include "talloc.h"

  #include "tevent.h"
@@ -81,6 +82,7 @@

      struct be_conn *be_conns;

  

      struct sss_domain_info *domains;

+     int client_idle_timeout;

      struct sysdb_ctx_list *db_list;

  

      struct sss_cmd_table *sss_cmds;
@@ -120,6 +122,8 @@

      int netgrent_cur;

  

      time_t pam_timeout;

+ 

+     struct tevent_timer *idle;

  };

  

  struct sss_cmd_table {
@@ -171,4 +175,8 @@

                           bool fast_reply, int type,

                           const char *opt_name, uint32_t opt_id);

  

+ bool sss_utf8_check(const uint8_t *s, size_t n);

+ 

+ void responder_set_fd_limit(rlim_t fd_limit);

+ 

  #endif /* __SSS_RESPONDER_H__ */

@@ -35,6 +35,7 @@

  #include <popt.h>

  #include "config.h"

  #include "util/util.h"

+ #include "util/sss_utf8.h"

  #include "db/sysdb.h"

  #include "confdb/confdb.h"

  #include "dbus/dbus.h"
@@ -89,7 +90,18 @@

  

  static int client_destructor(struct cli_ctx *ctx)

  {

-     if (ctx->cfd > 0) close(ctx->cfd);

+     errno_t ret;

+ 

+     if ((ctx->cfd > 0) && close(ctx->cfd) < 0) {

+         ret = errno;

+         DEBUG(1,

+               ("Failed to close fd [%d]: [%s]\n",

+                ctx->cfd, strerror(ret)));

+     }

+ 

+     DEBUG(9,

+           ("Terminated client [%p][%d]\n",

+            ctx, ctx->cfd));

      return 0;

  }

  
@@ -210,12 +222,24 @@

      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(1,

+               ("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;
@@ -226,59 +250,72 @@

      }

  }

  

- /* TODO: this is a copy of accept_fd_handler, maybe both can be put into on

-  * handler.  */

- static void accept_priv_fd_handler(struct tevent_context *ev,

+ 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 resp_ctx *rctx = talloc_get_type(ptr, struct resp_ctx);

+     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(1, ("stat on privileged pipe failed: [%d][%s].\n", errno,

+                       strerror(errno)));

+             return;

+         }

  

-     ret = stat(rctx->priv_sock_name, &stat_buf);

-     if (ret == -1) {

-         DEBUG(1, ("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(1, ("privileged pipe has an illegal status.\n"));

- /* TODO: what is the best response to this condition? Terminate? */

-         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(1, ("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;

-         int fd;

-         DEBUG(0, ("Out of memory trying to setup client context on privileged pipe!\n"));

+         DEBUG(0, ("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);

-         fd = accept(rctx->priv_lfd, (struct sockaddr *)&addr, &len);

-         if (fd == -1) {

+         client_fd = accept(fd, (struct sockaddr *)&addr, &len);

+         if (client_fd == -1) {

              return;

          }

-         close(fd);

+         close(client_fd);

          return;

      }

  

      len = sizeof(cctx->addr);

-     cctx->cfd = accept(rctx->priv_lfd, (struct sockaddr *)&cctx->addr, &len);

+     cctx->cfd = accept(fd, (struct sockaddr *)&cctx->addr, &len);

      if (cctx->cfd == -1) {

          DEBUG(1, ("Accept failed [%s]\n", strerror(errno)));

          talloc_free(cctx);

          return;

      }

  

-     cctx->priv = 1;

+     cctx->priv = accept_ctx->is_private;

  

      ret = get_client_cred(cctx);

      if (ret != EOK) {
@@ -291,7 +328,8 @@

      if (!cctx->cfde) {

          close(cctx->cfd);

          talloc_free(cctx);

-         DEBUG(2, ("Failed to queue client handler on privileged pipe\n"));

+         DEBUG(2, ("Failed to queue client handler%\n",

+                 accept_ctx->is_private ? " on privileged pipe" : ""));

      }

  

      cctx->ev = ev;
@@ -299,66 +337,18 @@

  

      talloc_set_destructor(cctx, client_destructor);

  

-     DEBUG(4, ("Client connected to privileged pipe!\n"));

- 

-     return;

- }

- 

- 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 resp_ctx *rctx = talloc_get_type(ptr, struct resp_ctx);

-     struct cli_ctx *cctx;

-     socklen_t len;

-     int ret;

+     DEBUG(4, ("Client connected%s!\n",

+               accept_ctx->is_private ? " to privileged pipe" : ""));

  

-     cctx = talloc_zero(rctx, struct cli_ctx);

-     if (!cctx) {

-         struct sockaddr_un addr;

-         int fd;

-         DEBUG(0, ("Out of memory trying to setup client context!\n"));

-         /* accept and close to signal the client we have a problem */

-         memset(&addr, 0, sizeof(addr));

-         len = sizeof(addr);

-         fd = accept(rctx->lfd, (struct sockaddr *)&addr, &len);

-         if (fd == -1) {

-             return;

-         }

-         close(fd);

-         return;

-     }

- 

-     len = sizeof(cctx->addr);

-     cctx->cfd = accept(rctx->lfd, (struct sockaddr *)&cctx->addr, &len);

-     if (cctx->cfd == -1) {

-         DEBUG(1, ("Accept failed [%s]\n", strerror(errno)));

-         talloc_free(cctx);

-         return;

-     }

- 

-     ret = get_client_cred(cctx);

+     /* Set up the idle timer */

+     ret = reset_idle_timer(cctx);

      if (ret != EOK) {

-         DEBUG(2, ("get_client_cred failed, "

-                   "client cred may not be available.\n"));

-     }

- 

-     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(2, ("Failed to queue client handler\n"));

+         DEBUG(1,

+               ("Could not create idle timer for client. "

+                "This connection may not auto-terminate\n"));

+         /* Non-fatal, continue */

      }

  

-     cctx->ev = ev;

-     cctx->rctx = rctx;

- 

-     talloc_set_destructor(cctx, client_destructor);

- 

-     DEBUG(4, ("Client connected!\n"));

- 

      return;

  }

  
@@ -395,6 +385,40 @@

      return EOK;

  }

  

+ 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(9,

+           ("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(8,

+           ("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_interface *intf,

                         const char *cli_name,
@@ -444,6 +468,7 @@

  {

      struct sockaddr_un addr;

      errno_t ret;

+     struct accept_fd_ctx *accept_ctx;

  

  /* for future use */

  #if 0
@@ -518,8 +543,14 @@

              goto failed;

          }

  

+         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, rctx);

+                                    TEVENT_FD_READ, accept_fd_handler,

+                                    accept_ctx);

          if (!rctx->lfde) {

              DEBUG(0, ("Failed to queue handler on pipe\n"));

              goto failed;
@@ -562,8 +593,14 @@

              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_priv_fd_handler, rctx);

+                                    TEVENT_FD_READ, accept_fd_handler,

+                                    accept_ctx);

          if (!rctx->priv_lfde) {

              DEBUG(0, ("Failed to queue handler on privileged pipe\n"));

              goto failed;
@@ -614,6 +651,23 @@

      rctx->priv_sock_name = sss_priv_pipe_name;

      rctx->confdb_service_path = confdb_service_path;

  

+     ret = confdb_get_int(rctx->cdb, NULL,

+                          rctx->confdb_service_path,

+                          CONFDB_RESPONDER_CLI_IDLE_TIMEOUT,

+                          CONFDB_RESPONDER_CLI_IDLE_DEFAULT_TIMEOUT,

+                          &rctx->client_idle_timeout);

+     if (ret != EOK) {

+         DEBUG(2,

+               ("Cannot get the client idle timeout [%d]: %s\n",

+                ret, strerror(ret)));

+         return ret;

+     }

+ 

+     /* Ensure that the client timeout is at least ten seconds */

+     if (rctx->client_idle_timeout < 10) {

+         rctx->client_idle_timeout = 10;

+     }

+ 

      ret = confdb_get_domains(rctx->cdb, &rctx->domains);

      if (ret != EOK) {

          DEBUG(0, ("fatal error setting up domain map\n"));
@@ -683,3 +737,56 @@

      return EOK;

  }

  

+ 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(4,

+               ("Maximum file descriptors set to [%d]\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, &current_limit);

+     if (limret == 0) {

+         DEBUG(7,

+               ("Current fd limit: [%d]\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(6,

+                   ("Maximum file descriptors set to [%d]\n",

+                    new_limit.rlim_cur));

+         } else {

+             DEBUG(2,

+                   ("Could not set new fd limits. Proceeding with [%d]\n",

+                    current_limit.rlim_cur));

+         }

+     } else {

+         DEBUG(2,

+               ("Could not determine fd limits. "

+                "Proceeding with system values\n"));

+     }

+ }

+ 

@@ -43,6 +43,7 @@

  };

  

  struct sss_dp_req {

+     struct resp_ctx *rctx;

      struct tevent_context *ev;

      DBusPendingCall *pending_reply;

  
@@ -68,7 +69,6 @@

  static int sss_dp_req_destructor(void *ptr)

  {

      struct sss_dp_req *sdp_req = talloc_get_type(ptr, struct sss_dp_req);

-     struct sss_dp_callback *cb, *next;

      hash_key_t key;

  

      /* Cancel Dbus pending reply if still pending */
@@ -77,71 +77,44 @@

          sdp_req->pending_reply = NULL;

      }

  

-     /* Destroy the hash entry */

+     /* Destroy the hash entry

+      * There are some situations when the entry has already

+      * been destroyed to avoid race condition, so don't check

+      * the result */

      key.type = HASH_KEY_STRING;

      key.str = sdp_req->key;

      int hret = hash_delete(dp_requests, &key);

      if (hret != HASH_SUCCESS) {

-         /* This should never happen */

-         DEBUG(0, ("Could not clear entry from request queue\n"));

-     }

- 

-     /* Free any remaining callback */

-     if (sdp_req->err_maj == DP_ERR_OK) {

-         sdp_req->err_maj = DP_ERR_FATAL;

-         sdp_req->err_min = EIO;

-         sdp_req->err_msg = discard_const_p(char, "Internal Error");

-     }

- 

-     cb = sdp_req->cb_list;

-     while (cb) {

-         next = cb->next;

-         /* It is the responsibility of the callback to free cb */

-         cb->callback(sdp_req->err_maj,

-                      sdp_req->err_min,

-                      sdp_req->err_msg,

-                      cb->callback_ctx);

-         cb = next;

+         DEBUG(8, ("Could not clear entry from request queue\n"));

      }

  

      return 0;

  }

  

- static bool reconnect_handler(hash_entry_t *item, void *user_data)

- {

-     struct sss_dp_req *sdp_req = talloc_get_type(item->value.ptr,

-                                                  struct sss_dp_req);

- 

-     return (talloc_free(sdp_req) == EOK ? true : false);

- }

- 

  void handle_requests_after_reconnect(void)

  {

      int ret;

+     hash_value_t *values;

+     unsigned long count, i;

+     struct sss_dp_req *sdp_req;

  

-     ret = hash_iterate(dp_requests, reconnect_handler, NULL);

+     if (!dp_requests) {

+         DEBUG(7, ("No requests to handle after reconnect\n"));

+         return;

+     }

+ 

+     ret = hash_values(dp_requests, &count, &values);

      if (ret != HASH_SUCCESS) {

-         DEBUG(1, ("hash_iterate failed, "

+         DEBUG(1, ("hash_values failed, "

                    "not all request might be handled after reconnect.\n"));

+         return;

      }

- }

- 

- static void sdp_req_timeout(struct tevent_context *ev,

-                             struct tevent_timer *te,

-                             struct timeval t, void *ptr)

- {

-     struct sss_dp_req *sdp_req = talloc_get_type(ptr, struct sss_dp_req);

  

-     sdp_req->err_maj = DP_ERR_FATAL;

-     sdp_req->err_min = ETIMEDOUT;

-     sdp_req->err_msg = discard_const_p(char, "Timed out");

- 

-     /* steal te on NULL because it will be freed as soon as the handler

-      * returns. Causing a double free if we don't, as te is allocated on

-      * sdp_req and we are just going to free it */

-     talloc_steal(NULL, te);

- 

-     talloc_free(sdp_req);

+     DEBUG(7, ("Will handle %lu requests after reconnect\n", count));

+     for (i=0; i<count; i++) {

+         sdp_req = talloc_get_type(values[i].ptr, struct sss_dp_req);

+         talloc_free(sdp_req);

+     }

  }

  

  static int sss_dp_get_reply(DBusPendingCall *pending,
@@ -155,8 +128,6 @@

  {

      struct sss_dp_req *sdp_req = talloc_get_type(ptr, struct sss_dp_req);

      struct sss_dp_callback *cb;

-     struct timeval tv;

-     struct tevent_timer *tev;

  

      cb = sdp_req->cb_list;

      /* Remove the callback from the list, the caller may free it, within the
@@ -169,36 +140,65 @@

                   sdp_req->err_msg,

                   cb->callback_ctx);

  

-     /* Call the next callback if needed */

+     /* If there are some more callbacks to be invoked,

+      * don't destroy the request */

      if (sdp_req->cb_list != NULL) {

-         tv = tevent_timeval_current();

-         tev = tevent_add_timer(sdp_req->ev, sdp_req, tv,

-                                sss_dp_invoke_callback, sdp_req);

-         if (!tev) {

-             /* Out of memory or other serious error */

-             goto done;

-         }

- 

          return;

      }

  

-     /* No more callbacks to invoke. Destroy the request */

- done:

-     /* steal te on NULL because it will be freed as soon as the handler

+     /* steal te on rctx because it will be freed as soon as the handler

       * returns. Causing a double free if we don't, as te is allocated on

       * sdp_req and we are just going to free it */

-     talloc_steal(NULL, te);

+     talloc_steal(sdp_req->rctx, te);

  

      talloc_zfree(sdp_req);

  }

  

+ static void sdp_req_timeout(struct tevent_context *ev,

+                             struct tevent_timer *te,

+                             struct timeval t, void *ptr)

+ {

+     struct sss_dp_req *sdp_req = talloc_get_type(ptr, struct sss_dp_req);

+     struct sss_dp_callback *cb, *next;

+     struct timeval tv;

+     struct tevent_timer *tev;

+     hash_key_t key;

+ 

+     sdp_req->err_maj = DP_ERR_FATAL;

+     sdp_req->err_min = ETIMEDOUT;

+     sdp_req->err_msg = discard_const_p(char, "Timed out");

+ 

+     /* Destroy the hash entry */

+     key.type = HASH_KEY_STRING;

+     key.str = sdp_req->key;

+     int hret = hash_delete(dp_requests, &key);

+     if (hret != HASH_SUCCESS) {

+         /* This should never happen */

+         DEBUG(0, ("Could not clear entry from request queue\n"));

+     }

+ 

+     /* Queue up all callbacks */

+     cb = sdp_req->cb_list;

+     tv = tevent_timeval_current();

+     while (cb) {

+         next = cb->next;

+         tev = tevent_add_timer(sdp_req->ev, sdp_req, tv,

+                                sss_dp_invoke_callback, sdp_req);

+         if (!tev) {

+             return;

+         }

+         cb = next;

+     }

+ }

+ 

  static void sss_dp_send_acct_callback(DBusPendingCall *pending, void *ptr)

  {

      int ret;

      struct sss_dp_req *sdp_req;

-     struct sss_dp_callback *cb;

+     struct sss_dp_callback *cb, *next;

      struct timeval tv;

      struct tevent_timer *te;

+     hash_key_t key;

  

      sdp_req = talloc_get_type(ptr, struct sss_dp_req);

  
@@ -225,28 +225,34 @@

      }

  

      /* Check whether we need to issue any callbacks */

-     cb = sdp_req->cb_list;

      if (sdp_req->cb_list == NULL) {

-         if (cb == NULL) {

-             /* No callbacks to invoke. Destroy the hash entry */

-             talloc_zfree(sdp_req);

-             return;

-         }

+         /* No callbacks to invoke. Destroy the hash entry */

+         talloc_zfree(sdp_req);

+         return;

+     }

+ 

+     /* Destroy the hash entry */

+     key.type = HASH_KEY_STRING;

+     key.str = sdp_req->key;

+     int hret = hash_delete(dp_requests, &key);

+     if (hret != HASH_SUCCESS) {

+         /* This should never happen */

+         DEBUG(0, ("Could not clear entry from request queue\n"));

      }

  

      /* Queue up all callbacks */

+     cb = sdp_req->cb_list;

      tv = tevent_timeval_current();

-     te = tevent_add_timer(sdp_req->ev, sdp_req, tv,

-                           sss_dp_invoke_callback, sdp_req);

-     if (!te) {

-         /* Out of memory or other serious error */

-         goto error;

+     while (cb) {

+         next = cb->next;

+         te = tevent_add_timer(sdp_req->ev, sdp_req, tv,

+                               sss_dp_invoke_callback, sdp_req);

+         if (!te) {

+             /* Out of memory or other serious error */

+             return;

+         }

+         cb = next;

      }

- 

-     return;

- 

- error:

-     talloc_zfree(sdp_req);

  }

  

  static int sss_dp_send_acct_req_create(struct resp_ctx *rctx,
@@ -482,6 +488,7 @@

          dbus_message_unref(msg);

          return ENOMEM;

      }

+     sdp_req->rctx = rctx;

  

      ret = sbus_conn_send(be_conn->conn, msg, timeout,

                           sss_dp_send_acct_callback,

@@ -217,6 +217,11 @@

      size_t len;

      void *buf;

  

+     if (!packet) {

+         /* No packet object to write to? */

+         return EINVAL;

+     }

+ 

      buf = packet->buffer + packet->iop;

      len = *packet->len - packet->iop;

  

file modified
+107 -1
@@ -47,6 +47,10 @@

  #define SSS_NSS_PIPE_NAME "nss"

  

  #define DEFAULT_PWFIELD "*"

+ #define DEFAULT_NSS_FD_LIMIT 8192

+ 

+ #define SHELL_REALLOC_INCREMENT 5

+ #define SHELL_REALLOC_MAX       50

  

  struct sbus_method monitor_nss_methods[] = {

      { MON_CLI_METHOD_PING, monitor_common_pong },
@@ -63,6 +67,71 @@

      NULL

  };

  

+ 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(6, ("Found shell %s in /etc/shells\n", shells[i]));

+         i++;

+ 

+         if (i == size) {

+             size += SHELL_REALLOC_INCREMENT;

+             if (size > SHELL_REALLOC_MAX) {

+                 DEBUG(0, ("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 resp_ctx *rctx,

                            struct confdb_ctx *cdb)
@@ -94,7 +163,7 @@

      if (ret != EOK) goto done;

      if (nctx->cache_refresh_percent < 0 ||

          nctx->cache_refresh_percent > 99) {

-         DEBUG(0,("Configuration error: entry_cache_nowait_percentage is"

+         DEBUG(0,("Configuration error: entry_cache_nowait_percentage is "

                   "invalid. Disabling feature.\n"));

          nctx->cache_refresh_percent = 0;

      }
@@ -110,6 +179,29 @@

                              &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_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 = 0;

  done:

      talloc_free(tmpctx);
@@ -167,6 +259,7 @@

      struct nss_ctx *nctx;

      int ret, max_retries;

      int hret;

+     int fd_limit;

  

      nctx = talloc_zero(mem_ctx, struct nss_ctx);

      if (!nctx) {
@@ -224,6 +317,19 @@

          return EIO;

      }

  

+     /* Set up file descriptor limits */

+     ret = confdb_get_int(nctx->rctx->cdb, nctx->rctx,

+                          CONFDB_NSS_CONF_ENTRY,

+                          CONFDB_SERVICE_FD_LIMIT,

+                          DEFAULT_NSS_FD_LIMIT,

+                          &fd_limit);

+     if (ret != EOK) {

+         DEBUG(0,

+               ("Failed to set up file descriptor limit\n"));

+         return ret;

+     }

+     responder_set_fd_limit(fd_limit);

+ 

      DEBUG(1, ("NSS Initialization complete\n"));

  

      return EOK;

@@ -57,6 +57,12 @@

      bool filter_users_in_groups;

  

      char *pwfield;

+ 

+     char *override_homedir;

+     char **allowed_shells;

+     char **vetoed_shells;

+     char **etc_shells;

+     char *shell_fallback;

  };

  

  struct nss_packet;

file modified
+269 -32
@@ -169,6 +169,192 @@

  /****************************************************************************

   * PASSWD db related functions

   ***************************************************************************/

+ char *expand_homedir_template(TALLOC_CTX *mem_ctx, const char *template,

+                               const char *username, uint32_t uid,

+                               const char *domain)

+ {

+     char *copy;

+     char *p;

+     char *n;

+     char *result = NULL;

+     char *res = NULL;

+     TALLOC_CTX *tmp_ctx = NULL;

+ 

+     if (template == NULL) {

+         DEBUG(1, ("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(1, ("talloc_strdup failed.\n"));

+         goto done;

+     }

+ 

+     result = talloc_strdup(tmp_ctx, "");

+     if (result == NULL) {

+         DEBUG(1, ("talloc_strdup failed.\n"));

+         goto done;

+     }

+ 

+     p = copy;

+     while ( (n = strchr(p, '%')) != NULL) {

+         *n = '\0';

+         n++;

+         if ( *n == '\0' ) {

+             DEBUG(1, ("format error, single %% at the end of the template.\n"));

+             goto done;

+         }

+         switch( *n ) {

+             case 'u':

+                 if (username == NULL) {

+                     DEBUG(1, ("Cannot expand user name template "

+                               "because user name is empty.\n"));

+                     goto done;

+                 }

+                 result = talloc_asprintf_append(result, "%s%s", p,

+                                                 username);

+                 break;

+ 

+             case 'U':

+                 if (uid == 0) {

+                     DEBUG(1, ("Cannot expand uid template "

+                               "because uid is invalid.\n"));

+                     goto done;

+                 }

+                 result = talloc_asprintf_append(result, "%s%d", p,

+                                                 uid);

+                 break;

+ 

+             case 'd':

+                 if (domain == NULL) {

+                     DEBUG(1, ("Cannot expand domain name template "

+                               "because domain name is empty.\n"));

+                     goto done;

+                 }

+                 result = talloc_asprintf_append(result, "%s%s", p,

+                                                 domain);

+                 break;

+ 

+             case 'f':

+                 if (domain == NULL || username == NULL) {

+                     DEBUG(1, ("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,

+                                                 username, domain);

+                 break;

+ 

+             case '%':

+                 result = talloc_asprintf_append(result, "%s%%", p);

+                 break;

+ 

+             default:

+                 DEBUG(1, ("format error, unknown template [%%%c].\n", *n));

+                 goto done;

+         }

+ 

+         if (result == NULL) {

+             DEBUG(1, ("talloc_asprintf_append failed.\n"));

+             goto done;

+         }

+ 

+         p = n + 1;

+     }

+ 

+     result = talloc_asprintf_append(result, "%s", p);

+     if (result == NULL) {

+         DEBUG(1, ("talloc_asprintf_append failed.\n"));

+         goto done;

+     }

+ 

+     res = talloc_move(mem_ctx, &result);

+ done:

+     talloc_zfree(tmp_ctx);

+     return 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,

+                                         const char *name,

+                                         uint32_t uid)

+ {

+     if (dom->override_homedir) {

+         return expand_homedir_template(mem_ctx, dom->override_homedir,

+                                        name, uid, dom->name);

+     } else if (nctx->override_homedir) {

+         return expand_homedir_template(mem_ctx, nctx->override_homedir,

+                                        name, uid, dom->name);

+     }

+ 

+     return talloc_strdup(mem_ctx,

+             ldb_msg_find_attr_as_string(msg, SYSDB_HOMEDIR, NULL));

+ }

+ 

+ static const char *get_shell_override(TALLOC_CTX *mem_ctx,

+                                       struct ldb_message *msg,

+                                       struct nss_ctx *nctx)

+ {

+     const char *user_shell;

+     int i;

+ 

+     user_shell = ldb_msg_find_attr_as_string(msg, SYSDB_SHELL, NULL);

+     if (!user_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(5, ("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(9, ("Shell %s found in /etc/shells\n",

+                         nctx->etc_shells[i]));

+                 break;

+             }

+         }

+ 

+         if (nctx->etc_shells[i]) {

+             DEBUG(9, ("Using original shell '%s'\n", user_shell));

+             return talloc_strdup(mem_ctx, user_shell);

+         }

+     }

+ 

+     if (nctx->allowed_shells) {

+         for (i=0; nctx->allowed_shells[i]; i++) {

+             if (strcmp(nctx->allowed_shells[i], user_shell) == 0) {

+                 DEBUG(5, ("The shell '%s' is allowed but does not exist. "

+                         "Using fallback\n", user_shell));

+                 return talloc_strdup(mem_ctx, nctx->shell_fallback);

+             }

+         }

+     }

+ 

+     DEBUG(5, ("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,
@@ -195,6 +381,7 @@

      const char *namefmt = nctx->rctx->names->fq_fmt;

      bool packet_initialized = false;

      int ncret;

+     TALLOC_CTX *tmp_ctx = NULL;

  

      if (add_domain) dom_len = strlen(domain);

  
@@ -202,11 +389,14 @@

  

      num = 0;

      for (i = 0; i < *count; i++) {

+         talloc_zfree(tmp_ctx);

+         tmp_ctx = talloc_new(NULL);

+ 

          msg = msgs[i];

  

          name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);

          uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0);

-         gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0);

+         gid = get_gid_override(msg, dom);

  

          if (!name || !uid || !gid) {

              DEBUG(2, ("Incomplete or fake user object for %s[%llu]! Skipping\n",
@@ -233,8 +423,8 @@

          }

  

          gecos = ldb_msg_find_attr_as_string(msg, SYSDB_GECOS, NULL);

-         homedir = ldb_msg_find_attr_as_string(msg, SYSDB_HOMEDIR, NULL);

-         shell = ldb_msg_find_attr_as_string(msg, SYSDB_SHELL, NULL);

+         homedir = get_homedir_override(tmp_ctx, msg, nctx, dom, name, uid);

+         shell = get_shell_override(tmp_ctx, msg, nctx);

  

          if (!gecos) gecos = "";

          if (!homedir) homedir = "/";
@@ -298,6 +488,7 @@

  

          num++;

      }

+     talloc_zfree(tmp_ctx);

  

  done:

      *count = i;
@@ -532,12 +723,17 @@

  

          /* if neg cached, return we didn't find it */

          if (ret == EEXIST) {

-             DEBUG(2, ("User [%s] does not exist! (negative cache)\n", name));

+             DEBUG(2, ("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 = dom->next;

                  continue;

              }

+             /* There are no further domains or this was a

+              * fully-qualified user request.

+              */

+             return ENOENT;

          }

  

          DEBUG(4, ("Requesting info for [%s@%s]\n", name, dom->name));
@@ -560,20 +756,20 @@

          }

  

          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, name);

+             if (ret != EOK) {

+                 return ret;

+             }

+ 

              /* if a multidomain search, try with next */

              if (cmdctx->check_next) {

                  dom = dom->next;

-                 continue;

+                 if (dom) continue;

              }

  

              DEBUG(2, ("No results for getpwnam call\n"));

  

-             /* set negative cache only if not result of cache check */

-             ret = sss_ncache_set_user(nctx->ncache, false, dom->name, name);

-             if (ret != EOK) {

-                 return ret;

-             }

- 

              return ENOENT;

          }

  
@@ -677,6 +873,13 @@

          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;

  

      domname = NULL;
@@ -1794,12 +1997,17 @@

  

          /* if neg cached, return we didn't find it */

          if (ret == EEXIST) {

-             DEBUG(2, ("Group [%s] does not exist! (negative cache)\n", name));

+             DEBUG(2, ("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 = dom->next;

                  continue;

              }

+             /* There are no further domains or this was a

+              * fully-qualified user request.

+              */

+             return ENOENT;

          }

  

          DEBUG(4, ("Requesting info for [%s@%s]\n", name, dom->name));
@@ -1822,20 +2030,20 @@

          }

  

          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, name);

+             if (ret != EOK) {

+                 return ret;

+             }

+ 

              /* if a multidomain search, try with next */

              if (cmdctx->check_next) {

                  dom = dom->next;

-                 continue;

+                 if (dom) continue;

              }

  

              DEBUG(2, ("No results for getgrnam call\n"));

  

-             /* set negative cache only if not result of cache check */

-             ret = sss_ncache_set_group(nctx->ncache, false, dom->name, name);

-             if (ret != EOK) {

-                 return ret;

-             }

- 

              return ENOENT;

          }

  
@@ -1939,6 +2147,13 @@

          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;

  

      domname = NULL;
@@ -2734,7 +2949,9 @@

      uint8_t *body;

      size_t blen;

      gid_t gid;

-     int ret, i, num;

+     int ret, i, num, bindex;

+     int skipped = 0;

+     const char *posix;

  

      if (res->count == 0) {

          return ENOENT;
@@ -2750,16 +2967,24 @@

      sss_packet_get_body(packet, &body, &blen);

  

      /* skip first entry, it's the user entry */

+     bindex = 0;

      for (i = 0; i < num; i++) {

          gid = ldb_msg_find_attr_as_uint64(res->msgs[i + 1], SYSDB_GIDNUM, 0);

+         posix = ldb_msg_find_attr_as_string(res->msgs[i + 1], SYSDB_POSIX, NULL);

          if (!gid) {

-             DEBUG(1, ("Incomplete group object for initgroups! Aborting\n"));

-             return EFAULT;

+             if (posix && strcmp(posix, "FALSE") == 0) {

+                 skipped++;

+                 continue;

+             } else {

+                 DEBUG(1, ("Incomplete group object for initgroups! Aborting\n"));

+                 return EFAULT;

+             }

          }

-         ((uint32_t *)body)[2 + i] = gid;

+         ((uint32_t *)body)[2 + bindex] = gid;

+         bindex++;

      }

  

-     ((uint32_t *)body)[0] = num; /* num results */

+     ((uint32_t *)body)[0] = num-skipped; /* num results */

      ((uint32_t *)body)[1] = 0; /* reserved */

  

      return EOK;
@@ -2827,12 +3052,17 @@

  

          /* if neg cached, return we didn't find it */

          if (ret == EEXIST) {

-             DEBUG(2, ("User [%s] does not exist! (negative cache)\n", name));

+             DEBUG(2, ("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 = dom->next;

                  continue;

              }

+             /* There are no further domains or this was a

+              * fully-qualified user request.

+              */

+             return ENOENT;

          }

  

          DEBUG(4, ("Requesting info for [%s@%s]\n", name, dom->name));
@@ -2851,20 +3081,20 @@

          }

  

          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, name);

+             if (ret != EOK) {

+                 return ret;

+             }

+ 

              /* if a multidomain search, try with next */

              if (cmdctx->check_next) {

                  dom = dom->next;

-                 continue;

+                 if (dom) continue;

              }

  

              DEBUG(2, ("No results for initgroups call\n"));

  

-             /* set negative cache only if not result of cache check */

-             ret = sss_ncache_set_user(nctx->ncache, false, dom->name, name);

-             if (ret != EOK) {

-                 return ret;

-             }

- 

              return ENOENT;

          }

  
@@ -2964,6 +3194,13 @@

          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;

  

      domname = NULL;

@@ -57,16 +57,19 @@

  

  static int netgr_hash_remove (TALLOC_CTX *ctx);

  static errno_t set_netgroup_entry(struct nss_ctx *nctx,

-                                   char *name,

                                    struct getent_ctx *netgr)

  {

      hash_key_t key;

      hash_value_t value;

      int hret;

  

+     if (netgr->name == NULL) {

+         DEBUG(1, ("Missing netgroup name.\n"));

+         return EINVAL;

+     }

      /* Add this entry to the hash table */

      key.type = HASH_KEY_STRING;

-     key.str = name;

+     key.str = netgr->name;

      value.type = HASH_VALUE_PTR;

      value.ptr = netgr;

      hret = hash_enter(nctx->netgroups, &key, &value);
@@ -110,6 +113,13 @@

          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);
@@ -270,7 +280,7 @@

              goto error;

          }

  

-         ret = set_netgroup_entry(nctx, client->netgr_name, state->netgr);

+         ret = set_netgroup_entry(nctx, state->netgr);

          if (ret != EOK) {

              DEBUG(1, ("set_netgroup_entry failed.\n"));

              talloc_free(state->netgr);
@@ -454,6 +464,8 @@

  

          if (ret != EOK) {

              DEBUG(1, ("Failed to convert results into entries\n"));

+             netgr->ready = true;

+             set_netgr_lifetime(step_ctx->nctx->neg_timeout, step_ctx, netgr);

              return EIO;

          }

  
@@ -494,8 +506,14 @@

          netgr->ready = true;

          netgr->entries = NULL;

          netgr->lookup_table = step_ctx->nctx->netgroups;

+         netgr->name = talloc_strdup(netgr, step_ctx->name);

+         if (netgr->name == NULL) {

+             DEBUG(1, ("talloc_strdup failed.\n"));

+             talloc_free(netgr);

+             return ENOMEM;

+         }

  

-         ret = set_netgroup_entry(step_ctx->nctx, step_ctx->name, netgr);

+         ret = set_netgroup_entry(step_ctx->nctx, netgr);

          if (ret != EOK) {

              DEBUG(1, ("set_netgroup_entry failed, ignored.\n"));

          }

@@ -265,11 +265,12 @@

  

      if (res->count < 1) {

          DEBUG(4, ("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(4, ("More than one object found with filter ["SYSDB_PWNAM_FILTER"]\n"));

+         DEBUG(4, ("More than one object found with filter ["SYSDB_PWNAM_FILTER"]\n",

+                   pd->user, pd->user));

          lreq->error = EFAULT;

          goto done;

      }

@@ -44,6 +44,8 @@

  #include "responder/pam/pamsrv.h"

  #include "responder/common/negcache.h"

  

+ #define DEFAULT_PAM_FD_LIMIT 8192

+ 

  #define SSS_PAM_SBUS_SERVICE_VERSION 0x0001

  #define SSS_PAM_SBUS_SERVICE_NAME "pam"

  
@@ -109,6 +111,7 @@

      struct pam_ctx *pctx;

      int ret, max_retries;

      int id_timeout;

+     int fd_limit;

  

      pctx = talloc_zero(mem_ctx, struct pam_ctx);

      if (!pctx) {
@@ -174,6 +177,19 @@

          goto done;

      }

  

+     /* Set up file descriptor limits */

+     ret = confdb_get_int(pctx->rctx->cdb, pctx->rctx,

+                          CONFDB_PAM_CONF_ENTRY,

+                          CONFDB_SERVICE_FD_LIMIT,

+                          DEFAULT_PAM_FD_LIMIT,

+                          &fd_limit);

+     if (ret != EOK) {

+         DEBUG(0,

+               ("Failed to set up file descriptor limit\n"));

+         return ret;

+     }

+     responder_set_fd_limit(fd_limit);

+ 

      ret = EOK;

  

  done:

@@ -38,6 +38,10 @@

      time_t id_timeout;

  };

  

+ struct pam_auth_dp_req {

+     struct pam_auth_req *preq;

+ };

+ 

  struct pam_auth_req {

      struct cli_ctx *cctx;

      struct sss_domain_info *domain;
@@ -49,6 +53,8 @@

      struct ldb_result *res;

      bool check_provider;

      void *data;

+ 

+     struct pam_auth_dp_req *dpreq_spy;

  };

  

  struct sss_cmd_table *get_pam_cmds(void);

@@ -70,6 +70,11 @@

  

      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;
@@ -500,8 +505,12 @@

              DEBUG(5, ("Password change not possible while offline.\n"));

              pd->pam_status = PAM_AUTHTOK_ERR;

              user_info_type = SSS_PAM_USER_INFO_OFFLINE_CHPASS;

-             pam_add_response(pd, SSS_PAM_USER_INFO, sizeof(uint32_t),

-                              (const uint8_t *) &user_info_type);

+             ret = pam_add_response(pd, SSS_PAM_USER_INFO, sizeof(uint32_t),

+                                    (const uint8_t *) &user_info_type);

+             if (ret != EOK) {

+                 DEBUG(1, ("pam_add_response failed.\n"));

+                 goto done;

+             }

              break;

  /* TODO: we need the pam session cookie here to make sure that cached

   * authentication was successful */
@@ -565,8 +574,12 @@

      }

  

      if (pd->domain != NULL) {

-         pam_add_response(pd, SSS_PAM_DOMAIN_NAME, strlen(pd->domain)+1,

-                          (uint8_t *) pd->domain);

+         ret = pam_add_response(pd, SSS_PAM_DOMAIN_NAME, strlen(pd->domain)+1,

+                                (uint8_t *) pd->domain);

+         if (ret != EOK) {

+             DEBUG(1, ("pam_add_response failed.\n"));

+             goto done;

+         }

      }

  

      resp_c = 0;
@@ -684,6 +697,17 @@

  static int pam_check_user_done(struct pam_auth_req *preq, int ret);

  static void pam_dom_forwarder(struct pam_auth_req *preq);

  

+ 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;

+ }

+ 

  /* 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. */
@@ -704,6 +728,7 @@

      if (!preq) {

          return ENOMEM;

      }

+     talloc_set_destructor(preq, pam_auth_req_destructor);

      preq->cctx = cctx;

  

      preq->pd = talloc_zero(preq, struct pam_data);
@@ -952,10 +977,12 @@

                    (unsigned int)err_maj, (unsigned int)err_min, err_msg));

      }

  

-     /* Make sure we don't go to the ID provider too often */

-     preq->cctx->pam_timeout = time(NULL) + pctx->id_timeout;

- 

      ret = pam_check_user_search(preq);

+     if (ret == EOK || ret == ENOENT) {

+         /* Make sure we don't go to the ID provider too often */

+         preq->cctx->pam_timeout = time(NULL) + pctx->id_timeout;

+     }

+ 

      if (ret == EOK) {

          pam_dom_forwarder(preq);

      }

file modified
+36 -5
@@ -37,13 +37,26 @@

      DBusMessage* msg;

      int ret;

      int type;

-     struct pam_auth_req *preq;

+     struct pam_auth_req *preq = NULL;

+     struct pam_auth_dp_req *pdp_req;

  

-     preq = talloc_get_type(ptr, struct pam_auth_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(4, ("Client already disconnected\n"));

+         dbus_pending_call_unref(pending);

+         dbus_message_unref(msg);

+         return;

+     }

+ 

+     /* Sanity-check of message validity */

      if (msg == NULL) {

          DEBUG(0, ("Severe error. A reply callback was called but no reply was"

                    "received and no timeout occurred\n"));
@@ -51,7 +64,6 @@

          goto done;

      }

  

- 

      type = dbus_message_get_type(msg);

      switch (type) {

          case DBUS_MESSAGE_TYPE_METHOD_RETURN:
@@ -79,6 +91,16 @@

      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;
@@ -86,6 +108,7 @@

      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
@@ -118,9 +141,17 @@

          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,

-                          preq, NULL);

+                          pdp_req, NULL);

      dbus_message_unref(msg);

      return res;

  }

file modified
+1 -1
@@ -46,7 +46,7 @@

          return EIO;

      }

  

-     ret = check_file(filename, 0, 0, 0600, CHECK_SOCK, NULL);

+     ret = check_file(filename, 0, 0, 0600, CHECK_SOCK, NULL, true);

      if (ret != EOK) {

          DEBUG(1, ("check_file failed for [%s].\n", filename));

          return EIO;

file modified
+1
@@ -79,6 +79,7 @@

                      struct tevent_context *ev,

                      const char *address,

                      struct sbus_interface *intf,

+                     bool use_symlink,

                      struct sbus_connection **server,

                      sbus_server_conn_init_fn init_fn, void *init_pvt_data);

  

@@ -58,6 +58,7 @@

      void *reconnect_pvt;

  

      /* server related stuff */

+     char *symlink;

      struct sbus_interface *server_intf;

      sbus_server_conn_init_fn srv_init_fn;

      void *srv_init_data;

file modified
+171 -17
@@ -81,6 +81,99 @@

      }

  }

  

+ 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(7, ("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(1, ("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(1, ("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(2, ("readlink failed [%d]: %s\n", ret, strerror(ret)));

+         return ret;

+     }

+     target[numread] = '\0';

+     DEBUG(9, ("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(2, ("snprintf failed"));

+         return EIO;

+     } else if (ret >= PATH_MAX) {

+         DEBUG(2, ("path too long?!?!\n"));

+         return EIO;

+     }

+     DEBUG(9, ("The path including our pid is [%s]\n", pidpath));

+ 

+     if (strcmp(pidpath, target) != 0) {

+         DEBUG(4, ("Will not remove symlink, seems to be owned by "

+                   "another process\n"));

+         return EOK;

+     }

+ 

+     ret = unlink(symlink_name);

+     if (ret != 0) {

+         ret = errno;

+         DEBUG(2, ("unlink failed to remove [%s] [%d]: %s\n",

+                    symlink, ret, strerror(ret)));

+         return ret;

+     }

+ 

+     DEBUG(9, ("Removed the symlink\n"));

+     return EOK;

+ }

+ 

  /*

   * dbus_new_server

   * Set up a D-BUS server, integrate with the event loop
@@ -90,8 +183,10 @@

                      struct tevent_context *ev,

                      const char *address,

                      struct sbus_interface *intf,

+                     bool use_symlink,

                      struct sbus_connection **_server,

-                     sbus_server_conn_init_fn init_fn, void *init_pvt_data)

+                     sbus_server_conn_init_fn init_fn,

+                     void *init_pvt_data)

  {

      struct sbus_connection *server;

      DBusServer *dbus_server;
@@ -100,30 +195,64 @@

      char *tmp;

      int 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(address, &dbus_error);

+     dbus_server = dbus_server_listen(socket_address, &dbus_error);

      if (!dbus_server) {

          DEBUG(1,("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);

-         return EIO;

+         ret = EIO;

+         goto done;

      }

  

-     filename = strchr(address, '/');

+     filename = strchr(socket_address, '/');

      if (filename == NULL) {

-         DEBUG(1, ("Unexpected dbus address [%s].\n", address));

-         return EIO;

+         DEBUG(1, ("Unexpected dbus address [%s].\n", socket_address));

+         ret = EIO;

+         goto done;

+     }

+ 

+     if (use_symlink) {

+         symlink_filename = strchr(address, '/');

+         if (symlink_filename == NULL) {

+             DEBUG(1, ("Unexpected dbus address [%s].\n", address));

+             ret = EIO;

+             goto done;

+         }

+ 

+         ret = create_socket_symlink(filename, symlink_filename);

+         if (ret != EOK) {

+             DEBUG(1, ("Could not create symlink [%d]: %s\n",

+                       ret, strerror(ret)));

+             ret = EIO;

+             goto done;

+         }

      }

  

-     ret = check_file(filename, 0, 0, -1, CHECK_SOCK, &stat_buf);

+     /* Both check_file and chmod can handle both the symlink and

+      * the socket */

+     ret = check_file(filename, 0, 0, -1, CHECK_SOCK, &stat_buf, true);

      if (ret != EOK) {

          DEBUG(1, ("check_file failed for [%s].\n", filename));

-         return EIO;

+         ret = EIO;

+         goto done;

      }

  

      if ((stat_buf.st_mode & ~S_IFMT) != 0600) {
@@ -131,7 +260,8 @@

          if (ret != EOK) {

              DEBUG(1, ("chmod failed for [%s]: [%d][%s].\n", filename, errno,

                                                           strerror(errno)));

-             return EIO;

+             ret = EIO;

+             goto done;

          }

      }

  
@@ -139,9 +269,10 @@

      DEBUG(3, ("D-BUS Server listening on %s\n", tmp));

      free(tmp);

  

-     server = talloc_zero(mem_ctx, struct sbus_connection);

+     server = talloc_zero(tmp_ctx, struct sbus_connection);

      if (!server) {

-         return ENOMEM;

+         ret = ENOMEM;

+         goto done;

      }

  

      server->ev = ev;
@@ -153,6 +284,14 @@

  

      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,
@@ -166,8 +305,8 @@

                                              server, NULL);

      if (!dbret) {

          DEBUG(4, ("Error setting up D-BUS server watch functions\n"));

-         talloc_free(server);

-         return EIO;

+         ret = EIO;

+         goto done;

      }

  

      /* Set up DBusTimeout functions */
@@ -180,19 +319,34 @@

          DEBUG(4,("Error setting up D-BUS server timeout functions\n"));

          dbus_server_set_watch_functions(server->dbus.server,

                                          NULL, NULL, NULL, NULL, NULL);

-         talloc_free(server);

-         return EIO;

+         ret = EIO;

+         goto done;

      }

  

-     *_server = server;

-     return EOK;

+     *_server = talloc_steal(mem_ctx, server);

+     ret = EOK;

+ done:

+     if (ret != EOK && symlink_filename) {

+         unlink(symlink_filename);

+     }

+     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(3, ("Could not remove the server symlink\n"));

+         }

+     }

+ 

      return 0;

  }

file modified
+134 -76
@@ -35,6 +35,7 @@

  #include <sys/stat.h>

  #include <unistd.h>

  #include <stdlib.h>

+ #include <stdbool.h>

  #include <stdint.h>

  #include <string.h>

  #include <fcntl.h>
@@ -49,10 +50,27 @@

  #include <pthread.h>

  #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) {
@@ -69,7 +87,7 @@

   * byte 12-15: 32bit unsigned (reserved)

   * byte 16-X: (optional) request structure associated to the command code used

   */

- static enum nss_status sss_nss_send_req(enum sss_cli_command cmd,

+ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd,

                                          struct sss_cli_req_data *rd,

                                          int *errnop)

  {
@@ -124,19 +142,21 @@

          }

          if (*errnop) {

              sss_cli_close_socket();

-             return NSS_STATUS_UNAVAIL;

+             return SSS_STATUS_UNAVAIL;

          }

  

          errno = 0;

          if (datasent < SSS_NSS_HEADER_SIZE) {

-             res = write(sss_cli_sd,

-                         (char *)header + datasent,

-                         SSS_NSS_HEADER_SIZE - datasent);

+             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 = write(sss_cli_sd,

-                         (const char *)rd->data + rdsent,

-                         rd->len - rdsent);

+             res = send(sss_cli_sd,

+                        (const char *)rd->data + rdsent,

+                        rd->len - rdsent,

+                        SSS_DEFAULT_WRITE_FLAGS);

          }

          error = errno;

  
@@ -150,14 +170,14 @@

  

              /* Write failed */

              sss_cli_close_socket();

-             *errnop = errno;

-             return NSS_STATUS_UNAVAIL;

+             *errnop = error;

+             return SSS_STATUS_UNAVAIL;

          }

  

          datasent += res;

      }

  

-     return NSS_STATUS_SUCCESS;

+     return SSS_STATUS_SUCCESS;

  }

  

  /* Replies:
@@ -169,7 +189,7 @@

   * byte 16-X: (optional) reply structure associated to the command code used

   */

  

- static enum nss_status sss_nss_recv_rep(enum sss_cli_command cmd,

+ static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd,

                                          uint8_t **_buf, int *_len,

                                          int *errnop)

  {
@@ -229,7 +249,7 @@

          }

          if (*errnop) {

              sss_cli_close_socket();

-             ret = NSS_STATUS_UNAVAIL;

+             ret = SSS_STATUS_UNAVAIL;

              goto failed;

          }

  
@@ -260,8 +280,8 @@

               * through. */

  

              sss_cli_close_socket();

-             *errnop = errno;

-             ret = NSS_STATUS_UNAVAIL;

+             *errnop = error;

+             ret = SSS_STATUS_UNAVAIL;

              goto failed;

          }

  
@@ -276,10 +296,10 @@

                  sss_cli_close_socket();

                  *errnop = header[2];

                  if (*errnop == EAGAIN) {

-                     ret = NSS_STATUS_TRYAGAIN;

+                     ret = SSS_STATUS_TRYAGAIN;

                      goto failed;

                  } else {

-                     ret = NSS_STATUS_UNAVAIL;

+                     ret = SSS_STATUS_UNAVAIL;

                      goto failed;

                  }

              }
@@ -287,7 +307,7 @@

                  /* wrong command id */

                  sss_cli_close_socket();

                  *errnop = EBADMSG;

-                 ret = NSS_STATUS_UNAVAIL;

+                 ret = SSS_STATUS_UNAVAIL;

                  goto failed;

              }

              if (header[0] > SSS_NSS_HEADER_SIZE) {
@@ -296,7 +316,7 @@

                  if (!buf) {

                      sss_cli_close_socket();

                      *errnop = ENOMEM;

-                     ret = NSS_STATUS_UNAVAIL;

+                     ret = SSS_STATUS_UNAVAIL;

                      goto failed;

                  }

              }
@@ -306,7 +326,7 @@

      *_len = len;

      *_buf = buf;

  

-     return NSS_STATUS_SUCCESS;

+     return SSS_STATUS_SUCCESS;

  

  failed:

      free(buf);
@@ -315,25 +335,25 @@

  

  /* 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 nss_status sss_nss_make_request_nochecks(

+ 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 nss_status ret;

+     enum sss_status ret;

      uint8_t *buf = NULL;

      int len = 0;

  

      /* send data */

-     ret = sss_nss_send_req(cmd, rd, errnop);

-     if (ret != NSS_STATUS_SUCCESS) {

+     ret = sss_cli_send_req(cmd, rd, errnop);

+     if (ret != SSS_STATUS_SUCCESS) {

          return ret;

      }

  

      /* data sent, now get reply */

-     ret = sss_nss_recv_rep(cmd, &buf, &len, errnop);

-     if (ret != NSS_STATUS_SUCCESS) {

+     ret = sss_cli_recv_rep(cmd, &buf, &len, errnop);

+     if (ret != SSS_STATUS_SUCCESS) {

          return ret;

      }

  
@@ -351,21 +371,21 @@

          }

      }

  

-     return NSS_STATUS_SUCCESS;

+     return SSS_STATUS_SUCCESS;

  }

  

  /* GET_VERSION Reply:

   * 0-3: 32bit unsigned version number

   */

  

- static int sss_nss_check_version(const char *socket_name)

+ static bool sss_cli_check_version(const char *socket_name)

  {

      uint8_t *repbuf;

      size_t replen;

-     enum nss_status nret;

+     enum sss_status nret;

      int errnop;

-     int res = NSS_STATUS_UNAVAIL;

      uint32_t expected_version;

+     uint32_t obtained_version;

      struct sss_cli_req_data req;

  

      if (strcmp(socket_name, SSS_NSS_SOCKET_NAME) == 0) {
@@ -374,28 +394,26 @@

                 strcmp(socket_name, SSS_PAM_PRIV_SOCKET_NAME) == 0) {

          expected_version = SSS_PAM_PROTOCOL_VERSION;

      } else {

-         return NSS_STATUS_UNAVAIL;

+         return false;

      }

  

      req.len = sizeof(expected_version);

      req.data = &expected_version;

  

-     nret = sss_nss_make_request_nochecks(SSS_GET_VERSION, &req,

+     nret = sss_cli_make_request_nochecks(SSS_GET_VERSION, &req,

                                           &repbuf, &replen, &errnop);

-     if (nret != NSS_STATUS_SUCCESS) {

-         return nret;

+     if (nret != SSS_STATUS_SUCCESS) {

+         return false;

      }

  

      if (!repbuf) {

-         return res;

-     }

- 

-     if (((uint32_t *)repbuf)[0] == expected_version) {

-         res = NSS_STATUS_SUCCESS;

+         return false;

      }

  

+     obtained_version = ((uint32_t *)repbuf)[0];

      free(repbuf);

-     return res;

+ 

+     return (obtained_version == expected_version);

  }

  

  /* this 2 functions are adapted from samba3 winbinbd's wb_common.c */
@@ -492,11 +510,15 @@

      return new_fd;

  }

  

- static int sss_nss_open_socket(int *errnop, const char *socket_name)

+ static int sss_cli_open_socket(int *errnop, const char *socket_name)

  {

      struct sockaddr_un nssaddr;

-     int inprogress = 1;

-     int wait_time, sleep_time;

+     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));
@@ -521,39 +543,37 @@

      /* this piece is adapted from winbind client code */

      wait_time = 0;

      sleep_time = 0;

-     while(inprogress) {

+     while (inprogress) {

          int connect_errno = 0;

          socklen_t errnosize;

-         struct timeval tv;

-         fd_set w_fds;

-         int ret;

+         struct pollfd pfd;

  

          wait_time += sleep_time;

  

          ret = connect(sd, (struct sockaddr *)&nssaddr,

                        sizeof(nssaddr));

          if (ret == 0) {

-             return sd;

+             connected = true;

+             break;

          }

  

          switch(errno) {

          case EINPROGRESS:

-             FD_ZERO(&w_fds);

-             FD_SET(sd, &w_fds);

-             tv.tv_sec = SSS_CLI_SOCKET_TIMEOUT - wait_time;

-             tv.tv_usec = 0;

+             pfd.fd = sd;

+             pfd.events = POLLOUT;

  

-             ret = select(sd + 1, NULL, &w_fds, NULL, &tv);

+             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) {

-                     return sd;

+                     connected = true;

+                     break;

                  }

              }

-             wait_time += SSS_CLI_SOCKET_TIMEOUT;

+             wait_time = time(NULL) - start_time;

              break;

          case EAGAIN:

              if (wait_time < SSS_CLI_SOCKET_TIMEOUT) {
@@ -563,28 +583,50 @@

              break;

          default:

              *errnop = errno;

-             inprogress = 0;

+             inprogress = false;

              break;

          }

  

          if (wait_time >= SSS_CLI_SOCKET_TIMEOUT) {

-             inprogress = 0;

+             inprogress = false;

+         }

+ 

+         if (connected) {

+             inprogress = false;

          }

      }

  

-     /* if we get here connect() failed or we timed out */

+     if (!connected) {

+         close(sd);

+         return -1;

+     }

+ 

+     ret = fstat(sd, &sss_cli_sb);

+     if (ret != 0) {

+         close(sd);

+         return -1;

+     }

  

-     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) {

-         sss_cli_close_socket();

+         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();

      }

  
@@ -634,14 +676,14 @@

          sss_cli_close_socket();

      }

  

-     mysd = sss_nss_open_socket(errnop, socket_name);

+     mysd = sss_cli_open_socket(errnop, socket_name);

      if (mysd == -1) {

          return SSS_STATUS_UNAVAIL;

      }

  

      sss_cli_sd = mysd;

  

-     if (sss_nss_check_version(socket_name) == NSS_STATUS_SUCCESS) {

+     if (sss_cli_check_version(socket_name)) {

          return SSS_STATUS_SUCCESS;

      }

  
@@ -671,7 +713,16 @@

          return NSS_STATUS_UNAVAIL;

      }

  

-     return sss_nss_make_request_nochecks(cmd, rd, repbuf, replen, errnop);

+     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)
@@ -702,7 +753,9 @@

                        uint8_t **repbuf, size_t *replen,

                        int *errnop)

  {

-     int ret;

+     int ret, statret;

+     errno_t error;

+     enum sss_status status;

      char *envval;

      struct stat stat_buf;

  
@@ -717,8 +770,8 @@

  

      /* only root shall use the privileged pipe */

      if (getuid() == 0 && getgid() == 0) {

-         ret = stat(SSS_PAM_PRIV_SOCKET_NAME, &stat_buf);

-         if (ret != 0) {

+         statret = stat(SSS_PAM_PRIV_SOCKET_NAME, &stat_buf);

+         if (statret != 0) {

              ret = PAM_SERVICE_ERR;

              goto out;

          }
@@ -731,10 +784,10 @@

              goto out;

          }

  

-         ret = sss_cli_check_socket(errnop, SSS_PAM_PRIV_SOCKET_NAME);

+         status = sss_cli_check_socket(errnop, SSS_PAM_PRIV_SOCKET_NAME);

      } else {

-         ret = stat(SSS_PAM_SOCKET_NAME, &stat_buf);

-         if (ret != 0) {

+         statret = stat(SSS_PAM_SOCKET_NAME, &stat_buf);

+         if (statret != 0) {

              ret = PAM_SERVICE_ERR;

              goto out;

          }
@@ -747,22 +800,27 @@

              goto out;

          }

  

-         ret = sss_cli_check_socket(errnop, SSS_PAM_SOCKET_NAME);

+         status = sss_cli_check_socket(errnop, SSS_PAM_SOCKET_NAME);

      }

-     if (ret != NSS_STATUS_SUCCESS) {

+     if (status != SSS_STATUS_SUCCESS) {

          ret = PAM_SERVICE_ERR;

          goto out;

      }

  

-     ret = check_server_cred(sss_cli_sd);

-     if (ret != 0) {

+     error = check_server_cred(sss_cli_sd);

+     if (error != 0) {

          sss_cli_close_socket();

-         *errnop = ret;

+         *errnop = error;

          ret = PAM_SERVICE_ERR;

          goto out;

      }

  

-     ret = sss_nss_make_request_nochecks(cmd, rd, repbuf, replen, errnop);

+     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();

file modified
+27 -7
@@ -1069,7 +1069,7 @@

  }

  

  static int send_and_receive(pam_handle_t *pamh, struct pam_items *pi,

-                             enum sss_cli_command task)

+                             enum sss_cli_command task, bool quiet_mode)

  {

      int ret;

      int errnop;
@@ -1092,11 +1092,11 @@

      errnop = 0;

      ret = sss_pam_make_request(task, &rd, &repbuf, &replen, &errnop);

  

-     if (ret != NSS_STATUS_SUCCESS) {

+     if (ret != PAM_SUCCESS) {

          if (errnop != 0) {

              logger(pamh, LOG_ERR, "Request to sssd failed. %s", ssscli_err2string(errnop));

          }

-         pam_status = PAM_SYSTEM_ERR;

+         pam_status = PAM_AUTHINFO_UNAVAIL;

          goto done;

      }

  
@@ -1124,17 +1124,27 @@

                     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:
@@ -1147,10 +1157,15 @@

              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_SETCRED:
@@ -1236,10 +1251,12 @@

  }

  

  static void eval_argv(pam_handle_t *pamh, int argc, const char **argv,

-                       uint32_t *flags, int *retries)

+                       uint32_t *flags, int *retries, bool *quiet_mode)

  {

      char *ep;

  

+     *quiet_mode = false;

+ 

      for (; argc-- > 0; ++argv) {

          if (strcmp(*argv, "forward_pass") == 0) {

              *flags |= FLAGS_FORWARD_PASS;
@@ -1269,6 +1286,8 @@

                      *retries = 0;

                  }

              }

+         } else if (strcmp(*argv, "quiet") == 0) {

+             *quiet_mode = true;

          } else {

              logger(pamh, LOG_WARNING, "unknown option: %s", *argv);

          }
@@ -1319,7 +1338,7 @@

      int ret;

      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) {
@@ -1394,13 +1413,14 @@

      uint32_t flags = 0;

      int *exp_data;

      bool retry = false;

+     bool quiet_mode = false;

      int retries = 0;

  

      bindtextdomain(PACKAGE, LOCALEDIR);

  

      D(("Hello pam_sssd: %d", task));

  

-     eval_argv(pamh, argc, argv, &flags, &retries);

+     eval_argv(pamh, argc, argv, &flags, &retries, &quiet_mode);

  

      ret = get_pam_items(pamh, &pi);

      if (ret != PAM_SUCCESS) {
@@ -1441,7 +1461,7 @@

                  return PAM_SYSTEM_ERR;

          }

  

-         pam_status = send_and_receive(pamh, &pi, task);

+         pam_status = send_and_receive(pamh, &pi, task, quiet_mode);

  

          switch (task) {

              case SSS_PAM_AUTHENTICATE:

@@ -267,6 +267,7 @@

  #define SSS_CLI_SOCKET_TIMEOUT 300000

  

  enum sss_status {

+     SSS_STATUS_TRYAGAIN,

      SSS_STATUS_UNAVAIL,

      SSS_STATUS_SUCCESS

  };

@@ -100,7 +100,7 @@

      ret = symlink(filename, newpath);

      fail_unless(ret == 0, "symlink failed [%d][%s]", ret, strerror(errno));

  

-     ret = check_file(newpath, uid, gid, mode, CHECK_REG, NULL);

+     ret = check_file(newpath, uid, gid, mode, CHECK_REG, NULL, false);

      unlink(newpath);

  

      fail_unless(ret == EINVAL,
@@ -108,6 +108,32 @@

  }

  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, mode, CHECK_REG, NULL, true);

+     unlink(newpath);

+ 

+     fail_unless(ret == EOK,

+                 "check_and_open_readonly failed on symlink with follow=true");

+ }

+ END_TEST

+ 

  START_TEST(test_not_regular_file)

  {

      int ret;
@@ -196,6 +222,7 @@

      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);

file modified
+16 -8
@@ -147,7 +147,7 @@

      int port;

      struct task *task;

      struct fo_server *server = NULL;

-     struct hostent *he;

+     struct resolv_hostent *he;

      int i;

  

      task = tevent_req_callback_data(req, struct task);
@@ -170,13 +170,15 @@

      if (task->new_server_status >= 0)

          fo_set_server_status(server, task->new_server_status);

  

-     he = fo_get_server_hostent(server);

-     fail_if(he == NULL, "%s: fo_get_server_hostent() returned NULL");

-     for (i = 0; he->h_addr_list[i]; i++) {

-         char buf[256];

+     if (fo_get_server_name(server) != NULL) {

+         he = fo_get_server_hostent(server);

+         fail_if(he == NULL, "%s: fo_get_server_hostent() returned NULL");

+         for (i = 0; he->addr_list[i]; i++) {

+             char buf[256];

  

-         inet_ntop(he->h_addrtype, he->h_addr_list[i], buf, sizeof(buf));

-         fail_if(strcmp(buf, "127.0.0.1") != 0 && strcmp(buf, "::1") != 0);

+             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);

+         }

      }

  

  }
@@ -215,7 +217,7 @@

  START_TEST(test_fo_resolve_service)

  {

      struct test_ctx *ctx;

-     struct fo_service *service[2];

+     struct fo_service *service[3];

  

      ctx = setup_test();

      fail_if(ctx == NULL);
@@ -225,6 +227,8 @@

  

      fail_if(fo_new_service(ctx->fo_ctx, "ldap", &service[1]) != EOK);

  

+     fail_if(fo_new_service(ctx->fo_ctx, "ntp", &service[2]) != EOK);

+ 

      /* Add servers. */

      fail_if(fo_add_server(service[0], "localhost", 20, NULL) != EOK);

      fail_if(fo_add_server(service[0], "127.0.0.1", 80, NULL) != EOK);
@@ -233,6 +237,8 @@

      fail_if(fo_add_server(service[1], "127.0.0.1", 389, NULL) != EOK);

      fail_if(fo_add_server(service[1], "127.0.0.1", 389, NULL) != EEXIST);

  

+     fail_if(fo_add_server(service[2], NULL, 123, NULL) != EOK);

+ 

      /* Make requests. */

      get_request(ctx, service[0], EOK, 20, PORT_WORKING, -1);

      get_request(ctx, service[0], EOK, 20, -1, SERVER_NOT_WORKING);
@@ -244,6 +250,8 @@

      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

file modified
+3 -3
@@ -183,7 +183,7 @@

  

      /* and finally copy.. */

      DEBUG(5, ("Will copy from '%s' to '%s'\n", dir_path, dst_path));

-     ret = copy_tree(dir_path, dst_path, uid, gid);

+     ret = copy_tree(dir_path, dst_path, 0700, uid, gid);

      fail_unless(ret == EOK, "copy_tree failed\n");

  

      /* check if really copied */
@@ -225,7 +225,7 @@

  

      /* and finally copy.. */

      DEBUG(5, ("Will copy from '%s' to '%s'\n", dir_path, dst_path));

-     ret = copy_tree(dir_path, dst_path, uid, gid);

+     ret = copy_tree(dir_path, dst_path, 0700, uid, gid);

      fail_unless(ret == EOK, "copy_tree failed\n");

  

      /* check if really copied */
@@ -264,7 +264,7 @@

  

      /* and finally copy.. */

      DEBUG(5, ("Will copy from '%s' to '%s'\n", dir_path, dst_path));

-     ret = copy_tree(dir_path, dst_path, uid, gid);

+     ret = copy_tree(dir_path, dst_path, 0700, uid, gid);

      fail_unless(ret == EOK, "copy_tree failed\n");

  

      /* check if really copied */

@@ -0,0 +1,850 @@

+ /*

+     SSSD

+ 

+     Authors:

+         Stephen Gallagher <sgallagh@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ #include <stdlib.h>

+ #include <check.h>

+ #include <unistd.h>

+ #include <sys/types.h>

+ #include <sys/stat.h>

+ #include <talloc.h>

+ 

+ #include "tests/common.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, "client.example.com");

+     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, "site_hosts");

+     fail_if(new_srchost->groups[0] == NULL);

+ 

+     new_srchost->groups[1] = talloc_strdup(new_srchost->groups, "corp_hosts");

+     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;

+     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");

+ 

+     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;

+     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");

+ 

+     /* 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");

+ 

+     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;

+     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");

+ 

+     /* 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");

+ 

+     /* 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");

+ 

+     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;

+     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");

+ 

+     /* 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");

+ 

+     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;

+     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");

+ 

+     /* 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");

+ 

+     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;

+     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");

+ 

+     /* 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");

+ 

+     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;

+     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");

+ 

+     /* 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](%s)",

+                 hbac_result_string(HBAC_EVAL_DENY),

+                 hbac_result_string(result),

+                 info ? hbac_error_string(info->code):"Unknown");

+ 

+     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;

+     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");

+ 

+     /* 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");

+ 

+     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,

+                               leak_check_setup,

+                               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;

+ }

@@ -39,6 +39,7 @@

  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}

  };

  

@@ -0,0 +1,522 @@

+ #!/usr/bin/python

+ 

+ import unittest

+ import sys

+ import os

+ import copy

+ 

+ srcdir = os.getenv('builddir')

+ if not srcdir:

+     srcdir = "."

+ MODPATH = srcdir + "/.libs" #FIXME - is there a way to get this from libtool?

+ 

+ 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:

+             import pyhbac

+         except ImportError, e:

+             print >>sys.stderr, "Could not load the pyhbac module. Please check if it is compiled"

+             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'<category 0 names [] groups []>')

+ 

+         el.category.add(pyhbac.HBAC_CATEGORY_ALL)

+         el.names = ['foo']

+         el.groups = ['bar, baz']

+         self.assertEquals(el.__repr__(), u'<category 1 names [foo] groups [bar, baz]>')

+         

+ 

+ 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"<name foo enabled 0 "

+                                         "users <category 0 names [] groups []> "

+                                         "services <category 0 names [] groups []> "

+                                         "targethosts <category 0 names [] groups []> "

+                                         "srchosts <category 0 names [] groups []>>")

+ 

+         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"<name foo enabled 0 "

+                                         "users <category 0 names [%s] groups []> "

+                                         "services <category 0 names [%s] groups []> "

+                                         "targethosts <category 0 names [%s] groups []> "

+                                         "srchosts <category 0 names [%s] groups []>>" %

+                                         (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"<name  groups []>")

+ 

+         r.name = 'foo'

+         r.groups = ['bar', 'baz']

+         self.assertEqual(r.__repr__(), u"<name foo groups [bar,baz]>")

+ 

+ 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__(), "<user <name  groups []> "

+                                          "service <name  groups []> "

+                                          "targethost <name  groups []> "

+                                          "srchost <name  groups []>>")

+ 

+         req.user.name = name

+         req.service.name = service

+         req.srchost.name = srchost

+         req.targethost.name = targethost

+ 

+         self.assertEqual(req.__repr__(), "<user <name %s groups []> "

+                                          "service <name %s groups []> "

+                                          "targethost <name %s groups []> "

+                                          "srchost <name %s groups []>>" %

+                                          (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):

+     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)

+ 

file modified
+82 -40
@@ -95,37 +95,59 @@

  START_TEST(test_copy_hostent)

  {

      void *ctx;

-     struct hostent *new_he;

+     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 };

-     char addr_1[] = { 1, 2, 3, 4 };

-     char addr_2[] = { 4, 3, 2, 1 };

-     char *addr_list[] = { addr_1, addr_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, 123 /* Whatever. */,

+             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);

  

      check_leaks_push(ctx);

-     new_he = resolv_copy_hostent(ctx, &he);

-     fail_if(new_he == NULL);

-     fail_if(strcmp(new_he->h_name, name));

-     fail_if(strcmp(new_he->h_aliases[0], alias_1));

-     fail_if(strcmp(new_he->h_aliases[1], alias_2));

-     fail_if(new_he->h_aliases[2] != NULL);

-     fail_if(new_he->h_addrtype != 123);

-     fail_if(new_he->h_length != sizeof(addr_1));

-     fail_if(memcmp(new_he->h_addr_list[0], addr_1, sizeof(addr_1)));

-     fail_if(memcmp(new_he->h_addr_list[1], addr_2, sizeof(addr_1)));

-     fail_if(new_he->h_addr_list[2] != NULL);

- 

-     talloc_free(new_he);

+ 

+     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);

+ 

      check_leaks_pop(ctx);

  }

  END_TEST
@@ -134,7 +156,7 @@

  {

      int recv_status;

      int status;

-     struct hostent *hostent;

+     struct resolv_hostent *rhostent;

      int i;

      struct resolv_test_ctx *test_ctx = tevent_req_callback_data(req,

                                                                  struct resolv_test_ctx);
@@ -142,7 +164,7 @@

      test_ctx->done = true;

  

      recv_status = resolv_gethostbyname_recv(req, test_ctx,

-                                             &status, NULL, &hostent);

+                                             &status, NULL, &rhostent);

      talloc_zfree(req);

      if (recv_status != EOK) {

          DEBUG(2, ("resolv_gethostbyname_recv failed: %d\n", recv_status));
@@ -152,15 +174,17 @@

      DEBUG(7, ("resolv_gethostbyname_recv status: %d\n", status));

  

      test_ctx->error = ENOENT;

-     for (i = 0; hostent->h_addr_list[i]; i++) {

+     for (i = 0; rhostent->addr_list[i]; i++) {

          char addr_buf[256];

-         inet_ntop(hostent->h_addrtype, hostent->h_addr_list[i], addr_buf, sizeof(addr_buf));

+         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(hostent);

+     talloc_free(rhostent);

  }

  

  START_TEST(test_resolv_ip_addr)
@@ -178,7 +202,8 @@

  

      check_leaks_push(test_ctx);

      req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,

-                                     test_ctx->resolv, hostname, IPV4_ONLY);

+                                     test_ctx->resolv, hostname, IPV4_ONLY,

+                                     default_host_dbs);

      DEBUG(7, ("Sent resolv_gethostbyname\n"));

      if (req == NULL) {

          ret = ENOMEM;
@@ -200,7 +225,7 @@

  {

      int recv_status;

      int status;

-     struct hostent *hostent;

+     struct resolv_hostent *rhostent;

      int i;

      struct resolv_test_ctx *test_ctx = tevent_req_callback_data(req,

                                                                  struct resolv_test_ctx);
@@ -208,7 +233,7 @@

      test_ctx->done = true;

  

      recv_status = resolv_gethostbyname_recv(req, test_ctx,

-                                             &status, NULL, &hostent);

+                                             &status, NULL, &rhostent);

      talloc_zfree(req);

      if (recv_status != EOK) {

          DEBUG(2, ("resolv_gethostbyname_recv failed: %d\n", recv_status));
@@ -218,16 +243,17 @@

      DEBUG(7, ("resolv_gethostbyname_recv status: %d\n", status));

  

      test_ctx->error = ENOENT;

-     for (i = 0; hostent->h_addr_list[i]; i++) {

+     for (i = 0; rhostent->addr_list[i]; i++) {

          char addr_buf[256];

-         inet_ntop(hostent->h_addrtype, hostent->h_addr_list[i], addr_buf, sizeof(addr_buf));

+         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(hostent);

+     talloc_free(rhostent);

  }

  

  START_TEST(test_resolv_localhost)
@@ -245,7 +271,8 @@

  

      check_leaks_push(test_ctx);

      req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,

-                                     test_ctx->resolv, hostname, IPV4_FIRST);

+                                     test_ctx->resolv, hostname, IPV4_FIRST,

+                                     default_host_dbs);

      DEBUG(7, ("Sent resolv_gethostbyname\n"));

      if (req == NULL) {

          ret = ENOMEM;
@@ -267,7 +294,7 @@

  {

       int recv_status;

       int status;

-      struct hostent *hostent;

+      struct resolv_hostent *hostent;

       struct resolv_test_ctx *test_ctx;

  

       test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx);
@@ -300,7 +327,8 @@

  

      check_leaks_push(test_ctx);

      req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,

-                                     test_ctx->resolv, hostname, IPV4_FIRST);

+                                     test_ctx->resolv, hostname, IPV4_FIRST,

+                                     default_host_dbs);

      DEBUG(7, ("Sent resolv_gethostbyname\n"));

      if (req == NULL) {

          ret = ENOMEM;
@@ -325,9 +353,10 @@

      int status;

      struct resolv_test_ctx *test_ctx;

      void *tmp_ctx;

-     struct hostent *hostent = NULL;

+     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);

  
@@ -339,8 +368,18 @@

      switch (test_ctx->tested_function) {

      case TESTING_HOSTNAME:

          recv_status = resolv_gethostbyname_recv(req, tmp_ctx,

-                                                 &status, NULL, &hostent);

-         test_ctx->error = (hostent->h_length == 0) ? ENOENT : EOK;

+                                                 &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(2, ("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,
@@ -368,8 +407,8 @@

      fail_if(recv_status != EOK, "The recv function failed: %d", recv_status);

      DEBUG(7, ("recv status: %d\n", status));

  

-     if (hostent != NULL) {

-         talloc_free(hostent);

+     if (rhostent != NULL) {

+         talloc_free(rhostent);

      } else if (txt_replies != NULL) {

          talloc_free(txt_replies);

      } else if (srv_replies != NULL) {
@@ -394,7 +433,8 @@

  

      check_leaks_push(test_ctx);

      req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,

-                                     test_ctx->resolv, hostname, IPV4_FIRST);

+                                     test_ctx->resolv, hostname, IPV4_FIRST,

+                                     default_host_dbs);

      DEBUG(7, ("Sent resolv_gethostbyname\n"));

      if (req == NULL) {

          ret = ENOMEM;
@@ -498,7 +538,8 @@

      }

  

      req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,

-                                     test_ctx->resolv, hostname, IPV4_FIRST);

+                                     test_ctx->resolv, hostname, IPV4_FIRST,

+                                     default_host_dbs);

      DEBUG(7, ("Sent resolv_gethostbyname\n"));

      if (req == NULL) {

          fail("Error calling resolv_gethostbyname_send");
@@ -645,7 +686,8 @@

  

      check_leaks_push(test_ctx);

      req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,

-                                     test_ctx->resolv, hostname, IPV4_FIRST);

+                                     test_ctx->resolv, hostname, IPV4_FIRST,

+                                     default_host_dbs);

      DEBUG(7, ("Sent resolv_gethostbyname\n"));

      if (req == NULL) {

          fail("Error calling resolv_gethostbyname_send");

file modified
+1 -1
@@ -59,7 +59,7 @@

      pwd = getpwnam(name);

      error = errno;

      if (pwd == NULL) {

-         if (errno == 0 || errno == ENOENT) {

+         if (error == 0 || error == ENOENT) {

              ret = (enoent_fail == 1) ? ENOENT : 0;

          }

      }

file modified
+2 -2
@@ -268,7 +268,7 @@

      int ret;

  

      ret = sysdb_add_incomplete_group(data->ctx->sysdb, data->ctx->domain,

-                                      data->groupname, data->gid);

+                                      data->groupname, data->gid, NULL, true);

      return ret;

  }

  
@@ -2743,7 +2743,7 @@

  

      /* Add */

      ret = sysdb_add_incomplete_group(test_ctx->sysdb, test_ctx->domain,

-                                      odd_groupname, 20000);

+                                      odd_groupname, 20000, NULL, true);

      fail_unless(ret == EOK, "sysdb_add_incomplete_group error [%d][%s]",

                              ret, strerror(ret));

  

file modified
+521 -393
@@ -54,6 +54,10 @@

   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

   */

  

+ #define _GNU_SOURCE

+ 

+ #include "config.h"

+ 

  #include <sys/stat.h>

  #include <sys/types.h>

  #include <sys/time.h>
@@ -62,24 +66,142 @@

  #include <errno.h>

  #include <talloc.h>

  

- #include "config.h"

  #include "util/util.h"

  #include "tools/tools_util.h"

  

- int copy_tree(const char *src_root, const char *dst_root,

-               uid_t uid, gid_t gid);

- 

  struct copy_ctx {

      const char *src_orig;

      const char *dst_orig;

      dev_t       src_dev;

+     uid_t       uid;

+     gid_t       gid;

  };

  

+ static int 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;

+ }

+ 

+ static int 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;

+ }

+ 

+ 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,

-                                 dev_t parent_dev,

-                                 const char *root);

+                                 int parent_fd,

+                                 const char *dir_name,

+                                 dev_t parent_dev);

  

  int remove_tree(const char *root)

  {
@@ -91,7 +213,7 @@

          return ENOMEM;

      }

  

-     ret = remove_tree_with_ctx(tmp_ctx, 0, root);

+     ret = remove_tree_with_ctx(tmp_ctx, AT_FDCWD, root, 0);

      talloc_free(tmp_ctx);

      return ret;

  }
@@ -102,75 +224,75 @@

   * reach the top level remove_tree() again

   */

  static int remove_tree_with_ctx(TALLOC_CTX *mem_ctx,

-                                 dev_t parent_dev,

-                                 const char *root)

+                                 int parent_fd,

+                                 const char *dir_name,

+                                 dev_t parent_dev)

  {

-     char *fullpath = NULL;

      struct dirent *result;

-     struct dirent direntp;

      struct stat statres;

      DIR *rootdir = NULL;

      int ret, err;

+     int dir_fd;

+ 

+     dir_fd = 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 = opendir(root);

+     rootdir = fdopendir(dir_fd);

      if (rootdir == NULL) {

          ret = errno;

-         DEBUG(1, ("Cannot open directory %s [%d][%s]\n",

-                   root, ret, strerror(ret)));

+         DEBUG(SSSDBG_CRIT_FAILURE,

+               ("Cannot open directory: [%d][%s]\n", ret, strerror(ret)));

+         close(dir_fd);

          goto fail;

      }

  

-     while (readdir_r(rootdir, &direntp, &result) == 0) {

-         if (result == NULL) {

-             /* End of directory */

-             break;

-         }

- 

-         if (strcmp (direntp.d_name, ".") == 0 ||

-             strcmp (direntp.d_name, "..") == 0) {

+     while ((result = readdir(rootdir)) != NULL) {

+         if (strcmp(result->d_name, ".") == 0 ||

+             strcmp(result->d_name, "..") == 0) {

              continue;

          }

  

-         fullpath = talloc_asprintf(mem_ctx, "%s/%s", root, direntp.d_name);

-         if (fullpath == NULL) {

-             ret = ENOMEM;

-             goto fail;

-         }

- 

-         ret = lstat(fullpath, &statres);

+         ret = fstatat(dir_fd, result->d_name,

+                       &statres, AT_SYMLINK_NOFOLLOW);

          if (ret != 0) {

              ret = errno;

-             DEBUG(1, ("Cannot stat %s: [%d][%s]\n",

-                       fullpath, ret, strerror(ret)));

+             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(1, ("Directory %s is on different filesystem, "

-                           "will not follow\n", fullpath));

+                 DEBUG(SSSDBG_CRIT_FAILURE,

+                       ("Directory %s is on different filesystem, "

+                        "will not follow\n"));

                  ret = EFAULT;

                  goto fail;

              }

  

-             ret = remove_tree_with_ctx(mem_ctx, statres.st_dev, fullpath);

+             ret = remove_tree_with_ctx(mem_ctx, dir_fd, result->d_name, statres.st_dev);

              if (ret != EOK) {

-                 DEBUG(1, ("Removing subdirectory %s failed: [%d][%s]\n",

-                             fullpath, ret, strerror(ret)));

+                 DEBUG(SSSDBG_CRIT_FAILURE,

+                       ("Removing subdirectory failed: [%d][%s]\n",

+                        ret, strerror(ret)));

                  goto fail;

              }

          } else {

-             ret = unlink(fullpath);

+             ret = unlinkat(dir_fd, result->d_name, 0);

              if (ret != 0) {

                  ret = errno;

-                 DEBUG(1, ("Removing file %s failed: [%d][%s]\n",

-                           fullpath, ret, strerror(ret)));

+                 DEBUG(SSSDBG_CRIT_FAILURE,

+                         ("Removing file failed: [%d][%s]\n", ret, strerror(ret)));

                  goto fail;

              }

          }

- 

-         talloc_free(fullpath);

      }

  

      ret = closedir(rootdir);
@@ -180,84 +302,29 @@

          goto fail;

      }

  

-     ret = rmdir(root);

-     if (ret != 0) {

+     ret = unlinkat(parent_fd, dir_name, AT_REMOVEDIR);

+     if (ret == -1) {

          ret = errno;

-         goto fail;

      }

  

      ret = EOK;

- 

  fail:

      if (rootdir) {  /* clean up on abnormal exit but retain return code */

          err = closedir(rootdir);

          if (err) {

-             DEBUG(1, ("closedir failed, bad dirp?\n"));

+             DEBUG(SSSDBG_CRIT_FAILURE, ("closedir failed, bad dirp?\n"));

          }

      }

      return ret;

  }

  

- static int copy_dir(const char *src, const char *dst,

-                     const struct stat *statp, const struct timeval mt[2],

-                     uid_t uid, gid_t gid)

- {

-     int ret = 0;

- 

-     /*

-      * Create a new target directory, make it owned by

-      * the user and then recursively copy that directory.

-      */

-     selinux_file_context(dst);

- 

-     ret = mkdir(dst, statp->st_mode);

-     if (ret != 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot mkdir directory '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         return ret;

-     }

- 

-     ret = chown(dst, uid, gid);

-     if (ret != 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot chown directory '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         return ret;

-     }

- 

-     ret = chmod(dst, statp->st_mode);

-     if (ret != 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot chmod directory '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         return ret;

-     }

- 

-     ret = copy_tree(src, dst, uid, gid);

-     if (ret != 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot copy directory from '%s' to '%s': [%d][%s].\n",

-                   src, dst, ret, strerror(ret)));

-         return ret;

-     }

- 

-     ret = utimes(dst, mt);

-     if (ret != 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot set utimes on a directory '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         return ret;

-     }

- 

-     return EOK;

- }

- 

- static char *talloc_readlink(TALLOC_CTX *mem_ctx, const char *filename)

+ 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) {
@@ -265,8 +332,9 @@

      }

  

      while (1) {

-         nchars = readlink(filename, buffer, size);

+         nchars = readlinkat(dir_fd, filename, buffer, size);

          if (nchars < 0) {

+             talloc_free(buffer);

              return NULL;

          }

  
@@ -277,10 +345,12 @@

  

          /* Try again with a bigger buffer */

          size *= 2;

-         buffer = talloc_realloc(mem_ctx, buffer, char, size);

-         if (!buffer) {

+         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 */
@@ -288,424 +358,482 @@

      return buffer;

  }

  

- static int copy_symlink(struct copy_ctx *cctx,

-                         const char *src,

-                         const char *dst,

-                         const struct stat *statp,

-                         const struct timeval mt[],

-                         uid_t uid, gid_t gid)

+ 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)

  {

-     int ret;

-     char *oldlink;

-     char *tmp;

-     TALLOC_CTX *tmp_ctx = NULL;

+     char *buf;

+     errno_t ret;

  

-     tmp_ctx = talloc_new(cctx);

-     if (!tmp_ctx) {

+     buf = talloc_readlinkat(NULL, src_dir_fd, file_name);

+     if (!buf) {

          return ENOMEM;

      }

  

-     /*

-      * Get the name of the file which the link points

-      * to.  If that name begins with the original

-      * source directory name, that part of the link

-      * name will be replaced with the original

-      * destination directory name.

-      */

-     oldlink = talloc_readlink(tmp_ctx, src);

-     if (oldlink == NULL) {

-         ret = ENOMEM;

-         goto done;

+     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 */

      }

  

-     /* If src was a link to an entry of the src_orig directory itself,

-      * create a link to the corresponding entry in the dst_orig

-      * directory.

-      * FIXME: This may change a relative link to an absolute link

-      */

-     if (strncmp(oldlink, cctx->src_orig, strlen(cctx->src_orig)) == 0) {

-         tmp = talloc_asprintf(tmp_ctx, "%s%s", cctx->dst_orig, oldlink + strlen(cctx->src_orig));

-         if (tmp == NULL) {

-             ret = ENOMEM;

-             goto done;

+     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;

          }

  

-         talloc_free(oldlink);

-         oldlink = tmp;

+         DEBUG(SSSDBG_CRIT_FAILURE, ("symlinkat failed: %s\n", strerror(ret)));

+         return ret;

      }

  

-     selinux_file_context(dst);

- 

-     ret = symlink(oldlink, dst);

-     if (ret != 0) {

+     ret = fchownat(dst_dir_fd, file_name,

+                    uid, gid, AT_SYMLINK_NOFOLLOW);

+     if (ret == -1) {

          ret = errno;

-         DEBUG(1, ("symlink() failed on file '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         goto done;

+         DEBUG(SSSDBG_CRIT_FAILURE,

+              ("fchownat failed: %s\n", strerror(ret)));

+         return ret;

      }

  

-     ret = lchown(dst, uid, gid);

-     if (ret != 0) {

-         ret = errno;

-         DEBUG(1, ("lchown() failed on file '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         goto done;

+     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 */

      }

  

- done:

-     talloc_free(tmp_ctx);

-     return ret;

+     return EOK;

  }

  

- static int copy_special(const char *dst,

+ /* Create a special file named file_name under a directory with file

+  * descriptor dst_dir_fd. full_path is used for both setting SELinux

+  * context and logging. The node is owned by uid/gid and its mode

+  * and device number is read from statp.

+  */

+ static int copy_special(int dst_dir_fd,

+                         const char *file_name,

+                         const char *full_path,

                          const struct stat *statp,

-                         const struct timeval mt[],

                          uid_t uid, gid_t gid)

  {

-     int ret = 0;

+     int ret;

  

-     selinux_file_context(dst);

+     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 = mknod(dst, statp->st_mode & ~07777, statp->st_rdev);

+     ret = mknodat(dst_dir_fd, file_name, statp->st_mode & ~07777,

+                   statp->st_rdev);

      if (ret != 0) {

          ret = errno;

-         DEBUG(1, ("Cannot mknod special file '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

+         DEBUG(SSSDBG_OP_FAILURE,

+               ("Cannot mknod special file '%s': [%d][%s].\n",

+               full_path, ret, strerror(ret)));

          return ret;

      }

  

-     ret = chown(dst, uid, gid);

+     ret = fchownat(dst_dir_fd, file_name, uid, gid, 0);

      if (ret != 0) {

          ret = errno;

-         DEBUG(1, ("Cannot chown special file '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

+         DEBUG(SSSDBG_CRIT_FAILURE,

+               ("fchownat failed for '%s': [%d][%s]\n",

+               full_path, ret, strerror(ret)));

          return ret;

      }

  

-     ret = chmod(dst, statp->st_mode & 07777);

+     ret = fchmodat(dst_dir_fd, file_name, statp->st_mode & 07777, 0);

      if (ret != 0) {

          ret = errno;

-         DEBUG(1, ("Cannot chmod special file '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

+         DEBUG(SSSDBG_CRIT_FAILURE,

+               ("fchmodat failed for '%s': [%d][%s]\n",

+               full_path, ret, strerror(ret)));

          return ret;

      }

  

-     ret = utimes(dst, mt);

-     if (ret != 0) {

+     ret = sss_timeat_set(dst_dir_fd, file_name, statp, 0);

+     if (ret == -1) {

          ret = errno;

-         DEBUG(1, ("Cannot call utimes on special file '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         return ret;

+         DEBUG(SSSDBG_MINOR_FAILURE,

+               ("utimensat failed for '%s': [%d][%s]\n",

+               full_path, ret, strerror(ret)));

+         /* Do not fail, this shouldn't be fatal */

      }

  

      return EOK;

  }

  

- static int copy_file(const char *src,

-                      const char *dst,

-                      const struct stat *statp,

-                      const struct timeval mt[],

-                      uid_t uid, gid_t gid)

+ /* 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 ret;

-     int ifd = -1;

      int ofd = -1;

+     errno_t ret;

      char buf[1024];

-     ssize_t cnt, written, res;

-     struct stat fstatbuf;

- 

-     ifd = open(src, O_RDONLY);

-     if (ifd < 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot open() source file '%s': [%d][%s].\n",

-                   src, ret, strerror(ret)));

-         goto fail;

-     }

+     ssize_t cnt, written;

  

-     ret = fstat(ifd, &fstatbuf);

+     ret = selinux_file_context(full_path);

      if (ret != 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot fstat() source file '%s': [%d][%s].\n",

-                   src, ret, strerror(ret)));

-         goto fail;

-     }

- 

-     if (statp->st_dev != fstatbuf.st_dev ||

-         statp->st_ino != fstatbuf.st_ino) {

-         DEBUG(1, ("File %s was modified between lstat and open.\n", src));

-         ret = EIO;

-         goto fail;

-     }

- 

-     selinux_file_context(dst);

- 

-     ofd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, statp->st_mode & 07777);

-     if (ofd < 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot open() destination file '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         goto fail;

-     }

- 

-     ret = fchown(ofd, uid, gid);

-     if (ret != 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot fchown() destination file '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         goto fail;

+         DEBUG(SSSDBG_MINOR_FAILURE,

+               ("Failed to set SELinux context for [%s]\n", full_path));

+         /* Not fatal */

      }

  

-     ret = fchmod(ofd, statp->st_mode & 07777);

-     if (ret != 0) {

+     /* 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(1, ("Cannot fchmod() destination file '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         goto fail;

+         DEBUG(SSSDBG_OP_FAILURE,

+                ("Cannot open() destination file '%s': [%d][%s].\n",

+                full_path, ret, strerror(ret)));

+         goto done;

      }

  

-     while ((cnt = read(ifd, buf, sizeof(buf))) != 0) {

+     while ((cnt = sss_atomic_read_s(ifd, buf, sizeof(buf))) != 0) {

          if (cnt == -1) {

-             if (errno == EINTR || errno == EAGAIN) {

-                 continue;

-             }

- 

-             DEBUG(1, ("Cannot read() from source file '%s': [%d][%s].\n",

-                         src, ret, strerror(ret)));

-             goto fail;

+             ret = errno;

+             DEBUG(SSSDBG_CRIT_FAILURE,

+                   ("Cannot read() from source file: [%d][%s].\n",

+                    ret, strerror(ret)));

+             goto done;

          }

-         else if (cnt > 0) {

-             /* Copy the buffer to the new file */

-             written = 0;

-             while (written < cnt) {

-                 res = write(ofd, buf+written, (size_t)cnt-written);

-                 if (res == -1) {

-                     ret = errno;

-                     if (ret == EINTR || ret == EAGAIN) {

-                         /* retry the write */

-                         continue;

-                     }

-                     DEBUG(1, ("Cannot write() to destination file '%s': [%d][%s].\n",

-                                 dst, ret, strerror(ret)));

-                     goto fail;

-                 }

-                 else if (res <= 0) {

-                     DEBUG(1, ("Unexpected result from write(): [%d]\n", res));

-                     goto fail;

-                 }

- 

-                 written += res;

-             }

+ 

+         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;

          }

-         else {

-             DEBUG(1, ("Unexpected return code of read [%d]\n", cnt));

-             goto fail;

+ 

+         if (written != cnt) {

+             DEBUG(SSSDBG_CRIT_FAILURE,

+                   ("Wrote %d bytes, expected %d\n", written, cnt));

+             goto done;

          }

      }

  

-     ret = close(ifd);

-     ifd = -1;

-     if (ret != 0) {

+     /* Set the ownership; permissions are still

+      * restrictive. */

+     ret = fchown(ofd, uid, gid);

+     if (ret == -1 && errno != EPERM) {

          ret = errno;

-         DEBUG(1, ("Cannot close() source file '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         goto fail;

+         DEBUG(SSSDBG_OP_FAILURE,

+               ("Error changing owner of '%s': %s\n",

+               full_path, strerror(ret)));

+         goto done;

      }

  

-     ret = close(ofd);

-     ifd = -1;

-     if (ret != 0) {

+     /* Set the desired mode. */

+     ret = fchmod(ofd, statp->st_mode);

+     if (ret == -1) {

          ret = errno;

-         DEBUG(1, ("Cannot close() destination file '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         goto fail;

+         DEBUG(SSSDBG_OP_FAILURE, ("Error changing owner of '%s': %s\n",

+               full_path, strerror(ret)));

+               goto done;

      }

  

-     ret = utimes(dst, mt);

-     if (ret != 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot call utimes() on destination file '%s': [%d][%s].\n",

-                   dst, ret, strerror(ret)));

-         goto fail;

+     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 */

      }

  

-     return EOK;

+     close(ofd);

+     ofd = -1;

+     ret = EOK;

  

-     /* Reachable by jump only */

- fail:

-     if (ifd != -1) close(ifd);

+ done:

      if (ofd != -1) close(ofd);

      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 copy_tree() again

-  */

- static int copy_entry(struct copy_ctx *cctx,

-                       const char *src,

-                       const char *dst,

-                       uid_t uid,

-                       gid_t gid)

+ 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)

  {

-     int ret = EOK;

-     struct stat sb;

-     struct timeval mt[2];

- 

-     ret = lstat(src, &sb);

-     if (ret == -1) {

-         ret = errno;

-         DEBUG(1, ("Cannot lstat() the source file '%s': [%d][%s].\n",

-                   src, ret, strerror(ret)));

-         return ret;

+     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;

      }

  

-     mt[0].tv_sec  = sb.st_atime;

-     mt[0].tv_usec = 0;

- 

-     mt[1].tv_sec  = sb.st_mtime;

-     mt[1].tv_usec = 0;

+     /* 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 = 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;

+         }

  

-     if (S_ISLNK (sb.st_mode)) {

-         ret = copy_symlink(cctx, src, dst, &sb, mt, uid, gid);

+         /* 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(1, ("Cannot copy symlink '%s' to '%s': [%d][%s]\n",

-                       src, dst, ret, strerror(ret)));

+             DEBUG(SSSDBG_OP_FAILURE, ("Cannot copy '%s' to '%s'\n",

+                   src_ent_path, dest_ent_path));

          }

-         return ret;

+         goto done;

      }

  

-     if (S_ISDIR(sb.st_mode)) {

-         /* Check if we're still on the same FS */

-         if (sb.st_dev != cctx->src_dev) {

-             DEBUG(2, ("Will not descend to other FS\n"));

-             /* Skip this without error */

-             return EOK;

+     ret = fstat(ifd, &st);

+     if (ret != 0) {

+         ret = errno;

+         DEBUG(SSSDBG_CRIT_FAILURE,

+                 ("couldn't stat '%s': %s", 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,

+                     ("Could recursively copy '%s' to '%s': %s\n",

+                     src_ent_path, dest_dir_fd, 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;

          }

-         return copy_dir(src, dst, &sb, mt, uid, gid);

-     } else if (!S_ISREG(sb.st_mode)) {

-         /*

-          * Deal with FIFOs and special files.  The user really

-          * shouldn't have any of these, but it seems like it

-          * would be nice to copy everything ...

-          */

-         return copy_special(dst, &sb, mt, uid, gid);

      } else {

-         /*

-          * Create the new file and copy the contents.  The new

-          * file will be owned by the provided UID and GID values.

-          */

-         return copy_file(src, dst, &sb, mt, uid, gid);

+         /* Copy a special file */

+         ret = copy_special(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;

+         }

      }

  

+     ret = EOK;

+ done:

+     talloc_free(src_ent_path);

+     talloc_free(dest_ent_path);

+     if (ifd != -1) close(ifd);

      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 copy_tree() again

-  */

- static int copy_tree_ctx(struct copy_ctx *cctx,

-                          const char *src_root,

-                          const char *dst_root,

-                          uid_t uid,

-                          gid_t gid)

+ 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)

  {

-     DIR *src_dir = NULL;

-     int ret, err;

-     struct dirent *result;

-     struct dirent direntp;

-     char *src_name, *dst_name;

-     TALLOC_CTX *tmp_ctx;

+     errno_t ret;

+     int dest_dir_fd = -1;

+     DIR *dir = NULL;

+     struct dirent *ent;

  

-     tmp_ctx = talloc_new(cctx);

+     if (!dest_dir_path) {

+         return EINVAL;

+     }

  

-     src_dir = opendir(src_root);

-     if (src_dir == NULL) {

+     dir = fdopendir(src_dir_fd);

+     if (dir == NULL) {

          ret = errno;

-         DEBUG(1, ("Cannot open the source directory %s: [%d][%s].\n",

-                   src_root, ret, strerror(ret)));

-         goto fail;

+         DEBUG(SSSDBG_CRIT_FAILURE,

+               ("Error reading '%s': %s", src_dir_path, strerror(ret)));

+         goto done;

      }

  

-     while (readdir_r(src_dir, &direntp, &result) == 0) {

-         if (result == NULL) {

-             /* End of directory */

-             break;

-         }

+     /* 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", dest_dir_path, strerror(ret)));

+         goto done;

+     }

  

-         if (strcmp (direntp.d_name, ".") == 0 ||

-             strcmp (direntp.d_name, "..") == 0) {

-             continue;

-         }

+     dest_dir_fd = 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", dest_dir_path, strerror(ret)));

+         goto done;

+     }

  

-         /* build src and dst paths */

-         src_name = talloc_asprintf(tmp_ctx, "%s/%s", src_root, direntp.d_name);

-         dst_name = talloc_asprintf(tmp_ctx, "%s/%s", dst_root, direntp.d_name);

-         if (dst_name == NULL || src_name == NULL) {

-             ret = ENOMEM;

-             goto fail;

+     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;

          }

  

-         /* copy */

-         ret = copy_entry(cctx, src_name, dst_name, uid, gid);

+         ret = copy_entry(cctx,

+                          src_dir_fd, src_dir_path,

+                          dest_dir_fd, dest_dir_path,

+                          ent->d_name);

          if (ret != EOK) {

-             DEBUG(1, ("Cannot copy '%s' to '%s', error %d\n",

-                       src_name, dst_name, ret));

-             goto fail;

+             DEBUG(SSSDBG_OP_FAILURE, ("Could not copy [%s] to [%s]\n",

+                   src_dir_path, dest_dir_path));

+             goto done;

          }

-         talloc_free(src_name);

-         talloc_free(dst_name);

      }

  

-     ret = closedir(src_dir);

-     src_dir = NULL;

-     if (ret != 0) {

+     /* 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;

-         goto fail;

+         DEBUG(SSSDBG_OP_FAILURE,

+               ("Error changing owner of '%s': %s",

+               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) {

+         DEBUG(SSSDBG_OP_FAILURE,

+               ("Error setting mode of '%s': %s",

+               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;

- fail:

-     if (src_dir) {  /* clean up on abnormal exit but retain return code */

-         err = closedir(src_dir);

-         if (err) {

-             DEBUG(1, ("closedir failed, bad dirp?\n"));

-         }

+ done:

+     if (dir) closedir(dir);

+ 

+     if (dest_dir_fd != -1) {

+         close(dest_dir_fd);

      }

-     talloc_free(tmp_ctx);

      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,

-               uid_t uid, gid_t gid)

+               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;

  

-     cctx = talloc_zero(NULL, struct copy_ctx);

+     fd = open_cloexec(src_root, O_RDONLY | O_DIRECTORY, &ret);

+     if (fd == -1) {

+         goto fail;

+     }

  

-     ret = lstat(src_root, &s_src);

-     if (ret != 0) {

+     ret = fstat(fd, &s_src);

+     if (ret == -1) {

          ret = errno;

-         DEBUG(1, ("Cannot lstat the source directory '%s': [%d][%s]\n",

-                   src_root, ret, strerror(ret)));

+         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_tree_ctx(cctx, src_root, dst_root, uid, gid);

+     ret = copy_dir(cctx, fd, src_root, AT_FDCWD,

+                    dst_root, dst_root, mode_root, &s_src);

      if (ret != EOK) {

-         DEBUG(1, ("copy_tree_ctx failed: [%d][%s]\n", ret, strerror(ret)));

+         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;

file modified
+30 -22
@@ -35,9 +35,9 @@

  #if defined(NSCD_PATH) && defined(HAVE_NSCD)

  int flush_nscd_cache(TALLOC_CTX *mem_ctx, enum nscd_db flush_db)

  {

-     char *cmd = NULL;

      const char *service;

-     int ret;

+     pid_t nscd_pid;

+     int ret, status;

  

      switch(flush_db) {

          case NSCD_DB_PASSWD:
@@ -54,30 +54,38 @@

              goto done;

      }

  

-     cmd = talloc_asprintf(mem_ctx, "%s %s %s", NSCD_PATH,

-                                                NSCD_RELOAD_ARG,

-                                                service);

-     if (!cmd) {

-         ret = ENOMEM;

-         goto done;

-     }

- 

-     ret = system(cmd);

-     if (ret) {

-         if (ret == -1) {

-             DEBUG(1, ("system(3) failed\n"));

-             ret = EFAULT;

-             goto done;

+     nscd_pid = fork();

+     switch (nscd_pid) {

+     case 0:

+         execl(NSCD_PATH, "nscd", NSCD_RELOAD_ARG, service, NULL);

+         /* if this returns it is an error */

+         DEBUG(1, ("execl(3) failed: %d(%s)\n", errno, strerror(errno)));

+         exit(errno);

+     case -1:

+         DEBUG(1, ("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(8, ("Error flushing cache, is nscd running?\n"));

+                 }

+             }

+         } else {

+             DEBUG(5, ("Failed to wait for children %d\n", nscd_pid));

+             ret = EIO;

          }

-         /* The flush fails if nscd is not running, so do not care

-          * about the return code */

-         DEBUG(8, ("Error flushing cache, perhaps nscd is not running\n"));

      }

  

- 

-     ret = EOK;

  done:

-     talloc_free(cmd);

      return ret;

  }

  

file modified
+43 -15
@@ -19,17 +19,13 @@

                        dest="stdin", default=False,

                        help="Read the password from stdin.")

      parser.add_option("-d", "--domain",

-                       dest="domain", default="default",

-                       help="The domain to use the password in (default: default)",

+                       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")

-     parser.add_option("-p", "--password",

-                       dest="password", default=None,

-                       help="Password to obfuscate.",

-                       metavar="PASSWORD")

      (options, args) = parser.parse_args()

  

      return options, args
@@ -40,13 +36,33 @@

          print >> sys.stderr, "Cannot parse options"

          return 1

  

-     if not options.stdin and not options.password:

-         pprompt = lambda: (getpass.getpass("Enter password: "), getpass.getpass("Re-enter password: "))

-         p1, p2 = pprompt()

-         while p1 != p2:

-             print('Passwords do not match. Try again')

+     if not options.domain:

+         print >> sys.stderr, "No domain specified"

+         return 1

+ 

+     if not options.stdin:

+         try:

+             pprompt = lambda: (getpass.getpass("Enter password: "), getpass.getpass("Re-enter password: "))

              p1, p2 = pprompt()

-         password = p1

+ 

+             #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 >> sys.stderr, '\nUnexpected end-of-file. Password change aborted'

+             return 1

+         except KeyboardInterrupt:

+             return 1

  

      else:

          try:
@@ -59,11 +75,15 @@

      obfpwd = obfobj.encrypt(password, obfobj.AES_256)

  

      # Save the obfuscated password into the domain

-     sssdconfig = SSSDConfig.SSSDConfig()

+     try:

+         sssdconfig = SSSDConfig.SSSDConfig()

+     except IOError:

+         print "Cannot read internal configuration files."

+         return 1

      try:

          sssdconfig.import_config(options.filename)

      except IOError:

-         print "Cannot open config file %s" % options.filename

+         print "Permissions error reading config file"

          return 1

  

      try:
@@ -82,7 +102,15 @@

  

  

      sssdconfig.save_domain(domain)

-     sssdconfig.write()

+     try:

+         sssdconfig.write()

+     except IOError:

+         # File could not be written

+         print >> sys.stderr, "Could not write to config file. Check that " \

+                              "you have the appropriate permissions to edit " \

+                              "this file."

+         return 1

+ 

      return 0

  

  if __name__ == "__main__":

file modified
+1 -27
@@ -478,33 +478,7 @@

  

      selinux_file_context(homedir);

  

-     ret = mkdir(homedir, 0);

-     if (ret != 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot create user's home directory: [%d][%s].\n",

-                   ret, strerror(ret)));

-         goto done;

-     }

- 

-     ret = chown(homedir, uid, gid);

-     if (ret != 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot chown user's home directory: [%d][%s].\n",

-                   ret, strerror(ret)));

-         goto done;

-     }

- 

-     ret = chmod(homedir, 0777 & ~default_umask);

-     if (ret != 0) {

-         ret = errno;

-         DEBUG(1, ("Cannot chmod user's home directory: [%d][%s].\n",

-                   ret, strerror(ret)));

-         goto done;

-     }

- 

-     reset_selinux_file_context();

- 

-     ret = copy_tree(skeldir, homedir, uid, gid);

+     ret = copy_tree(skeldir, homedir, 0777 & ~default_umask, uid, gid);

      if (ret != EOK) {

          DEBUG(1, ("Cannot populate user's home directory: [%d][%s].\n",

                    ret, strerror(ret)));

file modified
+2 -3
@@ -104,9 +104,8 @@

  /* from files.c */

  int remove_tree(const char *root);

  

- int copy_tree(const char *src_root,

-               const char *dst_root,

-               uid_t uid, gid_t gid);

+ int copy_tree(const char *src_root, const char *dst_root,

+               mode_t mode_root, uid_t uid, gid_t gid);

  

  /* from nscd.c */

  enum nscd_db {

file added
+60
@@ -0,0 +1,60 @@

+ /*

+     Authors:

+         Jan Cholasta <jcholast@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #include "util/atomic_io.h"

+ 

+ /* based on code from libssh <http://www.libssh.org> */

+ 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;

+ }

file added
+40
@@ -0,0 +1,40 @@

+ /*

+     Authors:

+         Jan Cholasta <jcholast@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #ifndef __SSSD_ATOMIC_IO_H__

+ #define __SSSD_ATOMIC_IO_H__

+ 

+ #include <unistd.h>

+ #include <stdbool.h>

+ #include <poll.h>

+ #include <errno.h>

+ 

+ /* 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__ */

file modified
+1 -1
@@ -68,7 +68,7 @@

          dst_fd = open(dst_file, O_CREAT|O_EXCL|O_WRONLY, 0600);

          ret = errno;

  

-         if (dst_fd > 0) break;

+         if (dst_fd >= 0) break;

  

          if (ret != EEXIST) {

              DEBUG(dbglvl, ("Error (%d [%s]) opening destination file %s\n",

file modified
+3 -2
@@ -35,7 +35,7 @@

  

  errno_t check_file(const char *filename, const int uid, const int gid,

                     const int mode, enum check_file_type type,

-                    struct stat *caller_stat_buf)

+                    struct stat *caller_stat_buf, bool follow_symlink)

  {

      int ret;

      struct stat local_stat_buf;
@@ -47,7 +47,8 @@

          stat_buf = caller_stat_buf;

      }

  

-     ret = lstat(filename, stat_buf);

+     ret = follow_symlink ? stat(filename, stat_buf) : \

+                            lstat(filename, stat_buf);

      if (ret == -1) {

          DEBUG(1, ("lstat for [%s] failed: [%d][%s].\n", filename, errno,

                                                          strerror(errno)));

file modified
+11
@@ -23,6 +23,7 @@

  #include <stdio.h>

  #include <stdarg.h>

  #include <stdlib.h>

+ #include <fcntl.h>

  

  #include <sys/types.h>

  #include <sys/stat.h>
@@ -117,6 +118,8 @@

      const char *log_file;

      mode_t old_umask;

      int ret;

+     int debug_fd;

+     int flags;

  

      if (filename == NULL) {

          log_file = debug_log_file;
@@ -142,6 +145,14 @@

      }

      umask(old_umask);

  

+     debug_fd = fileno(f);

+     if (debug_fd == -1) {

+         return EIO;

+     }

+ 

+     flags = fcntl(debug_fd, F_GETFD, 0);

+     (void) fcntl(debug_fd, F_SETFD, flags | FD_CLOEXEC);

+ 

      if (filep == NULL) {

          debug_file = f;

      } else {

file modified
+1 -1
@@ -122,7 +122,7 @@

                      (list2)->prev = (el); \

                      tmp->next = (el)->next; \

                      (el)->next = (list2); \

-                     if ((el)->next != NULL) (el)->next->prev = tmp; \

+                     if (tmp->next != NULL) tmp->next->prev = tmp; \

      } \

  } while (0);

  

file modified
+31 -4
@@ -25,6 +25,7 @@

  

  #define _GNU_SOURCE

  #include <sys/types.h>

+ #include <sys/wait.h>

  #include <sys/stat.h>

  #include <fcntl.h>

  #include <unistd.h>
@@ -67,18 +68,43 @@

  #endif

  }

  

+ static void deamon_parent_sigterm(int sig)

+ {

+     _exit(0);

+ }

+ 

  /**

   Become a daemon, discarding the controlling terminal.

  **/

  

  void become_daemon(bool Fork)

  {

-         int ret;

+     pid_t pid;

+     int status;

+     int ret;

  

  	if (Fork) {

- 		if (fork()) {

- 			_exit(0);

- 		}

+         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 */

+             waitpid(pid, &status, 0);

+ 

+             /* return error if we didn't exited normally */

+             ret = 1;

+ 

+             if (WIFEXITED(status)) {

+                 /* but return our exit code otherwise */

+                 ret = WEXITSTATUS(status);

+             }

+ 

+             _exit(ret);

+         }

  	}

  

      /* detach from the terminal */
@@ -430,6 +456,7 @@

          return ENOMEM;

      }

  

+     ctx->parent_pid = getppid();

      ctx->event_ctx = event_ctx;

  

      conf_db = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE);

file modified
+418
@@ -18,11 +18,47 @@

      along with this program.  If not, see <http://www.gnu.org/licenses/>.

  */

  #include <stdlib.h>

+ #include <netdb.h>

+ #include <unistd.h>

+ #include <fcntl.h>

+ #include <sys/socket.h>

+ #include <netinet/in.h>

+ #include <netinet/tcp.h>

  

  #include "config.h"

  

  #include "util/sss_ldap.h"

+ #include "util/util.h"

  

+ const char* sss_ldap_err2string(int err)

+ {

+     static const char *password_expired = "Password expired";

+ 

+     switch (err) {

+     case LDAP_X_SSSD_PASSWORD_EXPIRED:

+         return password_expired;

+     default:

+         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,
@@ -68,3 +104,385 @@

      return LDAP_SUCCESS;

  #endif

  }

+ 

+ inline const char *

+ sss_ldap_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);

+ }

+ 

+ #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(1, ("fcntl F_GETFL failed.\n"));

+         return NULL;

+     }

+ 

+     req = tevent_req_create(mem_ctx, &state,

+                             struct sdap_async_sys_connect_state);

+     if (req == NULL) {

+         DEBUG(1, ("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(1, ("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(1, ("tevent_add_fd failed.\n"));

+                 ret = ENOMEM;

+                 goto done;

+             }

+ 

+             return req;

+ 

+             break;

+         default:

+             DEBUG(1, ("connect failed [%d][%s].\n", ret, strerror(ret)));

+     }

+ 

+ done:

+     fret = fcntl(fd, F_SETFL, flags);

+     if (fret != EOK) {

+         DEBUG(1, ("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 = EOK;

+     int fret;

+ 

+     /* I found the following comment in samba's lib/async_req/async_sock.c:

+      * Stevens, Network Programming says that if there's a

+      * successful connect, the socket is only writable. Upon an

+      * error, it's both readable and writable.

+      */

+     if ((flags & (TEVENT_FD_READ|TEVENT_FD_WRITE)) ==

+         (TEVENT_FD_READ|TEVENT_FD_WRITE)) {

+ 

+         ret = connect(state->fd, (struct sockaddr *) &state->addr,

+                       state->addr_len);

+         if (ret == EOK) {

+             goto done;

+         }

+ 

+         ret = errno;

+         if (ret == EINPROGRESS || ret == EINTR) {

+             return;

+         }

+ 

+         DEBUG(1, ("connect failed [%d][%s].\n", ret, strerror(ret)));

+     }

+ 

+ done:

+     talloc_zfree(fde);

+ 

+     fret = fcntl(state->fd, F_SETFL, state->old_flags);

+     if (fret != EOK) {

+         DEBUG(1, ("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(1, ("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(1, ("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(5, ("setsockopt SO_KEEPALIVE failed.[%d][%s].\n", ret,

+                   strerror(ret)));

+     }

+ 

+     ret = setsockopt(fd, SOL_TCP, TCP_NODELAY, &dummy, sizeof(dummy));

+     if (ret != 0) {

+         ret = errno;

+         DEBUG(5, ("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

+ };

+ 

+ 

+ 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(1, ("tevent_req_create failed.\n"));

+         return NULL;

+     }

+ 

+     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(1, ("socket failed [%d][%s].\n", ret, strerror(ret)));

+         goto fail;

+     }

+ 

+     ret = set_fd_flags_and_opts(state->sd);

+     if (ret != EOK) {

+         DEBUG(1, ("set_fd_flags_and_opts failed.\n"));

+         goto fail;

+     }

+ 

+     DEBUG(9, ("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(1, ("sdap_async_sys_connect_send failed.\n"));

+         goto fail;

+     }

+ 

+     DEBUG(6, ("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(1, ("tevent_add_timer failed.\n"));

+         ret = ENOMEM;

+         goto fail;

+     }

+ 

+     tevent_req_set_callback(subreq, sss_ldap_init_sys_connect_done, req);

+     return req;

+ 

+ fail:

+     if(state->sd >= 0) {

+         close(state->sd);

+     }

+     tevent_req_error(req, ret);

+ #else

+     DEBUG(3, ("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(1, ("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(4, ("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(1, ("sdap_async_sys_connect request failed.\n"));

+         close(state->sd);

+         tevent_req_error(req, ret);

+         return;

+     }

+     /* Initialize LDAP handler */

+ 

+     lret = ldap_init_fd(state->sd, LDAP_PROTO_TCP, state->uri, &state->ldap);

+     if (lret != LDAP_SUCCESS) {

+         DEBUG(1, ("ldap_init_fd failed: %s. [%ld][%s]\n",

+                   sss_ldap_err2string(lret), state->sd, state->uri));

+         close(state->sd);

+         if (lret == LDAP_SERVER_DOWN) {

+             tevent_req_error(req, ETIMEDOUT);

+         } else {

+             tevent_req_error(req, EIO);

+         }

+         return;

+     }

+ 

+     if (ldap_is_ldaps_url(state->uri)) {

+         lret = ldap_install_tls(state->ldap);

+         if (lret != LDAP_SUCCESS) {

+             if (lret == LDAP_LOCAL_ERROR) {

+                 DEBUG(5, ("TLS/SSL already in place.\n"));

+             } else {

+                 DEBUG(1, ("ldap_install_tls failed: %s\n",

+                           sss_ldap_err2string(lret)));

+ 

+                 tevent_req_error(req, EIO);

+                 return;

+             }

+         }

+     }

+ 

+     tevent_req_done(req);

+     return;

+ }

+ #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);

+ 

+     *ldap = state->ldap;

+     *sd = state->sd;

+ 

+     return EOK;

+ }

file modified
+32
@@ -21,10 +21,42 @@

  #ifndef __SSS_LDAP_H__

  #define __SSS_LDAP_H__

  

+ #include <sys/types.h>

+ #include <sys/socket.h>

  #include <ldap.h>

+ #include <talloc.h>

+ #include <tevent.h>

+ 

+ #define LDAP_X_SSSD_PASSWORD_EXPIRED 0x555D

+ 

+ #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);

  

  int sss_ldap_control_create(const char *oid, int iscritical,

                              struct berval *value, int dupval,

                              LDAPControl **ctrlp);

  

+ inline const char *

+ sss_ldap_escape_ip_address(TALLOC_CTX *mem_ctx, int family, const char *addr);

+ 

+ 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);

  #endif /* __SSS_LDAP_H__ */

file added
+104
@@ -0,0 +1,104 @@

+ /*

+     Authors:

+         Jakub Hrozek <jhrozek@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #include "src/util/sss_python.h"

+ #include "config.h"

+ 

+ PyObject *

+ sss_python_set_new(void)

+ {

+ #ifdef HAVE_PYSET_NEW

+     return PySet_New(NULL);

+ #else

+     return PyObject_CallObject((PyObject *) &PySet_Type, NULL);

+ #endif

+ }

+ 

+ int

+ sss_python_set_add(PyObject *set, PyObject *key)

+ {

+ #ifdef HAVE_PYSET_ADD

+     return PySet_Add(set, key);

+ #else

+     PyObject *pyret;

+     int ret;

+ 

+     pyret = PyObject_CallMethod(set, sss_py_const_p(char, "add"),

+                                 sss_py_const_p(char, "O"), key);

+     ret = (pyret == NULL) ? -1 : 0;

+     Py_XDECREF(pyret);

+     return ret;

+ #endif

+ }

+ 

+ bool

+ sss_python_set_check(PyObject *set)

+ {

+ #if HAVE_DECL_PYSET_CHECK

+     return PySet_Check(set);

+ #else

+     return PyObject_TypeCheck(set, &PySet_Type);

+ #endif

+ }

+ 

+ PyObject *

+ sss_python_unicode_from_string(const char *u)

+ {

+ #ifdef HAVE_PYUNICODE_FROMSTRING

+     return PyUnicode_FromString(u);

+ #else

+     return PyUnicode_DecodeUTF8(u, strlen(u), NULL);

+ #endif

+ }

+ 

+ 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

+ }

@@ -0,0 +1,63 @@

+ #ifndef __SSS_PYTHON_H__

+ #define __SSS_PYTHON_H__

+ 

+ #include <Python.h>

+ #include <stdbool.h>

+ #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

+ 

+ /* Py_ssize_t compatibility for python < 2.5 as per

+  * http://www.python.org/dev/peps/pep-0353/ */

+ #ifndef HAVE_PY_SSIZE_T

+ typedef int Py_ssize_t;

+ #endif

+ 

+ #ifndef PY_SSIZE_T_MAX

+ #define PY_SSIZE_T_MAX INT_MAX

+ #endif

+ 

+ #ifndef PY_SSIZE_T_MIN

+ #define PY_SSIZE_T_MIN INT_MIN

+ #endif

+ 

+ /* Wrappers providing the subset of C API for python's set objects we use */

+ PyObject *sss_python_set_new(void);

+ int sss_python_set_add(PyObject *set, PyObject *key);

+ bool sss_python_set_check(PyObject *set);

+ 

+ /* Unicode compatibility */

+ PyObject *sss_python_unicode_from_string(const char *u);

+ 

+ /* Exceptions compatibility */

+ PyObject *

+ sss_exception_with_doc(char *name, char *doc, PyObject *base, PyObject *dict);

+ 

+ /* PyModule_AddIntMacro() compatibility */

+ #if !HAVE_DECL_PYMODULE_ADDINTMACRO

+ #define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant(m, sss_py_const_p(char, #c), c)

+ #endif

+ 

+ /* Convenience macros */

+ #define TYPE_READY(module, type, name) do {         \

+     if (PyType_Ready(&type) < 0)                    \

+         return;                                     \

+     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__ */

file added
+119
@@ -0,0 +1,119 @@

+ /*

+     SSSD

+ 

+     Authors:

+         Stephen Gallagher <sgallagh@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #include "util/util.h"

+ #include "sss_utf8.h"

+ 

+ #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 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 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

file added
+43
@@ -0,0 +1,43 @@

+ /*

+     SSSD

+ 

+     Authors:

+         Stephen Gallagher <sgallagh@redhat.com>

+ 

+     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 <http://www.gnu.org/licenses/>.

+ */

+ 

+ #ifndef SSS_UTF8_H_

+ #define SSS_UTF8_H_

+ 

+ #ifdef HAVE_LIBUNISTRING

+ #include <unistr.h>

+ #include <unicase.h>

+ #elif HAVE_GLIB2

+ #include <glib.h>

+ #endif

+ #include "util/util.h"

+ 

+ #ifndef ENOMATCH

+ #define ENOMATCH -1

+ #endif

+ 

+ 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_ */

file modified
+21 -1
@@ -42,6 +42,7 @@

  #include <tevent.h>

  #include <ldb.h>

  #include <dhash.h>

+ #include "util/atomic_io.h"

  

  #ifndef HAVE_ERRNO_T

  #define HAVE_ERRNO_T
@@ -60,6 +61,24 @@

  void debug_fn(const char *format, ...);

  errno_t set_debug_file_from_fd(const int fd);

  

+ #define SSS_DEFAULT_DEBUG_LEVEL SSSDBG_DEFAULT

+ #define SSS_UNRESOLVED_DEBUG_LEVEL SSSDBG_UNRESOLVED

+ 

+ #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_UNRESOLVED     -1

+ #define SSSDBG_MASK_ALL       0xFFF0   /* enable all debug levels */

+ #define SSSDBG_DEFAULT        SSSDBG_FATAL_FAILURE

+ 

  #define SSSD_DEBUG_OPTS \

          {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, \

           _("Debug level"), NULL}, \
@@ -257,6 +276,7 @@

  struct main_context {

      struct tevent_context *event_ctx;

      struct confdb_ctx *confdb_ctx;

+     pid_t parent_pid;

  };

  

  int die_if_parent_died(void);
@@ -333,7 +353,7 @@

   */

  errno_t check_file(const char *filename, const int uid, const int gid,

                     const int mode, enum check_file_type type,

-                    struct stat *caller_stat_buf);

+                    struct stat *caller_stat_buf, bool follow_symlink);

  

  /* check_fd()

   * Verify that an open file descriptor has certain permissions and/or

file modified
+1 -1
@@ -1,5 +1,5 @@

  # Primary version number

- m4_define([VERSION_NUMBER], [1.5.1])

+ m4_define([VERSION_NUMBER], [1.5.18])

  

  # If the PRERELEASE_VERSION_NUMBER is set, we'll append

  # it to the release tag when creating an RPM or SRPM