summaryrefslogtreecommitdiff
path: root/source3/sam/idmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/sam/idmap.c')
-rw-r--r--source3/sam/idmap.c134
1 files changed, 100 insertions, 34 deletions
diff --git a/source3/sam/idmap.c b/source3/sam/idmap.c
index 96638b4723..b18423a13b 100644
--- a/source3/sam/idmap.c
+++ b/source3/sam/idmap.c
@@ -21,7 +21,6 @@
*/
#include "includes.h"
-#include "idmap.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_IDMAP
@@ -32,48 +31,58 @@ static struct {
/* Function to create a member of the idmap_methods list */
NTSTATUS (*reg_meth)(struct idmap_methods **methods);
struct idmap_methods *methods;
-} builtin_idmap_functions[] = {
+
+} remote_idmap_functions[] = {
+
{ "tdb", idmap_reg_tdb, NULL },
/* { "ldap", idmap_reg_ldap, NULL },*/
{ NULL, NULL, NULL }
+
};
-/* singleton pattern: uberlazy evaluation */
-static struct idmap_methods *impl;
+static struct idmap_methods *local_cache;
+static struct idmap_methods *remote_repo;
-static struct idmap_methods *get_impl(const char *name)
+static struct idmap_methods *get_methods(const char *name)
{
int i = 0;
struct idmap_methods *ret = NULL;
- while (builtin_idmap_functions[i].name && strcmp(builtin_idmap_functions[i].name, name)) {
+ while (remote_idmap_functions[i].name && strcmp(remote_idmap_functions[i].name, name)) {
i++;
}
- if (builtin_idmap_functions[i].name) {
+ if (remote_idmap_functions[i].name) {
- if (!builtin_idmap_functions[i].methods) {
- builtin_idmap_functions[i].reg_meth(&builtin_idmap_functions[i].methods);
+ if (!remote_idmap_functions[i].methods) {
+ remote_idmap_functions[i].reg_meth(&remote_idmap_functions[i].methods);
}
- ret = builtin_idmap_functions[i].methods;
+ ret = remote_idmap_functions[i].methods;
}
return ret;
}
/* Load idmap backend functions */
-BOOL set_impl(void)
+BOOL load_methods(void)
{
- if (!impl) {
- DEBUG(3, ("idmap_init: using '%s' as backend\n", lp_idmap_backend()));
+ if (!local_cache) {
+ idmap_reg_tdb(&local_cache);
+ }
+
+ if (!remote_repo && lp_idmap_backend()) {
+ DEBUG(3, ("load_methods: using '%s' as remote backend\n", lp_idmap_backend()));
- impl = get_impl(lp_idmap_backend());
- if (!impl) {
- DEBUG(0, ("set_impl: could not load backend '%s'\n", lp_idmap_backend()));
+ remote_repo = get_methods(lp_idmap_backend());
+ if (!remote_repo) {
+ DEBUG(0, ("load_methods: could not load remote backend '%s'\n", lp_idmap_backend()));
return False;
}
}
+
+ idmap_init();
+
return True;
}
@@ -82,9 +91,7 @@ NTSTATUS idmap_init(void)
{
NTSTATUS ret;
- if (!set_impl()) return NT_STATUS_UNSUCCESSFUL;
-
- ret = impl->init();
+ ret = remote_repo->init("idmap.tdb");
if (NT_STATUS_IS_ERR(ret)) {
DEBUG(3, ("idmap_init: init failed!\n"));
}
@@ -92,47 +99,105 @@ NTSTATUS idmap_init(void)
return ret;
}
+static NTSTATUS idmap_set_mapping(DOM_SID *sid, unid_t id, int id_type)
+{
+ NTSTATUS ret;
+
+ if (!load_methods()) return NT_STATUS_UNSUCCESSFUL;
+
+ ret = local_cache->set_mapping(sid, id, id_type);
+ if (NT_STATUS_IS_ERR(ret)) {
+ DEBUG (0, ("idmap_set_mapping: Error, unable to modify local cache!\n"));
+ return ret;
+ }
+
+ /* Being able to update the remote cache is seldomly right.
+ Generally this is a forbidden operation. */
+ if (!(id_type & ID_CACHE) && (remote_repo != NULL)) {
+ remote_repo->set_mapping(sid, id, id_type);
+ if (NT_STATUS_IS_ERR(ret)) {
+ DEBUG (0, ("idmap_set_mapping: Error, unable to modify remote cache!\n"));
+ }
+ }
+
+ return ret;
+}
+
/* Get ID from SID */
-NTSTATUS idmap_get_id_from_sid(id_t *id, int *id_type, DOM_SID *sid)
+NTSTATUS idmap_get_id_from_sid(unid_t *id, int *id_type, DOM_SID *sid)
{
NTSTATUS ret;
+ int loc_type;
- if (!set_impl()) return NT_STATUS_UNSUCCESSFUL;
+ if (!load_methods()) return NT_STATUS_UNSUCCESSFUL;
- ret = impl->get_id_from_sid(id, id_type, sid);
+ loc_type = *id_type;
+ if (remote_repo) { /* We have a central remote idmap */
+ loc_type |= ID_NOMAP;
+ }
+ ret = local_cache->get_id_from_sid(id, &loc_type, sid);
if (NT_STATUS_IS_ERR(ret)) {
- DEBUG(3, ("idmap_get_id_from_sid: error fetching id!\n"));
+ if (remote_repo) {
+ ret = remote_repo->get_id_from_sid(id, id_type, sid);
+ if (NT_STATUS_IS_ERR(ret)) {
+ DEBUG(3, ("idmap_get_id_from_sid: error fetching id!\n"));
+ } else {
+ loc_type |= ID_CACHE;
+ idmap_set_mapping(sid, *id, loc_type);
+ }
+ }
+ } else {
+ *id_type = loc_type & ID_TYPEMASK;
}
return ret;
}
/* Get SID from ID */
-NTSTATUS idmap_get_sid_from_id(DOM_SID *sid, id_t id, int id_type)
+NTSTATUS idmap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
{
NTSTATUS ret;
+ int loc_type;
- if (!set_impl()) return NT_STATUS_UNSUCCESSFUL;
+ if (!load_methods()) return NT_STATUS_UNSUCCESSFUL;
- ret = impl->get_sid_from_id(sid, id, id_type);
+ loc_type = id_type;
+ if (remote_repo) {
+ loc_type = id_type | ID_NOMAP;
+ }
+ ret = local_cache->get_sid_from_id(sid, id, loc_type);
if (NT_STATUS_IS_ERR(ret)) {
- DEBUG(3, ("idmap_get_sid_from_id: error fetching sid!\n"));
+ if (remote_repo) {
+ ret = remote_repo->get_sid_from_id(sid, id, id_type);
+ if (NT_STATUS_IS_ERR(ret)) {
+ DEBUG(3, ("idmap_get_sid_from_id: unable to fetch sid!\n"));
+ } else {
+ loc_type |= ID_CACHE;
+ idmap_set_mapping(sid, id, loc_type);
+ }
+ }
}
return ret;
}
-
/* Close backend */
NTSTATUS idmap_close(void)
{
NTSTATUS ret;
- if (!set_impl()) return NT_STATUS_UNSUCCESSFUL;
+ if (!load_methods()) return NT_STATUS_UNSUCCESSFUL;
- ret = impl->close();
+ ret = local_cache->close();
if (NT_STATUS_IS_ERR(ret)) {
- DEBUG(3, ("idmap_close: close failed!\n"));
+ DEBUG(3, ("idmap_close: failed to close local cache!\n"));
+ }
+
+ if (remote_repo) {
+ ret = remote_repo->close();
+ if (NT_STATUS_IS_ERR(ret)) {
+ DEBUG(3, ("idmap_close: failed to close remote idmap repository!\n"));
+ }
}
return ret;
@@ -141,8 +206,9 @@ NTSTATUS idmap_close(void)
/* Dump backend status */
void idmap_status(void)
{
- if (!set_impl()) return;
-
- impl->status();
+ if (load_methods()) {
+ local_cache->status();
+ remote_repo->status();
+ }
}