diff options
Diffstat (limited to 'source3/sam/idmap.c')
-rw-r--r-- | source3/sam/idmap.c | 134 |
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(); + } } |