#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
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;
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;
}
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.
*/
{
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);
}
if (unix_id->id != -1) {
if (is_null_sid(sid)) {
- /* negative gid mapping */
+ /* negative xid mapping */
fstrcpy(value, "-");
timeout = lp_idmap_negative_cache_time();
}
}
}
-/**
- * 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);
}
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)) {
}
}
- 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;
}