2 Unix SMB/CIFS implementation.
4 Copyright (C) Tim Potter 2000
5 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
6 Copyright (C) Simo Sorce 2003
7 Copyright (C) Jeremy Allison 2003.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/
26 #define DBGC_CLASS DBGC_IDMAP
28 struct idmap_function_entry
{
30 struct idmap_methods
*methods
;
31 struct idmap_function_entry
*prev
,*next
;
34 static struct idmap_function_entry
*backends
= NULL
;
36 static struct idmap_methods
*cache_map
;
37 static struct idmap_methods
*remote_map
;
39 static BOOL proxyonly
= False
;
41 /**********************************************************************
42 Get idmap methods. Don't allow tdb to be a remote method.
43 **********************************************************************/
45 static struct idmap_methods
*get_methods(const char *name
, BOOL cache_method
)
47 struct idmap_function_entry
*entry
= backends
;
49 for(entry
= backends
; entry
; entry
= entry
->next
) {
50 if (!cache_method
&& strequal(entry
->name
, "tdb"))
51 continue; /* tdb is only cache method. */
52 if (strequal(entry
->name
, name
))
53 return entry
->methods
;
59 /**********************************************************************
60 Allow a module to register itself as a method.
61 **********************************************************************/
63 NTSTATUS
smb_register_idmap(int version
, const char *name
, struct idmap_methods
*methods
)
65 struct idmap_function_entry
*entry
;
67 if ((version
!= SMB_IDMAP_INTERFACE_VERSION
)) {
68 DEBUG(0, ("smb_register_idmap: Failed to register idmap module.\n"
69 "The module was compiled against SMB_IDMAP_INTERFACE_VERSION %d,\n"
70 "current SMB_IDMAP_INTERFACE_VERSION is %d.\n"
71 "Please recompile against the current version of samba!\n",
72 version
, SMB_IDMAP_INTERFACE_VERSION
));
73 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
76 if (!name
|| !name
[0] || !methods
) {
77 DEBUG(0,("smb_register_idmap: called with NULL pointer or empty name!\n"));
78 return NT_STATUS_INVALID_PARAMETER
;
81 if (get_methods(name
, False
)) {
82 DEBUG(0,("smb_register_idmap: idmap module %s already registered!\n", name
));
83 return NT_STATUS_OBJECT_NAME_COLLISION
;
86 entry
= smb_xmalloc(sizeof(struct idmap_function_entry
));
87 entry
->name
= smb_xstrdup(name
);
88 entry
->methods
= methods
;
90 DLIST_ADD(backends
, entry
);
91 DEBUG(5, ("smb_register_idmap: Successfully added idmap backend '%s'\n", name
));
95 /**********************************************************************
96 Initialise idmap cache and a remote backend (if configured).
97 **********************************************************************/
99 BOOL
idmap_init(const char *remote_backend
)
105 cache_map
= get_methods("tdb", True
);
108 DEBUG(0, ("idmap_init: could not find tdb cache backend!\n"));
112 if (!NT_STATUS_IS_OK(cache_map
->init( NULL
))) {
113 DEBUG(0, ("idmap_init: could not initialise tdb cache backend!\n"));
118 if (!remote_map
&& remote_backend
&& *remote_backend
!= 0) {
119 char *rem_backend
= smb_xstrdup(remote_backend
);
123 /* get any mode parameters passed in */
125 if ( (pparams
= strchr( rem_backend
, ':' )) != NULL
) {
128 fstrcpy( params
, pparams
);
131 DEBUG(3, ("idmap_init: using '%s' as remote backend\n", rem_backend
));
133 if((remote_map
= get_methods(rem_backend
, False
)) ||
134 (NT_STATUS_IS_OK(smb_probe_module("idmap", rem_backend
)) &&
135 (remote_map
= get_methods(rem_backend
, False
)))) {
136 remote_map
->init(params
);
138 DEBUG(0, ("idmap_init: could not load remote backend '%s'\n", rem_backend
));
139 SAFE_FREE(rem_backend
);
142 SAFE_FREE(rem_backend
);
148 /**************************************************************************
149 Don't do id mapping. This is used to make winbind a netlogon proxy only.
150 **************************************************************************/
152 void idmap_proxyonly(void)
157 /**************************************************************************
158 This is a rare operation, designed to allow an explicit mapping to be
159 set up for a sid to a POSIX id.
160 **************************************************************************/
162 NTSTATUS
idmap_set_mapping(const DOM_SID
*sid
, unid_t id
, int id_type
)
164 struct idmap_methods
*map
= remote_map
;
168 return NT_STATUS_UNSUCCESSFUL
;
170 DEBUG(10, ("idmap_set_mapping: Set %s to %s %lu\n",
171 sid_string_static(sid
),
172 ((id_type
& ID_TYPEMASK
) == ID_USERID
) ? "UID" : "GID",
173 ((id_type
& ID_TYPEMASK
) == ID_USERID
) ? (unsigned long)id
.uid
:
174 (unsigned long)id
.gid
));
176 if ( (NT_STATUS_IS_OK(cache_map
->
177 get_sid_from_id(&tmp_sid
, id
,
178 id_type
| ID_QUERY_ONLY
))) &&
179 sid_equal(sid
, &tmp_sid
) ) {
180 /* Nothing to do, we already have that mapping */
181 DEBUG(10, ("idmap_set_mapping: Mapping already there\n"));
186 /* Ok, we don't have a authoritative remote
187 mapping. So update our local cache only. */
191 return map
->set_mapping(sid
, id
, id_type
);
194 /**************************************************************************
195 Get ID from SID. This can create a mapping for a SID to a POSIX id.
196 **************************************************************************/
198 NTSTATUS
idmap_get_id_from_sid(unid_t
*id
, int *id_type
, const DOM_SID
*sid
)
204 return NT_STATUS_UNSUCCESSFUL
;
209 /* We have a central remote idmap so only look in
210 cache, don't allocate */
211 loc_type
|= ID_QUERY_ONLY
;
214 ret
= cache_map
->get_id_from_sid(id
, &loc_type
, sid
);
216 if (NT_STATUS_IS_OK(ret
)) {
217 *id_type
= loc_type
& ID_TYPEMASK
;
221 if (remote_map
== NULL
) {
225 /* Ok, the mapping was not in the cache, give the remote map a
228 ret
= remote_map
->get_id_from_sid(id
, id_type
, sid
);
230 if (NT_STATUS_IS_OK(ret
)) {
231 /* The remote backend gave us a valid mapping, cache it. */
232 ret
= cache_map
->set_mapping(sid
, *id
, *id_type
);
238 /**************************************************************************
239 Get SID from ID. This must have been created before.
240 **************************************************************************/
242 NTSTATUS
idmap_get_sid_from_id(DOM_SID
*sid
, unid_t id
, int id_type
)
248 return NT_STATUS_UNSUCCESSFUL
;
252 loc_type
= id_type
| ID_QUERY_ONLY
;
255 ret
= cache_map
->get_sid_from_id(sid
, id
, loc_type
);
257 if (NT_STATUS_IS_OK(ret
))
260 if (remote_map
== NULL
)
263 /* We have a second chance, ask our authoritative backend */
265 ret
= remote_map
->get_sid_from_id(sid
, id
, id_type
);
267 if (NT_STATUS_IS_OK(ret
)) {
268 /* The remote backend gave us a valid mapping, cache it. */
269 ret
= cache_map
->set_mapping(sid
, id
, id_type
);
275 /**************************************************************************
276 Alloocate a new UNIX uid/gid
277 **************************************************************************/
279 NTSTATUS
idmap_allocate_id(unid_t
*id
, int id_type
)
281 /* we have to allocate from the authoritative backend */
284 return NT_STATUS_UNSUCCESSFUL
;
287 return remote_map
->allocate_id( id
, id_type
);
289 return cache_map
->allocate_id( id
, id_type
);
292 /**************************************************************************
294 **************************************************************************/
296 NTSTATUS
idmap_allocate_rid(uint32
*rid
, int type
)
298 /* we have to allocate from the authoritative backend */
301 return NT_STATUS_UNSUCCESSFUL
;
304 return remote_map
->allocate_rid( rid
, type
);
306 return cache_map
->allocate_rid( rid
, type
);
309 /**************************************************************************
311 **************************************************************************/
313 NTSTATUS
idmap_close(void)
320 ret
= cache_map
->close();
321 if (!NT_STATUS_IS_OK(ret
)) {
322 DEBUG(3, ("idmap_close: failed to close local tdb cache!\n"));
327 ret
= remote_map
->close();
328 if (!NT_STATUS_IS_OK(ret
)) {
329 DEBUG(3, ("idmap_close: failed to close remote idmap repository!\n"));
337 /**************************************************************************
339 **************************************************************************/
341 void idmap_status(void)
345 remote_map
->status();