ctdb: Use str_list_add_printf() in lock_helper_args()
[samba.git] / source3 / lib / idmap_cache.c
index ffd3c1955cdc723f80bc464cdf915983664ed9f5..a4b8861f4663d389c67e74d0b40982dc057e50d6 100644 (file)
@@ -21,6 +21,8 @@
 #include "idmap_cache.h"
 #include "../libcli/security/security.h"
 #include "../librpc/gen_ndr/idmap.h"
+#include "lib/gencache.h"
+#include "lib/util/string_wrappers.h"
 
 /**
  * Find a sid2xid mapping
@@ -35,7 +37,7 @@
 bool idmap_cache_find_sid2unixid(const struct dom_sid *sid, struct unixid *id,
                                 bool *expired)
 {
-       fstring sidstr;
+       struct dom_sid_buf sidstr;
        char *key;
        char *value = NULL;
        char *endptr;
@@ -44,7 +46,7 @@ bool idmap_cache_find_sid2unixid(const struct dom_sid *sid, struct unixid *id,
        struct unixid tmp_id;
 
        key = talloc_asprintf(talloc_tos(), "IDMAP/SID2XID/%s",
-                             sid_to_fstring(sidstr, sid));
+                             dom_sid_str_buf(sid, &sidstr));
        if (key == NULL) {
                return false;
        }
@@ -188,89 +190,89 @@ bool idmap_cache_find_sid2gid(const struct dom_sid *sid, gid_t *pgid,
        return true;
 }
 
-/**
- * Find a uid2sid mapping
- * @param[in] uid              the uid to map
- * @param[out] sid             where to put the result
- * @param[out] expired         is the cache entry expired?
- * @retval Was anything in the cache at all?
- *
- * If "is_null_sid(sid)", this was a negative mapping.
- */
+struct idmap_cache_xid2sid_state {
+       struct dom_sid *sid;
+       bool *expired;
+       bool ret;
+};
 
