if (key == NULL) {
return false;
}
- ret = gencache_get(key, &value, &timeout);
+ ret = gencache_get(key, talloc_tos(), &value, &timeout);
if (!ret) {
goto done;
}
DEBUG(10, ("Parsing value for key [%s]: value=[%s]\n", key, value));
+ if (value[0] == '\0') {
+ DEBUG(0, ("Failed to parse value for key [%s]: "
+ "value is empty\n", key));
+ ret = false;
+ goto done;
+ }
+
tmp_id.id = strtol(value, &endptr, 10);
+
+ if ((value == endptr) && (tmp_id.id == 0)) {
+ DEBUG(0, ("Failed to parse value for key [%s]: value[%s] does "
+ "not start with a number\n", key, value));
+ ret = false;
+ goto done;
+ }
+
DEBUG(10, ("Parsing value for key [%s]: id=[%llu], endptr=[%s]\n",
key, (unsigned long long)tmp_id.id, endptr));
tmp_id.type = ID_TYPE_BOTH;
break;
+ case 'N':
+ tmp_id.type = ID_TYPE_NOT_SPECIFIED;
+ break;
+
case '\0':
DEBUG(0, ("FAILED to parse value for key [%s] "
"(id=[%llu], endptr=[%s]): "
done:
TALLOC_FREE(key);
- SAFE_FREE(value);
+ TALLOC_FREE(value);
return ret;
}
return true;
}
+struct idmap_cache_xid2sid_state {
+ struct dom_sid *sid;
+ bool *expired;
+ bool ret;
+};
+
+static void idmap_cache_xid2sid_parser(time_t timeout, DATA_BLOB blob,
+ void *private_data)
+{
+ struct idmap_cache_xid2sid_state *state =
+ (struct idmap_cache_xid2sid_state *)private_data;
+ char *value;
+
+ ZERO_STRUCTP(state->sid);
+ state->ret = false;
+
+ if ((blob.length == 0) || (blob.data[blob.length-1] != 0)) {
+ /*
+ * Not a string, can't be a valid mapping
+ */
+ return;
+ }
+
+ value = (char *)blob.data;
+
+ if (value[0] != '-') {
+ state->ret = string_to_sid(state->sid, value);
+ }
+ if (state->ret) {
+ *state->expired = (timeout <= time(NULL));
+ }
+}
+
/**
* Find a uid2sid mapping
* @param[in] uid the uid to map
bool idmap_cache_find_uid2sid(uid_t uid, struct dom_sid *sid, bool *expired)
{
- char *key;
- char *value;
- time_t timeout;
- bool ret = true;
+ fstring key;
+ struct idmap_cache_xid2sid_state state;
- key = talloc_asprintf(talloc_tos(), "IDMAP/UID2SID/%d", (int)uid);
- if (key == NULL) {
- return false;
- }
- ret = gencache_get(key, &value, &timeout);
- TALLOC_FREE(key);
- if (!ret) {
- return false;
- }
- ZERO_STRUCTP(sid);
- if (value[0] != '-') {
- ret = string_to_sid(sid, value);
- }
- SAFE_FREE(value);
- if (ret) {
- *expired = (timeout <= time(NULL));
- }
- return ret;
+ fstr_sprintf(key, "IDMAP/UID2SID/%d", (int)uid);
+
+ state.sid = sid;
+ state.expired = expired;
+ state.ret = false;
+
+ gencache_parse(key, idmap_cache_xid2sid_parser, &state);
+ return state.ret;
}
/**
bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired)
{
- char *key;
- char *value;
- time_t timeout;
- bool ret = true;
+ fstring key;
+ struct idmap_cache_xid2sid_state state;
- key = talloc_asprintf(talloc_tos(), "IDMAP/GID2SID/%d", (int)gid);
- if (key == NULL) {
- return false;
- }
- ret = gencache_get(key, &value, &timeout);
- TALLOC_FREE(key);
- if (!ret) {
- return false;
- }
- ZERO_STRUCTP(sid);
- if (value[0] != '-') {
- ret = string_to_sid(sid, value);
- }
- SAFE_FREE(value);
- if (ret) {
- *expired = (timeout <= time(NULL));
- }
- return ret;
+ fstr_sprintf(key, "IDMAP/GID2SID/%d", (int)gid);
+
+ state.sid = sid;
+ state.expired = expired;
+ state.ret = false;
+
+ gencache_parse(key, idmap_cache_xid2sid_parser, &state);
+ return state.ret;
}
/**
case ID_TYPE_BOTH:
fstr_sprintf(value, "%d:B", (int)unix_id->id);
break;
+ case ID_TYPE_NOT_SPECIFIED:
+ fstr_sprintf(value, "%d:N", (int)unix_id->id);
+ break;
default:
return;
}
}
}
-/**
- * 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);
}
time_t timeout;
bool ret = true;
- if (!gencache_get(key, &sid_str, &timeout)) {
+ if (!gencache_get(key, mem_ctx, &sid_str, &timeout)) {
DEBUG(3, ("no entry: %s\n", key));
ret = false;
goto done;