WHATSNEW: add more items.
[Samba.git] / source / winbindd / idmap_util.c
blob9f876618be97aef0aa6c3ed07a0f9039e8120a5d
1 /*
2 Unix SMB/CIFS implementation.
3 ID Mapping
4 Copyright (C) Simo Sorce 2003
5 Copyright (C) Jeremy Allison 2006
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 #undef DBGC_CLASS
23 #define DBGC_CLASS DBGC_IDMAP
25 /*****************************************************************
26 Returns the SID mapped to the given UID.
27 If mapping is not possible returns an error.
28 *****************************************************************/
30 NTSTATUS idmap_uid_to_sid(const char *domname, DOM_SID *sid, uid_t uid)
32 NTSTATUS ret;
33 struct id_map map;
34 bool expired;
36 DEBUG(10,("uid = [%lu]\n", (unsigned long)uid));
38 if (idmap_cache_find_uid2sid(uid, sid, &expired)) {
39 DEBUG(10, ("idmap_cache_find_uid2sid found %d%s\n", uid,
40 expired ? " (expired)": ""));
41 if (expired && idmap_is_online()) {
42 DEBUG(10, ("revalidating expired entry\n"));
43 goto backend;
45 if (is_null_sid(sid)) {
46 DEBUG(10, ("Returning negative cache entry\n"));
47 return NT_STATUS_NONE_MAPPED;
49 DEBUG(10, ("Returning positive cache entry\n"));
50 return NT_STATUS_OK;
53 backend:
54 map.sid = sid;
55 map.xid.type = ID_TYPE_UID;
56 map.xid.id = uid;
58 ret = idmap_backends_unixid_to_sid(domname, &map);
59 if ( ! NT_STATUS_IS_OK(ret)) {
60 DEBUG(10, ("error mapping uid [%lu]\n", (unsigned long)uid));
61 return ret;
64 if (map.status != ID_MAPPED) {
65 struct dom_sid null_sid;
66 ZERO_STRUCT(null_sid);
67 idmap_cache_set_sid2uid(&null_sid, uid);
68 DEBUG(10, ("uid [%lu] not mapped\n", (unsigned long)uid));
69 return NT_STATUS_NONE_MAPPED;
72 idmap_cache_set_sid2uid(sid, uid);
74 return NT_STATUS_OK;
77 /*****************************************************************
78 Returns SID mapped to the given GID.
79 If mapping is not possible returns an error.
80 *****************************************************************/
82 NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid)
84 NTSTATUS ret;
85 struct id_map map;
86 bool expired;
88 DEBUG(10,("gid = [%lu]\n", (unsigned long)gid));
90 if (idmap_cache_find_gid2sid(gid, sid, &expired)) {
91 DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n", gid,
92 expired ? " (expired)": ""));
93 if (expired && idmap_is_online()) {
94 DEBUG(10, ("revalidating expired entry\n"));
95 goto backend;
97 if (is_null_sid(sid)) {
98 DEBUG(10, ("Returning negative cache entry\n"));
99 return NT_STATUS_NONE_MAPPED;
101 DEBUG(10, ("Returning positive cache entry\n"));
102 return NT_STATUS_OK;
105 backend:
106 map.sid = sid;
107 map.xid.type = ID_TYPE_GID;
108 map.xid.id = gid;
110 ret = idmap_backends_unixid_to_sid(domname, &map);
111 if ( ! NT_STATUS_IS_OK(ret)) {
112 DEBUG(10, ("error mapping gid [%lu]\n", (unsigned long)gid));
113 return ret;
116 if (map.status != ID_MAPPED) {
117 struct dom_sid null_sid;
118 ZERO_STRUCT(null_sid);
119 idmap_cache_set_sid2uid(&null_sid, gid);
120 DEBUG(10, ("gid [%lu] not mapped\n", (unsigned long)gid));
121 return NT_STATUS_NONE_MAPPED;
124 idmap_cache_set_sid2gid(sid, gid);
126 return NT_STATUS_OK;
129 /*****************************************************************
130 Returns the UID mapped to the given SID.
131 If mapping is not possible or SID maps to a GID returns an error.
132 *****************************************************************/
134 NTSTATUS idmap_sid_to_uid(const char *dom_name, DOM_SID *sid, uid_t *uid)
136 NTSTATUS ret;
137 struct id_map map;
138 bool expired;
140 DEBUG(10,("idmap_sid_to_uid: sid = [%s]\n", sid_string_dbg(sid)));
142 if (idmap_cache_find_sid2uid(sid, uid, &expired)) {
143 DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n",
144 (int)(*uid), expired ? " (expired)": ""));
145 if (expired && idmap_is_online()) {
146 DEBUG(10, ("revalidating expired entry\n"));
147 goto backend;
149 if ((*uid) == -1) {
150 DEBUG(10, ("Returning negative cache entry\n"));
151 return NT_STATUS_NONE_MAPPED;
153 DEBUG(10, ("Returning positive cache entry\n"));
154 return NT_STATUS_OK;
157 backend:
158 map.sid = sid;
159 map.xid.type = ID_TYPE_UID;
161 ret = idmap_backends_sid_to_unixid(dom_name, &map);
163 if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) {
164 if (map.xid.type != ID_TYPE_UID) {
165 DEBUG(10, ("sid [%s] not mapped to a uid "
166 "[%u,%u,%u]\n",
167 sid_string_dbg(sid),
168 map.status,
169 map.xid.type,
170 map.xid.id));
171 idmap_cache_set_sid2uid(sid, -1);
172 return NT_STATUS_NONE_MAPPED;
174 goto done;
177 if (dom_name[0] != '\0') {
179 * We had the task to go to a specific domain which
180 * could not answer our request. Fail.
182 idmap_cache_set_sid2uid(sid, -1);
183 return NT_STATUS_NONE_MAPPED;
186 ret = idmap_new_mapping(sid, ID_TYPE_UID, &map.xid);
188 if (!NT_STATUS_IS_OK(ret)) {
189 DEBUG(10, ("idmap_new_mapping failed: %s\n",
190 nt_errstr(ret)));
191 idmap_cache_set_sid2uid(sid, -1);
192 return ret;
195 done:
196 *uid = (uid_t)map.xid.id;
197 idmap_cache_set_sid2uid(sid, *uid);
198 return NT_STATUS_OK;
201 /*****************************************************************
202 Returns the GID mapped to the given SID.
203 If mapping is not possible or SID maps to a UID returns an error.
204 *****************************************************************/
206 NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid)
208 NTSTATUS ret;
209 struct id_map map;
210 bool expired;
212 DEBUG(10,("idmap_sid_to_gid: sid = [%s]\n", sid_string_dbg(sid)));
214 if (idmap_cache_find_sid2gid(sid, gid, &expired)) {
215 DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n",
216 (int)(*gid), expired ? " (expired)": ""));
217 if (expired && idmap_is_online()) {
218 DEBUG(10, ("revalidating expired entry\n"));
219 goto backend;
221 if ((*gid) == -1) {
222 DEBUG(10, ("Returning negative cache entry\n"));
223 return NT_STATUS_NONE_MAPPED;
225 DEBUG(10, ("Returning positive cache entry\n"));
226 return NT_STATUS_OK;
229 backend:
230 map.sid = sid;
231 map.xid.type = ID_TYPE_GID;
233 ret = idmap_backends_sid_to_unixid(domname, &map);
234 if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) {
235 if (map.xid.type != ID_TYPE_GID) {
236 DEBUG(10, ("sid [%s] not mapped to a gid "
237 "[%u,%u,%u]\n",
238 sid_string_dbg(sid),
239 map.status,
240 map.xid.type,
241 map.xid.id));
242 idmap_cache_set_sid2gid(sid, -1);
243 return NT_STATUS_NONE_MAPPED;
245 goto done;
248 if (domname[0] != '\0') {
250 * We had the task to go to a specific domain which
251 * could not answer our request. Fail.
253 idmap_cache_set_sid2uid(sid, -1);
254 return NT_STATUS_NONE_MAPPED;
257 ret = idmap_new_mapping(sid, ID_TYPE_GID, &map.xid);
259 if (!NT_STATUS_IS_OK(ret)) {
260 DEBUG(10, ("idmap_new_mapping failed: %s\n",
261 nt_errstr(ret)));
262 idmap_cache_set_sid2gid(sid, -1);
263 return ret;
266 done:
267 *gid = map.xid.id;
268 idmap_cache_set_sid2gid(sid, *gid);
269 return NT_STATUS_OK;