summaryrefslogtreecommitdiffstats
path: root/src/responder
diff options
context:
space:
mode:
Diffstat (limited to 'src/responder')
-rw-r--r--src/responder/common/negcache.c45
-rw-r--r--src/responder/common/negcache.h2
-rw-r--r--src/responder/common/negcache_files.c98
-rw-r--r--src/responder/common/negcache_files.h31
-rw-r--r--src/responder/common/responder_common.c22
5 files changed, 183 insertions, 15 deletions
diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index 1488c12a8..025455238 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -21,6 +21,7 @@
#include "util/util.h"
#include "confdb/confdb.h"
+#include "responder/common/negcache_files.h"
#include "responder/common/responder.h"
#include "responder/common/negcache.h"
#include <fcntl.h>
@@ -40,6 +41,7 @@
struct sss_nc_ctx {
struct tdb_context *tdb;
uint32_t timeout;
+ uint32_t local_timeout;
};
typedef int (*ncache_set_byname_fn_t)(struct sss_nc_ctx *, bool,
@@ -59,8 +61,8 @@ static int string_to_tdb_data(char *str, TDB_DATA *ret)
return EOK;
}
-int sss_ncache_init(TALLOC_CTX *memctx, uint32_t timeout,
- struct sss_nc_ctx **_ctx)
+int sss_ncache_init(TALLOC_CTX *memctx, uint32_t timeout,
+ uint32_t local_timeout, struct sss_nc_ctx **_ctx)
{
struct sss_nc_ctx *ctx;
@@ -73,6 +75,7 @@ int sss_ncache_init(TALLOC_CTX *memctx, uint32_t timeout,
if (!ctx->tdb) return errno;
ctx->timeout = timeout;
+ ctx->local_timeout = local_timeout;
*_ctx = ctx;
return EOK;
@@ -139,8 +142,8 @@ done:
return ret;
}
-static int sss_ncache_set_str(struct sss_nc_ctx *ctx,
- char *str, bool permanent)
+static int sss_ncache_set_str(struct sss_nc_ctx *ctx, char *str,
+ bool permanent, bool is_local)
{
TDB_DATA key;
TDB_DATA data;
@@ -154,7 +157,15 @@ static int sss_ncache_set_str(struct sss_nc_ctx *ctx,
if (permanent) {
timest = talloc_strdup(ctx, "0");
} else {
- timell = (unsigned long long int)time(NULL) + ctx->timeout;
+ if (is_local == true && ctx->local_timeout > 0) {
+ timell = (unsigned long long int)time(NULL) + ctx->local_timeout;
+ } else {
+ if (ctx->timeout > 0) {
+ timell = (unsigned long long int)time(NULL) + ctx->timeout;
+ } else {
+ return EOK;
+ }
+ }
timest = talloc_asprintf(ctx, "%llu", timell);
}
if (!timest) return ENOMEM;
@@ -300,7 +311,7 @@ static int sss_ncache_set_service_int(struct sss_nc_ctx *ctx, bool permanent,
str = talloc_asprintf(ctx, "%s/%s/%s", NC_SERVICE_PREFIX, domain, name);
if (!str) return ENOMEM;
- ret = sss_ncache_set_str(ctx, str, permanent);
+ ret = sss_ncache_set_str(ctx, str, permanent, false);
talloc_free(str);
return ret;
@@ -446,6 +457,7 @@ int sss_ncache_check_cert(struct sss_nc_ctx *ctx, const char *cert)
static int sss_ncache_set_user_int(struct sss_nc_ctx *ctx, bool permanent,
const char *domain, const char *name)
{
+ bool is_local;
char *str;
int ret;
@@ -454,7 +466,8 @@ static int sss_ncache_set_user_int(struct sss_nc_ctx *ctx, bool permanent,
str = talloc_asprintf(ctx, "%s/%s/%s", NC_USER_PREFIX, domain, name);
if (!str) return ENOMEM;
- ret = sss_ncache_set_str(ctx, str, permanent);
+ is_local = is_user_local_by_name(name);
+ ret = sss_ncache_set_str(ctx, str, permanent, is_local);
talloc_free(str);
return ret;
@@ -463,6 +476,7 @@ static int sss_ncache_set_user_int(struct sss_nc_ctx *ctx, bool permanent,
static int sss_ncache_set_group_int(struct sss_nc_ctx *ctx, bool permanent,
const char *domain, const char *name)
{
+ bool is_local;
char *str;
int ret;
@@ -471,7 +485,8 @@ static int sss_ncache_set_group_int(struct sss_nc_ctx *ctx, bool permanent,
str = talloc_asprintf(ctx, "%s/%s/%s", NC_GROUP_PREFIX, domain, name);
if (!str) return ENOMEM;
- ret = sss_ncache_set_str(ctx, str, permanent);
+ is_local = is_group_local_by_name(name);
+ ret = sss_ncache_set_str(ctx, str, permanent, is_local);
talloc_free(str);
return ret;
@@ -488,7 +503,7 @@ static int sss_ncache_set_netgr_int(struct sss_nc_ctx *ctx, bool permanent,
str = talloc_asprintf(ctx, "%s/%s/%s", NC_NETGROUP_PREFIX, domain, name);
if (!str) return ENOMEM;
- ret = sss_ncache_set_str(ctx, str, permanent);
+ ret = sss_ncache_set_str(ctx, str, permanent, false);
talloc_free(str);
return ret;
@@ -535,6 +550,7 @@ int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool permanent,
int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent,
struct sss_domain_info *dom, uid_t uid)
{
+ bool is_local;
char *str;
int ret;
@@ -546,7 +562,8 @@ int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent,
}
if (!str) return ENOMEM;
- ret = sss_ncache_set_str(ctx, str, permanent);
+ is_local = is_user_local_by_uid(uid);
+ ret = sss_ncache_set_str(ctx, str, permanent, is_local);
talloc_free(str);
return ret;
@@ -555,6 +572,7 @@ int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent,
int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent,
struct sss_domain_info *dom, gid_t gid)
{
+ bool is_local;
char *str;
int ret;
@@ -566,7 +584,8 @@ int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent,
}
if (!str) return ENOMEM;
- ret = sss_ncache_set_str(ctx, str, permanent);
+ is_local = is_group_local_by_gid(gid);
+ ret = sss_ncache_set_str(ctx, str, permanent, is_local);
talloc_free(str);
return ret;
@@ -580,7 +599,7 @@ int sss_ncache_set_sid(struct sss_nc_ctx *ctx, bool permanent, const char *sid)
str = talloc_asprintf(ctx, "%s/%s", NC_SID_PREFIX, sid);
if (!str) return ENOMEM;
- ret = sss_ncache_set_str(ctx, str, permanent);
+ ret = sss_ncache_set_str(ctx, str, permanent, false);
talloc_free(str);
return ret;
@@ -595,7 +614,7 @@ int sss_ncache_set_cert(struct sss_nc_ctx *ctx, bool permanent,
str = talloc_asprintf(ctx, "%s/%s", NC_CERT_PREFIX, cert);
if (!str) return ENOMEM;
- ret = sss_ncache_set_str(ctx, str, permanent);
+ ret = sss_ncache_set_str(ctx, str, permanent, false);
talloc_free(str);
return ret;
diff --git a/src/responder/common/negcache.h b/src/responder/common/negcache.h
index 572c723cc..377f97c8b 100644
--- a/src/responder/common/negcache.h
+++ b/src/responder/common/negcache.h
@@ -26,7 +26,7 @@ struct sss_nc_ctx;
/* init the in memory negative cache */
int sss_ncache_init(TALLOC_CTX *memctx, uint32_t timeout,
- struct sss_nc_ctx **_ctx);
+ uint32_t local_timeout, struct sss_nc_ctx **_ctx);
uint32_t sss_ncache_get_timeout(struct sss_nc_ctx *ctx);
diff --git a/src/responder/common/negcache_files.c b/src/responder/common/negcache_files.c
new file mode 100644
index 000000000..1b9a4be43
--- /dev/null
+++ b/src/responder/common/negcache_files.c
@@ -0,0 +1,98 @@
+/*
+ SSSD
+
+ NSS Responder
+
+ Copyright (C) Petr Čech <pcech@redhat.com> 2016
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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 <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include "util/util.h"
+#include "responder/common/negcache_files.h"
+
+#define BUFFER_SIZE 16384
+
+bool is_user_local_by_name(const char *name)
+{
+ struct passwd pwd = { 0 };
+ struct passwd *pwd_result;
+ char buffer[BUFFER_SIZE];
+ bool is_local = false;
+ int ret;
+
+ ret = getpwnam_r(name, &pwd, buffer, BUFFER_SIZE, &pwd_result);
+ if (ret == EOK && pwd_result != NULL) {
+ DEBUG(SSSDBG_TRACE_FUNC, "User %s is a local user\n", name);
+ is_local = true;
+ }
+
+ return is_local;
+}
+
+bool is_user_local_by_uid(uid_t uid)
+{
+ struct passwd pwd = { 0 };
+ struct passwd *pwd_result;
+ char buffer[BUFFER_SIZE];
+ bool is_local = false;
+ int ret;
+
+ ret = getpwuid_r(uid, &pwd, buffer, BUFFER_SIZE, &pwd_result);
+ if (ret == EOK && pwd_result != NULL) {
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "User with UID %"SPRIuid" is a local user\n", uid);
+ is_local = true;
+ }
+
+ return is_local;
+}
+
+bool is_group_local_by_name(const char *name)
+{
+ struct group grp = { 0 };
+ struct group *grp_result;
+ char buffer[BUFFER_SIZE];
+ bool is_local = false;
+ int ret;
+
+ ret = getgrnam_r(name, &grp, buffer, BUFFER_SIZE, &grp_result);
+ if (ret == EOK && grp_result != NULL) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Group %s is a local group\n", name);
+ is_local = true;
+ }
+
+ return is_local;
+}
+
+bool is_group_local_by_gid(uid_t gid)
+{
+ struct group grp = { 0 };
+ struct group *grp_result;
+ char buffer[BUFFER_SIZE];
+ bool is_local = false;
+ int ret;
+
+ ret = getgrgid_r(gid, &grp, buffer, BUFFER_SIZE, &grp_result);
+ if (ret == EOK && grp_result != NULL) {
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "Group with GID %"SPRIgid" is a local group\n", gid);
+ is_local = true;
+ }
+
+ return is_local;
+}
diff --git a/src/responder/common/negcache_files.h b/src/responder/common/negcache_files.h
new file mode 100644
index 000000000..01d9f0828
--- /dev/null
+++ b/src/responder/common/negcache_files.h
@@ -0,0 +1,31 @@
+/*
+ SSSD
+
+ NSS Responder
+
+ Copyright (C) Petr Čech <pcech@redhat.com> 2016
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General 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 _NEGCACHE_FILES_H_
+#define _NEGCACHE_FILES_H_
+
+bool is_user_local_by_name(const char *name);
+bool is_user_local_by_uid(uid_t uid);
+
+bool is_group_local_by_name(const char *name);
+bool is_group_local_by_gid(uid_t gid);
+
+#endif /* _NEGCACHE_FILES_H_ */
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 883b22a65..f0ddde9c0 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -761,6 +761,7 @@ static errno_t responder_init_ncache(TALLOC_CTX *mem_ctx,
struct sss_nc_ctx **ncache)
{
uint32_t neg_timeout;
+ uint32_t locals_timeout;
int tmp_value;
int ret;
@@ -783,8 +784,27 @@ static errno_t responder_init_ncache(TALLOC_CTX *mem_ctx,
neg_timeout = tmp_value;
ret = EOK;
+ /* local_timeout */
+ ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY,
+ CONFDB_RESPONDER_LOCAL_NEG_TIMEOUT,
+ 0, &tmp_value);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Fatal failure of setup negative cache timeout.\n");
+ ret = ENOENT;
+ goto done;
+ }
+
+ if (tmp_value < 0) {
+ ret = EINVAL;
+ goto done;
+ }
+
+ locals_timeout = tmp_value;
+ ret = EOK;
+
/* negative cache init */
- ret = sss_ncache_init(mem_ctx, neg_timeout, ncache);
+ ret = sss_ncache_init(mem_ctx, neg_timeout, locals_timeout, ncache);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE,
"Fatal failure of initializing negative cache.\n");