nsssrv.c revision 99c99e557020775714f028b28a147edda290c783
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina/*
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina SSSD
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina NSS Responder
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina This program is free software; you can redistribute it and/or modify
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina it under the terms of the GNU General Public License as published by
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina the Free Software Foundation; either version 3 of the License, or
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina (at your option) any later version.
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina This program is distributed in the hope that it will be useful,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina GNU General Public License for more details.
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina You should have received a copy of the GNU General Public License
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina*/
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include <stdio.h>
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include <unistd.h>
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include <fcntl.h>
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include <sys/types.h>
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include <sys/stat.h>
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include <sys/socket.h>
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include <sys/un.h>
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include <string.h>
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include <sys/time.h>
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include <errno.h>
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "popt.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "util/util.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "responder/nss/nsssrv.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "responder/nss/nsssrv_mmap_cache.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "responder/common/negcache.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "db/sysdb.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "confdb/confdb.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "dbus/dbus.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "sbus/sssd_dbus.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "responder/common/responder_packet.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "responder/common/responder.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "providers/data_provider.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "monitor/monitor_interfaces.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#include "sbus/sbus_client.h"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#define DEFAULT_PWFIELD "*"
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#define DEFAULT_NSS_FD_LIMIT 8192
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#define SHELL_REALLOC_INCREMENT 5
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina#define SHELL_REALLOC_MAX 50
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březinastatic int nss_clear_memcache(DBusMessage *message,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina struct sbus_connection *conn);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březinastruct sbus_method monitor_nss_methods[] = {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina { MON_CLI_METHOD_PING, monitor_common_pong },
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina { MON_CLI_METHOD_ROTATE, responder_logrotate },
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina { MON_CLI_METHOD_CLEAR_MEMCACHE, nss_clear_memcache},
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina { NULL, NULL }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina};
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březinastruct sbus_interface monitor_nss_interface = {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina MONITOR_INTERFACE,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina MONITOR_PATH,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina SBUS_DEFAULT_VTABLE,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina monitor_nss_methods,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina NULL
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina};
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březinastatic int nss_clear_memcache(DBusMessage *message,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina struct sbus_connection *conn)
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina{
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina errno_t ret;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina int memcache_timeout;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(conn),
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina struct resp_ctx);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina struct nss_ctx *nctx = (struct nss_ctx*) rctx->pvt_ctx;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = unlink(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (ret != 0) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = errno;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (ret == ENOENT) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina DEBUG(SSSDBG_TRACE_FUNC,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ("CLEAR_MC_FLAG not found. Nothing to do.\n"));
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina goto done;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina } else {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to unlink file: %s.\n",
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina strerror(ret)));
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina return ret;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina /* CLEAR_MC_FLAG removed successfully. Clearing memory caches. */
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = confdb_get_int(rctx->cdb,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina CONFDB_NSS_CONF_ENTRY,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina CONFDB_MEMCACHE_TIMEOUT,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina 300, &memcache_timeout);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (ret != EOK) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina DEBUG(SSSDBG_FATAL_FAILURE,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ("Unable to get memory cache entry timeout.\n"));
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina return ret;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina /* TODO: read cache sizes from configuration */
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, ("Clearing memory caches.\n"));
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = sss_mmap_cache_reinit(nctx, SSS_MC_CACHE_ELEMENTS,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina (time_t) memcache_timeout,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina &nctx->pwd_mc_ctx);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (ret != EOK) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ("passwd mmap cache invalidation failed\n"));
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina return ret;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = sss_mmap_cache_reinit(nctx, SSS_MC_CACHE_ELEMENTS,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina (time_t) memcache_timeout,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina &nctx->grp_mc_ctx);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (ret != EOK) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ("group mmap cache invalidation failed\n"));
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina return ret;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březinadone:
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina return monitor_common_pong(message, conn);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina}
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březinastatic errno_t nss_get_etc_shells(TALLOC_CTX *mem_ctx, char ***_shells)
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina{
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina int i = 0;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina char *sh;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina char **shells = NULL;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina TALLOC_CTX *tmp_ctx;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina errno_t ret;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina int size;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina tmp_ctx = talloc_new(NULL);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (!tmp_ctx) return ENOMEM;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina shells = talloc_array(tmp_ctx, char *, SHELL_REALLOC_INCREMENT);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (!shells) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = ENOMEM;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina goto done;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina size = SHELL_REALLOC_INCREMENT;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina setusershell();
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina while ((sh = getusershell())) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina shells[i] = talloc_strdup(shells, sh);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (!shells[i]) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina endusershell();
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = ENOMEM;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina goto done;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina DEBUG(6, ("Found shell %s in /etc/shells\n", shells[i]));
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina i++;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (i == size) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina size += SHELL_REALLOC_INCREMENT;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (size > SHELL_REALLOC_MAX) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina DEBUG(0, ("Reached maximum number of shells [%d]. "
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina "Users may be denied access. "
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina "Please check /etc/shells for sanity\n",
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina SHELL_REALLOC_MAX));
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina break;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina shells = talloc_realloc(NULL, shells, char *,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina size);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (!shells) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = ENOMEM;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina goto done;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina endusershell();
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (i + 1 < size) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina shells = talloc_realloc(NULL, shells, char *, i + 1);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (!shells) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = ENOMEM;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina goto done;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina shells[i] = NULL;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina *_shells = talloc_move(mem_ctx, &shells);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = EOK;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březinadone:
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina talloc_zfree(tmp_ctx);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina return ret;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina}
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březinastatic int nss_get_config(struct nss_ctx *nctx,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina struct confdb_ctx *cdb)
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina{
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina int ret;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina CONFDB_NSS_ENUM_CACHE_TIMEOUT, 120,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina &nctx->enum_cache_timeout);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (ret != EOK) goto done;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina CONFDB_NSS_ENTRY_NEG_TIMEOUT, 15,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina &nctx->neg_timeout);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (ret != EOK) goto done;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = confdb_get_bool(cdb, CONFDB_NSS_CONF_ENTRY,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina CONFDB_NSS_FILTER_USERS_IN_GROUPS, true,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina &nctx->filter_users_in_groups);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (ret != EOK) goto done;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina CONFDB_NSS_ENTRY_CACHE_NOWAIT_PERCENTAGE, 50,
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina &nctx->cache_refresh_percent);
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (ret != EOK) goto done;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina if (nctx->cache_refresh_percent < 0 ||
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina nctx->cache_refresh_percent > 99) {
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina DEBUG(0,("Configuration error: entry_cache_nowait_percentage is "
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina "invalid. Disabling feature.\n"));
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina nctx->cache_refresh_percent = 0;
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina }
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina
b407fe0474a674bb42f0f42ab47c7f530a07a367Pavel Březina ret = sss_ncache_prepopulate(nctx->ncache, cdb, nctx->rctx);
if (ret != EOK) {
goto done;
}
ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
CONFDB_NSS_PWFIELD, DEFAULT_PWFIELD,
&nctx->pwfield);
if (ret != EOK) goto done;
ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
CONFDB_NSS_OVERRIDE_HOMEDIR, NULL,
&nctx->override_homedir);
if (ret != EOK) goto done;
ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
CONFDB_NSS_FALLBACK_HOMEDIR, NULL,
&nctx->fallback_homedir);
if (ret != EOK) goto done;
ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
CONFDB_NSS_OVERRIDE_SHELL, NULL,
&nctx->override_shell);
if (ret != EOK && ret != ENOENT) goto done;
ret = confdb_get_string_as_list(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
CONFDB_NSS_ALLOWED_SHELL,
&nctx->allowed_shells);
if (ret != EOK && ret != ENOENT) goto done;
ret = confdb_get_string_as_list(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
CONFDB_NSS_VETOED_SHELL,
&nctx->vetoed_shells);
if (ret != EOK && ret != ENOENT) goto done;
ret = nss_get_etc_shells(nctx, &nctx->etc_shells);
if (ret != EOK) goto done;
ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
CONFDB_NSS_SHELL_FALLBACK,
CONFDB_DEFAULT_SHELL_FALLBACK,
&nctx->shell_fallback);
if (ret != EOK) goto done;
ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
CONFDB_NSS_DEFAULT_SHELL,
NULL,
&nctx->default_shell);
if (ret != EOK) goto done;
ret = 0;
done:
return ret;
}
static struct sbus_method nss_dp_methods[] = {
{ NULL, NULL }
};
struct sbus_interface nss_dp_interface = {
DP_INTERFACE,
DP_PATH,
SBUS_DEFAULT_VTABLE,
nss_dp_methods,
NULL
};
static void nss_dp_reconnect_init(struct sbus_connection *conn,
int status, void *pvt)
{
struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn);
int ret;
/* Did we reconnect successfully? */
if (status == SBUS_RECONNECT_SUCCESS) {
DEBUG(1, ("Reconnected to the Data Provider.\n"));
/* Identify ourselves to the data provider */
ret = dp_common_send_id(be_conn->conn,
DATA_PROVIDER_VERSION,
"NSS");
/* all fine */
if (ret == EOK) {
handle_requests_after_reconnect(be_conn->rctx);
return;
}
}
/* Failed to reconnect */
DEBUG(0, ("Could not reconnect to %s provider.\n",
be_conn->domain->name));
/* FIXME: kill the frontend and let the monitor restart it ? */
/* nss_shutdown(rctx); */
}
int nss_process_init(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct confdb_ctx *cdb)
{
struct sss_cmd_table *nss_cmds;
struct be_conn *iter;
struct nss_ctx *nctx;
int memcache_timeout;
int ret, max_retries;
int hret;
int fd_limit;
nctx = talloc_zero(mem_ctx, struct nss_ctx);
if (!nctx) {
DEBUG(0, ("fatal error initializing nss_ctx\n"));
return ENOMEM;
}
ret = sss_ncache_init(nctx, &nctx->ncache);
if (ret != EOK) {
DEBUG(0, ("fatal error initializing negative cache\n"));
return ret;
}
nss_cmds = get_nss_cmds();
ret = sss_process_init(nctx, ev, cdb,
nss_cmds,
SSS_NSS_SOCKET_NAME, NULL,
CONFDB_NSS_CONF_ENTRY,
NSS_SBUS_SERVICE_NAME,
NSS_SBUS_SERVICE_VERSION,
&monitor_nss_interface,
"NSS", &nss_dp_interface,
&nctx->rctx);
if (ret != EOK) {
return ret;
}
nctx->rctx->pvt_ctx = nctx;
ret = nss_get_config(nctx, cdb);
if (ret != EOK) {
DEBUG(0, ("fatal error getting nss config\n"));
return ret;
}
/* Enable automatic reconnection to the Data Provider */
ret = confdb_get_int(nctx->rctx->cdb,
CONFDB_NSS_CONF_ENTRY,
CONFDB_SERVICE_RECON_RETRIES,
3, &max_retries);
if (ret != EOK) {
DEBUG(0, ("Failed to set up automatic reconnection\n"));
return ret;
}
for (iter = nctx->rctx->be_conns; iter; iter = iter->next) {
sbus_reconnect_init(iter->conn, max_retries,
nss_dp_reconnect_init, iter);
}
/* Create the lookup table for netgroup results */
hret = sss_hash_create(nctx, 10, &nctx->netgroups);
if (hret != HASH_SUCCESS) {
DEBUG(0,("Unable to initialize netgroup hash table\n"));
return EIO;
}
/* create mmap caches */
/* Remove the CLEAR_MC_FLAG file if exists. */
ret = unlink(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG);
if (ret != 0 && errno != ENOENT) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
("Failed to unlink file [%s]. This can cause memory cache to "
"be purged when next log rotation is requested. %d: %s\n",
SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG, ret, strerror(ret)));
}
ret = confdb_get_int(nctx->rctx->cdb,
CONFDB_NSS_CONF_ENTRY,
CONFDB_MEMCACHE_TIMEOUT,
300, &memcache_timeout);
if (ret != EOK) {
DEBUG(0, ("Failed to set up automatic reconnection\n"));
return ret;
}
/* TODO: read cache sizes from configuration */
ret = sss_mmap_cache_init(nctx, "passwd", SSS_MC_PASSWD,
SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
&nctx->pwd_mc_ctx);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE, ("passwd mmap cache is DISABLED\n"));
}
ret = sss_mmap_cache_init(nctx, "group", SSS_MC_GROUP,
SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
&nctx->grp_mc_ctx);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE, ("group mmap cache is DISABLED\n"));
}
/* Set up file descriptor limits */
ret = confdb_get_int(nctx->rctx->cdb,
CONFDB_NSS_CONF_ENTRY,
CONFDB_SERVICE_FD_LIMIT,
DEFAULT_NSS_FD_LIMIT,
&fd_limit);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE,
("Failed to set up file descriptor limit\n"));
return ret;
}
responder_set_fd_limit(fd_limit);
DEBUG(SSSDBG_TRACE_FUNC, ("NSS Initialization complete\n"));
return EOK;
}
int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
struct main_context *main_ctx;
int ret;
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
POPT_TABLEEND
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */
debug_level = SSSDBG_INVALID;
pc = poptGetContext(argv[0], argc, argv, long_options, 0);
while((opt = poptGetNextOpt(pc)) != -1) {
switch(opt) {
default:
fprintf(stderr, "\nInvalid option %s: %s\n\n",
poptBadOption(pc, 0), poptStrerror(opt));
poptPrintUsage(pc, stderr, 0);
return 1;
}
}
poptFreeContext(pc);
CONVERT_AND_SET_DEBUG_LEVEL(debug_level);
/* set up things like debug, signals, daemonization, etc... */
debug_log_file = "sssd_nss";
ret = server_setup("sssd[nss]", 0, CONFDB_NSS_CONF_ENTRY, &main_ctx);
if (ret != EOK) return 2;
ret = die_if_parent_died();
if (ret != EOK) {
/* This is not fatal, don't return */
DEBUG(2, ("Could not set up to exit when parent process does\n"));
}
ret = nss_process_init(main_ctx,
main_ctx->event_ctx,
main_ctx->confdb_ctx);
if (ret != EOK) return 3;
/* loop on main */
server_loop(main_ctx);
return 0;
}