s3-krb5: Fix Coverity #722 (RESOURCE_LEAK).
[Samba/gbeck.git] / source3 / lib / idmap_cache.c
blob6377635a6563b3c7088e5743aadaa8660d1ac6ba
1 /*
2 Unix SMB/CIFS implementation.
3 ID Mapping Cache
5 Copyright (C) Volker Lendecke 2008
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.*/
20 #include "includes.h"
22 /**
23 * Find a sid2uid mapping
24 * @param[in] sid the sid to map
25 * @param[out] puid where to put the result
26 * @param[out] expired is the cache entry expired?
27 * @retval Was anything in the cache at all?
29 * If *puid == -1 this was a negative mapping.
32 bool idmap_cache_find_sid2uid(const struct dom_sid *sid, uid_t *puid,
33 bool *expired)
35 fstring sidstr;
36 char *key;
37 char *value;
38 char *endptr;
39 time_t timeout;
40 uid_t uid;
41 bool ret;
43 key = talloc_asprintf(talloc_tos(), "IDMAP/SID2UID/%s",
44 sid_to_fstring(sidstr, sid));
45 if (key == NULL) {
46 return false;
48 ret = gencache_get(key, &value, &timeout);
49 TALLOC_FREE(key);
50 if (!ret) {
51 return false;
53 uid = strtol(value, &endptr, 10);
54 ret = (*endptr == '\0');
55 SAFE_FREE(value);
56 if (ret) {
57 *puid = uid;
58 *expired = (timeout <= time(NULL));
60 return ret;
63 /**
64 * Find a uid2sid mapping
65 * @param[in] uid the uid to map
66 * @param[out] sid where to put the result
67 * @param[out] expired is the cache entry expired?
68 * @retval Was anything in the cache at all?
70 * If "is_null_sid(sid)", this was a negative mapping.
73 bool idmap_cache_find_uid2sid(uid_t uid, struct dom_sid *sid, bool *expired)
75 char *key;
76 char *value;
77 time_t timeout;
78 bool ret = true;
80 key = talloc_asprintf(talloc_tos(), "IDMAP/UID2SID/%d", (int)uid);
81 if (key == NULL) {
82 return false;
84 ret = gencache_get(key, &value, &timeout);
85 TALLOC_FREE(key);
86 if (!ret) {
87 return false;
89 ZERO_STRUCTP(sid);
90 if (value[0] != '-') {
91 ret = string_to_sid(sid, value);
93 SAFE_FREE(value);
94 if (ret) {
95 *expired = (timeout <= time(NULL));
97 return ret;
101 * Store a mapping in the idmap cache
102 * @param[in] sid the sid to map
103 * @param[in] uid the uid to map
105 * If both parameters are valid values, then a positive mapping in both
106 * directions is stored. If "is_null_sid(sid)" is true, then this will be a
107 * negative mapping of uid, we want to cache that for this uid we could not
108 * find anything. Likewise if "uid==-1", then we want to cache that we did not
109 * find a mapping for the sid passed here.
112 void idmap_cache_set_sid2uid(const struct dom_sid *sid, uid_t uid)
114 time_t now = time(NULL);
115 time_t timeout;
116 fstring sidstr, key, value;
118 if (!is_null_sid(sid)) {
119 fstr_sprintf(key, "IDMAP/SID2UID/%s",
120 sid_to_fstring(sidstr, sid));
121 fstr_sprintf(value, "%d", (int)uid);
122 timeout = (uid == -1)
123 ? lp_idmap_negative_cache_time()
124 : lp_idmap_cache_time();
125 gencache_set(key, value, now + timeout);
127 if (uid != -1) {
128 fstr_sprintf(key, "IDMAP/UID2SID/%d", (int)uid);
129 if (is_null_sid(sid)) {
130 /* negative uid mapping */
131 fstrcpy(value, "-");
132 timeout = lp_idmap_negative_cache_time();
134 else {
135 sid_to_fstring(value, sid);
136 timeout = lp_idmap_cache_time();
138 gencache_set(key, value, now + timeout);
143 * Find a sid2gid mapping
144 * @param[in] sid the sid to map
145 * @param[out] pgid where to put the result
146 * @param[out] expired is the cache entry expired?
147 * @retval Was anything in the cache at all?
149 * If *pgid == -1 this was a negative mapping.
152 bool idmap_cache_find_sid2gid(const struct dom_sid *sid, gid_t *pgid,
153 bool *expired)
155 fstring sidstr;
156 char *key;
157 char *value;
158 char *endptr;
159 time_t timeout;
160 gid_t gid;
161 bool ret;
163 key = talloc_asprintf(talloc_tos(), "IDMAP/SID2GID/%s",
164 sid_to_fstring(sidstr, sid));
165 if (key == NULL) {
166 return false;
168 ret = gencache_get(key, &value, &timeout);
169 TALLOC_FREE(key);
170 if (!ret) {
171 return false;
173 gid = strtol(value, &endptr, 10);
174 ret = (*endptr == '\0');
175 SAFE_FREE(value);
176 if (ret) {
177 *pgid = gid;
178 *expired = (timeout <= time(NULL));
180 return ret;
184 * Find a gid2sid mapping
185 * @param[in] gid the gid to map
186 * @param[out] sid where to put the result
187 * @param[out] expired is the cache entry expired?
188 * @retval Was anything in the cache at all?
190 * If "is_null_sid(sid)", this was a negative mapping.
193 bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired)
195 char *key;
196 char *value;
197 time_t timeout;
198 bool ret = true;
200 key = talloc_asprintf(talloc_tos(), "IDMAP/GID2SID/%d", (int)gid);
201 if (key == NULL) {
202 return false;
204 ret = gencache_get(key, &value, &timeout);
205 TALLOC_FREE(key);
206 if (!ret) {
207 return false;
209 ZERO_STRUCTP(sid);
210 if (value[0] != '-') {
211 ret = string_to_sid(sid, value);
213 SAFE_FREE(value);
214 if (ret) {
215 *expired = (timeout <= time(NULL));
217 return ret;
221 * Store a mapping in the idmap cache
222 * @param[in] sid the sid to map
223 * @param[in] gid the gid to map
225 * If both parameters are valid values, then a positive mapping in both
226 * directions is stored. If "is_null_sid(sid)" is true, then this will be a
227 * negative mapping of gid, we want to cache that for this gid we could not
228 * find anything. Likewise if "gid==-1", then we want to cache that we did not
229 * find a mapping for the sid passed here.
232 void idmap_cache_set_sid2gid(const struct dom_sid *sid, gid_t gid)
234 time_t now = time(NULL);
235 time_t timeout;
236 fstring sidstr, key, value;
238 if (!is_null_sid(sid)) {
239 fstr_sprintf(key, "IDMAP/SID2GID/%s",
240 sid_to_fstring(sidstr, sid));
241 fstr_sprintf(value, "%d", (int)gid);
242 timeout = (gid == -1)
243 ? lp_idmap_negative_cache_time()
244 : lp_idmap_cache_time();
245 gencache_set(key, value, now + timeout);
247 if (gid != -1) {
248 fstr_sprintf(key, "IDMAP/GID2SID/%d", (int)gid);
249 if (is_null_sid(sid)) {
250 /* negative gid mapping */
251 fstrcpy(value, "-");
252 timeout = lp_idmap_negative_cache_time();
254 else {
255 sid_to_fstring(value, sid);
256 timeout = lp_idmap_cache_time();
258 gencache_set(key, value, now + timeout);