diff options
Diffstat (limited to 'src/responder')
-rw-r--r-- | src/responder/common/negcache.c | 45 | ||||
-rw-r--r-- | src/responder/common/negcache.h | 2 | ||||
-rw-r--r-- | src/responder/common/negcache_files.c | 98 | ||||
-rw-r--r-- | src/responder/common/negcache_files.h | 31 | ||||
-rw-r--r-- | src/responder/common/responder_common.c | 22 |
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"); |