From 6c57f78d2e4e9fbf0ea0d92b9f96110aa3ec4053 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Sat, 21 Jan 2012 16:16:24 -0500
Subject: [PATCH 08/10] NSS: Add negative cache routines for services

---
 src/responder/common/negcache.c |  102 +++++++++++++++++++++++++++++++++++++-
 src/responder/common/negcache.h |   15 ++++++
 2 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index 0b25baf5660b327bd3102899f55e273ce1204aec..c7795e4bb9c9fa38081f71892da7963f5165d32d 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -30,6 +30,7 @@
 #define NC_USER_PREFIX NC_ENTRY_PREFIX"USER"
 #define NC_GROUP_PREFIX NC_ENTRY_PREFIX"GROUP"
 #define NC_NETGROUP_PREFIX NC_ENTRY_PREFIX"NETGR"
+#define NC_SERVICE_PREFIX NC_ENTRY_PREFIX"SERVICE"
 #define NC_UID_PREFIX NC_ENTRY_PREFIX"UID"
 #define NC_GID_PREFIX NC_ENTRY_PREFIX"GID"
 
@@ -37,6 +38,13 @@ struct sss_nc_ctx {
     struct tdb_context *tdb;
 };
 
+typedef int (*ncache_set_byname_fn_t)(struct sss_nc_ctx *, bool,
+                                      const char *, const char *);
+
+static int sss_ncache_set_ent(struct sss_nc_ctx *ctx, bool permanent,
+                              struct sss_domain_info *dom, const char *name,
+                              ncache_set_byname_fn_t setter);
+
 static int string_to_tdb_data(char *str, TDB_DATA *ret)
 {
     if (!str || !ret) return EINVAL;
@@ -210,6 +218,28 @@ static int sss_ncache_check_netgr_int(struct sss_nc_ctx *ctx, int ttl,
     return ret;
 }
 
+static int sss_ncache_check_service_int(struct sss_nc_ctx *ctx,
+                                        int ttl,
+                                        const char *domain,
+                                        const char *name)
+{
+    char *str;
+    int ret;
+
+    if (!name || !*name) return EINVAL;
+
+    str = talloc_asprintf(ctx, "%s/%s/%s",
+                          NC_SERVICE_PREFIX,
+                          domain,
+                          name);
+    if (!str) return ENOMEM;
+
+    ret = sss_ncache_check_str(ctx, str, ttl);
+
+    talloc_free(str);
+    return ret;
+}
+
 typedef int (*ncache_check_byname_fn_t)(struct sss_nc_ctx *, int,
                                         const char *, const char *);
 
@@ -253,6 +283,75 @@ int sss_ncache_check_netgr(struct sss_nc_ctx *ctx, int ttl,
                                sss_ncache_check_netgr_int);
 }
 
+static int sss_ncache_set_service_int(struct sss_nc_ctx *ctx, bool permanent,
+                                      const char *domain, const char *name)
+{
+    char *str;
+    int ret;
+
+    if (!name || !*name) return EINVAL;
+
+    str = talloc_asprintf(ctx, "%s/%s/%s", NC_SERVICE_PREFIX, domain, name);
+    if (!str) return ENOMEM;
+
+    ret = sss_ncache_set_str(ctx, str, permanent);
+
+    talloc_free(str);
+    return ret;
+}
+
+int sss_ncache_set_service_name(struct sss_nc_ctx *ctx, bool permanent,
+                                struct sss_domain_info *dom,
+                                const char *name, const char *proto)
+{
+    char *service_and_protocol = talloc_asprintf(ctx, "%s:%s",
+                                                 name,
+                                                 proto ? proto : "<ANY>");
+    return sss_ncache_set_ent(ctx, permanent, dom,
+                              service_and_protocol,
+                              sss_ncache_set_service_int);
+}
+
+int sss_ncache_check_service(struct sss_nc_ctx *ctx, int ttl,
+                             struct sss_domain_info *dom,
+                             const char *name,
+                             const char *proto)
+{
+    char *service_and_protocol = talloc_asprintf(ctx, "%s:%s",
+                                                 name,
+                                                 proto ? proto : "<ANY>");
+
+    return sss_cache_check_ent(ctx, ttl, dom, service_and_protocol,
+                               sss_ncache_check_service_int);
+}
+
+int sss_ncache_set_service_port(struct sss_nc_ctx *ctx, bool permanent,
+                                struct sss_domain_info *dom,
+                                uint16_t port, const char *proto)
+{
+    char *service_and_protocol = talloc_asprintf(ctx, "%ul:%s",
+                                                 port,
+                                                 proto ? proto : "<ANY>");
+    return sss_ncache_set_ent(ctx, permanent, dom,
+                              service_and_protocol,
+                              sss_ncache_set_service_int);
+}
+
+int sss_ncache_check_service_port(struct sss_nc_ctx *ctx, int ttl,
+                                  struct sss_domain_info *dom,
+                                  uint16_t port,
+                                  const char *proto)
+{
+    char *service_and_protocol = talloc_asprintf(ctx, "%ul:%s",
+                                                 port,
+                                                 proto ? proto : "<ANY>");
+
+    return sss_cache_check_ent(ctx, ttl, dom, service_and_protocol,
+                               sss_ncache_check_service_int);
+}
+
+
+
 int sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, uid_t uid)
 {
     char *str;
@@ -332,9 +431,6 @@ static int sss_ncache_set_netgr_int(struct sss_nc_ctx *ctx, bool permanent,
     return ret;
 }
 
-typedef int (*ncache_set_byname_fn_t)(struct sss_nc_ctx *, bool,
-                                      const char *, const char *);
-
 static int sss_ncache_set_ent(struct sss_nc_ctx *ctx, bool permanent,
                               struct sss_domain_info *dom, const char *name,
                               ncache_set_byname_fn_t setter)
diff --git a/src/responder/common/negcache.h b/src/responder/common/negcache.h
index 72b99c969043d42c6f1329d8b0d549cadaddb998..74f7ff344ce17ab402bc11c87d2afb0d20e7dca5 100644
--- a/src/responder/common/negcache.h
+++ b/src/responder/common/negcache.h
@@ -37,6 +37,15 @@ int sss_ncache_check_netgr(struct sss_nc_ctx *ctx, int ttl,
 int sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, uid_t uid);
 int sss_ncache_check_gid(struct sss_nc_ctx *ctx, int ttl, gid_t gid);
 
+int sss_ncache_check_service(struct sss_nc_ctx *ctx, int ttl,
+                             struct sss_domain_info *dom,
+                             const char *name,
+                             const char *proto);
+int sss_ncache_check_service_port(struct sss_nc_ctx *ctx, int ttl,
+                                  struct sss_domain_info *dom,
+                                  uint16_t port,
+                                  const char *proto);
+
 /* add a new neg-cache entry setting the timestamp to "now" unless
  * "permanent" is set to true, in which case the timestamps is set to 0
  * and the negative cache never expires (used to permanently filter out
@@ -49,6 +58,12 @@ int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool permanent,
                          struct sss_domain_info *dom, const char *name);
 int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent, uid_t uid);
 int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent, gid_t gid);
+int sss_ncache_set_service_name(struct sss_nc_ctx *ctx, bool permanent,
+                                struct sss_domain_info *dom,
+                                const char *name, const char *proto);
+int sss_ncache_set_service_port(struct sss_nc_ctx *ctx, bool permanent,
+                                struct sss_domain_info *dom,
+                                uint16_t port, const char *proto);
 
 int sss_ncache_reset_permament(struct sss_nc_ctx *ctx);
 
-- 
1.7.7.5

