PageRenderTime 28ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/samba-3.5.6/source3/lib/idmap_cache.c

https://github.com/theuni/XBMC-deps
C | 260 lines | 163 code | 19 blank | 78 comment | 34 complexity | f499159dd2d1a0109d2939c4a06ec251 MD5 | raw file
  1. /*
  2. Unix SMB/CIFS implementation.
  3. ID Mapping Cache
  4. Copyright (C) Volker Lendecke 2008
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.*/
  15. #include "includes.h"
  16. /**
  17. * Find a sid2uid mapping
  18. * @param[in] sid the sid to map
  19. * @param[out] puid where to put the result
  20. * @param[out] expired is the cache entry expired?
  21. * @retval Was anything in the cache at all?
  22. *
  23. * If *puid == -1 this was a negative mapping.
  24. */
  25. bool idmap_cache_find_sid2uid(const struct dom_sid *sid, uid_t *puid,
  26. bool *expired)
  27. {
  28. fstring sidstr;
  29. char *key;
  30. char *value;
  31. char *endptr;
  32. time_t timeout;
  33. uid_t uid;
  34. bool ret;
  35. key = talloc_asprintf(talloc_tos(), "IDMAP/SID2UID/%s",
  36. sid_to_fstring(sidstr, sid));
  37. if (key == NULL) {
  38. return false;
  39. }
  40. ret = gencache_get(key, &value, &timeout);
  41. TALLOC_FREE(key);
  42. if (!ret) {
  43. return false;
  44. }
  45. uid = strtol(value, &endptr, 10);
  46. ret = (*endptr == '\0');
  47. SAFE_FREE(value);
  48. if (ret) {
  49. *puid = uid;
  50. *expired = (timeout <= time(NULL));
  51. }
  52. return ret;
  53. }
  54. /**
  55. * Find a uid2sid mapping
  56. * @param[in] uid the uid to map
  57. * @param[out] sid where to put the result
  58. * @param[out] expired is the cache entry expired?
  59. * @retval Was anything in the cache at all?
  60. *
  61. * If "is_null_sid(sid)", this was a negative mapping.
  62. */
  63. bool idmap_cache_find_uid2sid(uid_t uid, struct dom_sid *sid, bool *expired)
  64. {
  65. char *key;
  66. char *value;
  67. time_t timeout;
  68. bool ret = true;
  69. key = talloc_asprintf(talloc_tos(), "IDMAP/UID2SID/%d", (int)uid);
  70. if (key == NULL) {
  71. return false;
  72. }
  73. ret = gencache_get(key, &value, &timeout);
  74. TALLOC_FREE(key);
  75. if (!ret) {
  76. return false;
  77. }
  78. ZERO_STRUCTP(sid);
  79. if (value[0] != '-') {
  80. ret = string_to_sid(sid, value);
  81. }
  82. SAFE_FREE(value);
  83. if (ret) {
  84. *expired = (timeout <= time(NULL));
  85. }
  86. return ret;
  87. }
  88. /**
  89. * Store a mapping in the idmap cache
  90. * @param[in] sid the sid to map
  91. * @param[in] uid the uid to map
  92. *
  93. * If both parameters are valid values, then a positive mapping in both
  94. * directions is stored. If "is_null_sid(sid)" is true, then this will be a
  95. * negative mapping of uid, we want to cache that for this uid we could not
  96. * find anything. Likewise if "uid==-1", then we want to cache that we did not
  97. * find a mapping for the sid passed here.
  98. */
  99. void idmap_cache_set_sid2uid(const struct dom_sid *sid, uid_t uid)
  100. {
  101. time_t now = time(NULL);
  102. time_t timeout;
  103. fstring sidstr, key, value;
  104. if (!is_null_sid(sid)) {
  105. fstr_sprintf(key, "IDMAP/SID2UID/%s",
  106. sid_to_fstring(sidstr, sid));
  107. fstr_sprintf(value, "%d", (int)uid);
  108. timeout = (uid == -1)
  109. ? lp_idmap_negative_cache_time()
  110. : lp_idmap_cache_time();
  111. gencache_set(key, value, now + timeout);
  112. }
  113. if (uid != -1) {
  114. fstr_sprintf(key, "IDMAP/UID2SID/%d", (int)uid);
  115. if (is_null_sid(sid)) {
  116. /* negative uid mapping */
  117. fstrcpy(value, "-");
  118. timeout = lp_idmap_negative_cache_time();
  119. }
  120. else {
  121. sid_to_fstring(value, sid);
  122. timeout = lp_idmap_cache_time();
  123. }
  124. gencache_set(key, value, now + timeout);
  125. }
  126. }
  127. /**
  128. * Find a sid2gid mapping
  129. * @param[in] sid the sid to map
  130. * @param[out] pgid where to put the result
  131. * @param[out] expired is the cache entry expired?
  132. * @retval Was anything in the cache at all?
  133. *
  134. * If *pgid == -1 this was a negative mapping.
  135. */
  136. bool idmap_cache_find_sid2gid(const struct dom_sid *sid, gid_t *pgid,
  137. bool *expired)
  138. {
  139. fstring sidstr;
  140. char *key;
  141. char *value;
  142. char *endptr;
  143. time_t timeout;
  144. gid_t gid;
  145. bool ret;
  146. key = talloc_asprintf(talloc_tos(), "IDMAP/SID2GID/%s",
  147. sid_to_fstring(sidstr, sid));
  148. if (key == NULL) {
  149. return false;
  150. }
  151. ret = gencache_get(key, &value, &timeout);
  152. TALLOC_FREE(key);
  153. if (!ret) {
  154. return false;
  155. }
  156. gid = strtol(value, &endptr, 10);
  157. ret = (*endptr == '\0');
  158. SAFE_FREE(value);
  159. if (ret) {
  160. *pgid = gid;
  161. *expired = (timeout <= time(NULL));
  162. }
  163. return ret;
  164. }
  165. /**
  166. * Find a gid2sid mapping
  167. * @param[in] gid the gid to map
  168. * @param[out] sid where to put the result
  169. * @param[out] expired is the cache entry expired?
  170. * @retval Was anything in the cache at all?
  171. *
  172. * If "is_null_sid(sid)", this was a negative mapping.
  173. */
  174. bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired)
  175. {
  176. char *key;
  177. char *value;
  178. time_t timeout;
  179. bool ret = true;
  180. key = talloc_asprintf(talloc_tos(), "IDMAP/GID2SID/%d", (int)gid);
  181. if (key == NULL) {
  182. return false;
  183. }
  184. ret = gencache_get(key, &value, &timeout);
  185. TALLOC_FREE(key);
  186. if (!ret) {
  187. return false;
  188. }
  189. ZERO_STRUCTP(sid);
  190. if (value[0] != '-') {
  191. ret = string_to_sid(sid, value);
  192. }
  193. SAFE_FREE(value);
  194. if (ret) {
  195. *expired = (timeout <= time(NULL));
  196. }
  197. return ret;
  198. }
  199. /**
  200. * Store a mapping in the idmap cache
  201. * @param[in] sid the sid to map
  202. * @param[in] gid the gid to map
  203. *
  204. * If both parameters are valid values, then a positive mapping in both
  205. * directions is stored. If "is_null_sid(sid)" is true, then this will be a
  206. * negative mapping of gid, we want to cache that for this gid we could not
  207. * find anything. Likewise if "gid==-1", then we want to cache that we did not
  208. * find a mapping for the sid passed here.
  209. */
  210. void idmap_cache_set_sid2gid(const struct dom_sid *sid, gid_t gid)
  211. {
  212. time_t now = time(NULL);
  213. time_t timeout;
  214. fstring sidstr, key, value;
  215. if (!is_null_sid(sid)) {
  216. fstr_sprintf(key, "IDMAP/SID2GID/%s",
  217. sid_to_fstring(sidstr, sid));
  218. fstr_sprintf(value, "%d", (int)gid);
  219. timeout = (gid == -1)
  220. ? lp_idmap_negative_cache_time()
  221. : lp_idmap_cache_time();
  222. gencache_set(key, value, now + timeout);
  223. }
  224. if (gid != -1) {
  225. fstr_sprintf(key, "IDMAP/GID2SID/%d", (int)gid);
  226. if (is_null_sid(sid)) {
  227. /* negative gid mapping */
  228. fstrcpy(value, "-");
  229. timeout = lp_idmap_negative_cache_time();
  230. }
  231. else {
  232. sid_to_fstring(value, sid);
  233. timeout = lp_idmap_cache_time();
  234. }
  235. gencache_set(key, value, now + timeout);
  236. }
  237. }