-bool idmap_cache_find_uid2sid(uid_t uid, struct dom_sid *sid, bool *expired)
+static void idmap_cache_xid2sid_parser(const struct gencache_timeout *timeout,
+                                      DATA_BLOB blob,
+                                      void *private_data)
 {
-       char *key;
+       struct idmap_cache_xid2sid_state *state =
+               (struct idmap_cache_xid2sid_state *)private_data;
        char *value;
-       time_t timeout;
-       bool ret = true;
 
-       key = talloc_asprintf(talloc_tos(), "IDMAP/UID2SID/%d", (int)uid);
-       if (key == NULL) {
-               return false;
-       }
-       ret = gencache_get(key, talloc_tos(), &value, &timeout);
-       TALLOC_FREE(key);
-       if (!ret) {
-               return false;
+       if ((blob.length == 0) || (blob.data[blob.length-1] != 0)) {
+               /*
+                * Not a string, can't be a valid mapping
+                */
+               state->ret = false;
+               return;
        }
-       ZERO_STRUCTP(sid);
-       if (value[0] != '-') {
-               ret = string_to_sid(sid, value);
+
+       value = (char *)blob.data;
+
+       if ((value[0] == '-') && (value[1] == '\0')) {
+               /*
+                * Return NULL SID, see comment to uid2sid
+                */
+               *state->sid = (struct dom_sid) {0};
+               state->ret = true;
+       } else {
+               state->ret = string_to_sid(state->sid, value);
        }
-       TALLOC_FREE(value);
-       if (ret) {
-               *expired = (timeout <= time(NULL));
+       if (state->ret) {
+               *state->expired = gencache_timeout_expired(timeout);
        }
-       return ret;
 }
 
 /**
- * Find a gid2sid mapping
- * @param[in] gid              the gid to map
+ * Find a xid2sid mapping
+ * @param[in] id               the unix id to map
  * @param[out] sid             where to put the result
  * @param[out] expired         is the cache entry expired?
  * @retval Was anything in the cache at all?
  *
  * If "is_null_sid(sid)", this was a negative mapping.
  */
-
-bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired)
+bool idmap_cache_find_xid2sid(
+       const struct unixid *id, struct dom_sid *sid, bool *expired)
 {
-       char *key;
-       char *value;
-       time_t timeout;
-       bool ret = true;
-
-       key = talloc_asprintf(talloc_tos(), "IDMAP/GID2SID/%d", (int)gid);
-       if (key == NULL) {
+       struct idmap_cache_xid2sid_state state = {
+               .sid = sid, .expired = expired
+       };
+       fstring key;
+       char c;
+
+       switch (id->type) {
+       case ID_TYPE_UID:
+               c = 'U';
+               break;
+       case ID_TYPE_GID:
+               c = 'G';
+               break;
+       default:
                return false;
        }
-       ret = gencache_get(key, talloc_tos(), &value, &timeout);
-       TALLOC_FREE(key);
-       if (!ret) {
-               return false;
-       }
-       ZERO_STRUCTP(sid);
-       if (value[0] != '-') {
-               ret = string_to_sid(sid, value);
-       }
-       TALLOC_FREE(value);
-       if (ret) {
-               *expired = (timeout <= time(NULL));
-       }
-       return ret;
+
+       fstr_sprintf(key, "IDMAP/%cID2SID/%d", c, (int)id->id);
+
+       gencache_parse(key, idmap_cache_xid2sid_parser, &state);
+       return state.ret;
 }
 
+
 /**
  * Store a mapping in the idmap cache
  * @param[in] sid              the sid to map
- * @param[in] gid              the gid to map
+ * @param[in] unix_id          the unix_id to map
  *
  * If both parameters are valid values, then a positive mapping in both
  * directions is stored. If "is_null_sid(sid)" is true, then this will be a
- * negative mapping of gid, we want to cache that for this gid we could not
- * find anything. Likewise if "gid==-1", then we want to cache that we did not
+ * negative mapping of xid, we want to cache that for this xid we could not
+ * find anything. Likewise if "xid==-1", then we want to cache that we did not
  * find a mapping for the sid passed here.
  */
 
@@ -278,11 +280,12 @@ void idmap_cache_set_sid2unixid(const struct dom_sid *sid, struct unixid *unix_i
 {
        time_t now = time(NULL);
        time_t timeout;
-       fstring sidstr, key, value;
+       fstring key, value;
 
        if (!is_null_sid(sid)) {
+               struct dom_sid_buf sidstr;
                fstr_sprintf(key, "IDMAP/SID2XID/%s",
-                            sid_to_fstring(sidstr, sid));
+                            dom_sid_str_buf(sid, &sidstr));
                switch (unix_id->type) {
                case ID_TYPE_UID:
                        fstr_sprintf(value, "%d:U", (int)unix_id->id);
@@ -306,7 +309,7 @@ void idmap_cache_set_sid2unixid(const struct dom_sid *sid, struct unixid *unix_i
        }
        if (unix_id->id != -1) {
                if (is_null_sid(sid)) {
-                       /* negative gid mapping */
+                       /* negative xid mapping */
                        fstrcpy(value, "-");
                        timeout = lp_idmap_negative_cache_time();
                }
@@ -337,78 +340,6 @@ void idmap_cache_set_sid2unixid(const struct dom_sid *sid, struct unixid *unix_i
        }
 }
 
-/**
- * Store a mapping in the idmap cache
- * @param[in] sid              the sid to map
- * @param[in] uid              the uid to map
- *
- * If both parameters are valid values, then a positive mapping in both
- * directions is stored. If "is_null_sid(sid)" is true, then this will be a
- * negative mapping of uid, we want to cache that for this uid we could not
- * find anything. Likewise if "uid==-1", then we want to cache that we did not
- * find a mapping for the sid passed here.
- */
-
-void idmap_cache_set_sid2uid(const struct dom_sid *sid, uid_t uid)
-{
-       struct unixid id;
-       id.type = ID_TYPE_UID;
-       id.id = uid;
-
-       if (uid == -1) {
-               uid_t tmp_gid;
-               bool expired;
-               /* If we were asked to invalidate this SID -> UID
-                * mapping, it was because we found out that this was
-                * not a UID at all.  Do not overwrite a valid GID or
-                * BOTH mapping */
-               if (idmap_cache_find_sid2gid(sid, &tmp_gid, &expired)) {
-                       if (!expired) {
-                               return;
-                       }
-               }
-       }
-
-       idmap_cache_set_sid2unixid(sid, &id);
-       return;
-}
-
-/**
- * Store a mapping in the idmap cache
- * @param[in] sid              the sid to map
- * @param[in] gid              the gid to map
- *
- * If both parameters are valid values, then a positive mapping in both
- * directions is stored. If "is_null_sid(sid)" is true, then this will be a
- * negative mapping of gid, we want to cache that for this gid we could not
- * find anything. Likewise if "gid==-1", then we want to cache that we did not
- * find a mapping for the sid passed here.
- */
-
-void idmap_cache_set_sid2gid(const struct dom_sid *sid, gid_t gid)
-{
-       struct unixid id;
-       id.type = ID_TYPE_GID;
-       id.id = gid;
-
-       if (gid == -1) {
-               uid_t tmp_uid;
-               bool expired;
-               /* If we were asked to invalidate this SID -> GID
-                * mapping, it was because we found out that this was
-                * not a GID at all.  Do not overwrite a valid UID or
-                * BOTH mapping */
-               if (idmap_cache_find_sid2uid(sid, &tmp_uid, &expired)) {
-                       if (!expired) {
-                               return;
-                       }
-               }
-       }
-
-       idmap_cache_set_sid2unixid(sid, &id);
-       return;
-}
-
 static char* key_xid2sid_str(TALLOC_CTX* mem_ctx, char t, const char* id) {
        return talloc_asprintf(mem_ctx, "IDMAP/%cID2SID/%s", t, id);
 }
@@ -474,6 +405,7 @@ bool idmap_cache_del_sid(const struct dom_sid *sid)
        bool ret = true;
        bool expired;
        struct unixid id;
+       struct dom_sid_buf sidbuf;
        const char *sid_key;
 
        if (!idmap_cache_find_sid2unixid(sid, &id, &expired)) {
@@ -498,7 +430,7 @@ bool idmap_cache_del_sid(const struct dom_sid *sid)
                }
        }
 
-       sid_key = key_sid2xid_str(mem_ctx, dom_sid_string(mem_ctx, sid));
+       sid_key = key_sid2xid_str(mem_ctx, dom_sid_str_buf(sid, &sidbuf));
        if (sid_key == NULL) {
                return false;
        }