s3-privs Remove unused function
[ira/wip.git] / source3 / winbindd / idmap.c
index a0c083c24875d159758e8b011e7ca6f3122e6878..102f4ebb7fca7f80eba0c2877962765c206a4bb4 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "includes.h"
 #include "winbindd.h"
+#include "idmap.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_IDMAP
@@ -55,27 +56,6 @@ struct idmap_backend {
 };
 static struct idmap_backend *backends = NULL;
 
-/**
- * Pointer to the alloc backend methods. Modules register themselves here via
- * smb_register_idmap_alloc.
- */
-struct idmap_alloc_backend {
-       const char *name;
-       struct idmap_alloc_methods *methods;
-       struct idmap_alloc_backend *prev, *next;
-};
-static struct idmap_alloc_backend *alloc_backends = NULL;
-
-/**
- * The idmap alloc context that is configured via "idmap alloc
- * backend". Defaults to "idmap backend" in case the module (tdb, ldap) also
- * provides alloc methods.
- */
-struct idmap_alloc_context {
-       struct idmap_alloc_methods *methods;
-};
-static struct idmap_alloc_context *idmap_alloc_ctx = NULL;
-
 /**
  * Default idmap domain configured via "idmap backend".
  */
@@ -109,19 +89,6 @@ static struct idmap_methods *get_methods(const char *name)
        return NULL;
 }
 
-static struct idmap_alloc_methods *get_alloc_methods(const char *name)
-{
-       struct idmap_alloc_backend *b;
-
-       for (b = alloc_backends; b; b = b->next) {
-               if (strequal(b->name, name)) {
-                       return b->methods;
-               }
-       }
-
-       return NULL;
-}
-
 bool idmap_is_offline(void)
 {
        return ( lp_winbind_offline_logon() &&
@@ -185,55 +152,6 @@ NTSTATUS smb_register_idmap(int version, const char *name,
        return NT_STATUS_OK;
 }
 
-/**********************************************************************
- Allow a module to register itself as an alloc method.
-**********************************************************************/
-
-NTSTATUS smb_register_idmap_alloc(int version, const char *name,
-                                 struct idmap_alloc_methods *methods)
-{
-       struct idmap_alloc_methods *test;
-       struct idmap_alloc_backend *entry;
-
-       if ((version != SMB_IDMAP_INTERFACE_VERSION)) {
-               DEBUG(0, ("Failed to register idmap alloc module.\n"
-                         "The module was compiled against "
-                         "SMB_IDMAP_INTERFACE_VERSION %d,\n"
-                         "current SMB_IDMAP_INTERFACE_VERSION is %d.\n"
-                         "Please recompile against the current version "
-                         "of samba!\n",
-                         version, SMB_IDMAP_INTERFACE_VERSION));
-               return NT_STATUS_OBJECT_TYPE_MISMATCH;
-       }
-
-       if (!name || !name[0] || !methods) {
-               DEBUG(0,("Called with NULL pointer or empty name!\n"));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       test = get_alloc_methods(name);
-       if (test) {
-               DEBUG(0,("idmap_alloc module %s already registered!\n", name));
-               return NT_STATUS_OBJECT_NAME_COLLISION;
-       }
-
-       entry = talloc(NULL, struct idmap_alloc_backend);
-       if ( ! entry) {
-               DEBUG(0,("Out of memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-       entry->name = talloc_strdup(entry, name);
-       if ( ! entry->name) {
-               DEBUG(0,("Out of memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-       entry->methods = methods;
-
-       DLIST_ADD(alloc_backends, entry);
-       DEBUG(5, ("Successfully added idmap alloc backend '%s'\n", name));
-       return NT_STATUS_OK;
-}
-
 static int close_domain_destructor(struct idmap_domain *dom)
 {
        NTSTATUS ret;
@@ -290,12 +208,14 @@ static bool parse_idmap_module(TALLOC_CTX *mem_ctx, const char *param,
  * @param[in] domainname       which domain is this for
  * @param[in] modulename       which backend module
  * @param[in] params           parameter to pass to the init function
+ * @param[in] check_range      whether range checking should be done
  * @result The initialized structure
  */
 static struct idmap_domain *idmap_init_domain(TALLOC_CTX *mem_ctx,
                                              const char *domainname,
                                              const char *modulename,
-                                             const char *params)
+                                             const char *params,
+                                             bool check_range)
 {
        struct idmap_domain *result;
        NTSTATUS status;
@@ -312,6 +232,91 @@ static struct idmap_domain *idmap_init_domain(TALLOC_CTX *mem_ctx,
                goto fail;
        }
 
+       /*
+        * load ranges and read only information from the config
+        */
+       if (strequal(result->name, "*")) {
+               /*
+                * The default domain "*" is configured differently
+                * from named domains.
+                */
+               uid_t low_uid = 0;
+               uid_t high_uid = 0;
+               gid_t low_gid = 0;
+               gid_t high_gid = 0;
+
+               result->low_id = 0;
+               result->high_id = 0;
+
+               if (!lp_idmap_uid(&low_uid, &high_uid)) {
+                       DEBUG(1, ("'idmap uid' not set!\n"));
+                       if (check_range) {
+                               goto fail;
+                       }
+               }
+
+               result->low_id = low_uid;
+               result->high_id = high_uid;
+
+               if (!lp_idmap_gid(&low_gid, &high_gid)) {
+                       DEBUG(1, ("'idmap gid' not set!\n"));
+                       if (check_range) {
+                               goto fail;
+                       }
+               }
+
+               if ((low_gid != low_uid) || (high_gid != high_uid)) {
+                       DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'"
+                             " ranges do not agree -- building "
+                             "intersection\n"));
+                       result->low_id = MAX(result->low_id, low_gid);
+                       result->high_id = MIN(result->high_id, high_gid);
+               }
+
+               result->read_only = lp_idmap_read_only();
+       } else {
+               char *config_option = NULL;
+               const char *range;
+
+               config_option = talloc_asprintf(result, "idmap config %s",
+                                               result->name);
+               if (config_option == NULL) {
+                       DEBUG(0, ("Out of memory!\n"));
+                       goto fail;
+               }
+
+               range = lp_parm_const_string(-1, config_option, "range", NULL);
+               if (range == NULL) {
+                       DEBUG(1, ("idmap range not specified for domain %s\n",
+                                 result ->name));
+                       if (check_range) {
+                               goto fail;
+                       }
+               } else if (sscanf(range, "%u - %u", &result->low_id,
+                                 &result->high_id) != 2)
+               {
+                       DEBUG(1, ("invalid range '%s' specified for domain "
+                                 "'%s'\n", range, result->name));
+                       if (check_range) {
+                               goto fail;
+                       }
+               }
+
+               result->read_only = lp_parm_bool(-1, config_option, "read only",
+                                                false);
+
+               talloc_free(config_option);
+       }
+
+       if (result->low_id > result->high_id) {
+               DEBUG(1, ("Error: invalid idmap range detected: %lu - %lu\n",
+                         (unsigned long)result->low_id,
+                         (unsigned long)result->high_id));
+               if (check_range) {
+                       goto fail;
+               }
+       }
+
        result->methods = get_methods(modulename);
        if (result->methods == NULL) {
                DEBUG(3, ("idmap backend %s not found\n", modulename));
@@ -371,7 +376,7 @@ static struct idmap_domain *idmap_init_default_domain(TALLOC_CTX *mem_ctx)
 
        DEBUG(3, ("idmap_init: using '%s' as remote backend\n", modulename));
 
-       result = idmap_init_domain(mem_ctx, "*", modulename, params);
+       result = idmap_init_domain(mem_ctx, "*", modulename, params, true);
        if (result == NULL) {
                goto fail;
        }
@@ -417,7 +422,7 @@ static struct idmap_domain *idmap_init_named_domain(TALLOC_CTX *mem_ctx,
                goto fail;
        }
 
-       result = idmap_init_domain(mem_ctx, domname, backend, NULL);
+       result = idmap_init_domain(mem_ctx, domname, backend, NULL, true);
        if (result == NULL) {
                goto fail;
        }
@@ -448,7 +453,7 @@ static struct idmap_domain *idmap_init_passdb_domain(TALLOC_CTX *mem_ctx)
        }
 
        passdb_idmap_domain = idmap_init_domain(NULL, get_global_sam_name(),
-                                               "passdb", NULL);
+                                               "passdb", NULL, false);
        if (passdb_idmap_domain == NULL) {
                DEBUG(1, ("Could not init passdb idmap domain\n"));
        }
@@ -526,124 +531,47 @@ static struct idmap_domain *idmap_find_domain(const char *domname)
 
 void idmap_close(void)
 {
-        if (idmap_alloc_ctx) {
-                idmap_alloc_ctx->methods->close_fn();
-                idmap_alloc_ctx->methods = NULL;
-        }
-        alloc_backends = NULL;
        TALLOC_FREE(default_idmap_domain);
        TALLOC_FREE(passdb_idmap_domain);
        TALLOC_FREE(idmap_domains);
        num_domains = 0;
 }
 
-/**
- * Initialize the idmap alloc backend
- * @param[out] ctx             Where to put the alloc_ctx?
- * @result Did it work fine?
- *
- * This routine first looks at "idmap alloc backend" and if that is not
- * defined, it uses "idmap backend" for the module name.
- */
-static NTSTATUS idmap_alloc_init(struct idmap_alloc_context **ctx)
-{
-       const char *backend;
-       char *modulename, *params;
-       NTSTATUS ret = NT_STATUS_NO_MEMORY;;
-
-       idmap_init();
-
-       if (idmap_alloc_ctx != NULL) {
-               *ctx = idmap_alloc_ctx;
-               return NT_STATUS_OK;
-       }
-
-       idmap_alloc_ctx = talloc(NULL, struct idmap_alloc_context);
-       if (idmap_alloc_ctx == NULL) {
-               DEBUG(0, ("talloc failed\n"));
-               goto fail;
-       }
-
-       backend = lp_idmap_alloc_backend();
-       if ((backend == NULL) || (backend[0] == '\0')) {
-               backend = lp_idmap_backend();
-       }
-
-       if (backend == NULL) {
-               DEBUG(3, ("no idmap alloc backend defined\n"));
-               ret = NT_STATUS_INVALID_PARAMETER;
-               goto fail;
-       }
-
-       if (!parse_idmap_module(idmap_alloc_ctx, backend, &modulename,
-                               &params)) {
-               DEBUG(1, ("parse_idmap_module %s failed\n", backend));
-               goto fail;
-       }
+/**************************************************************************
+ idmap allocator interface functions
+**************************************************************************/
 
-       idmap_alloc_ctx->methods = get_alloc_methods(modulename);
+static NTSTATUS idmap_allocate_unixid(struct unixid *id)
+{
+       struct idmap_domain *dom;
+       NTSTATUS ret;
 
-       if (idmap_alloc_ctx->methods == NULL) {
-               ret = smb_probe_module("idmap", modulename);
-               if (NT_STATUS_IS_OK(ret)) {
-                       idmap_alloc_ctx->methods =
-                               get_alloc_methods(modulename);
-               }
-       }
+       dom = idmap_find_domain(NULL);
 
-       if (idmap_alloc_ctx->methods == NULL) {
-               DEBUG(1, ("could not find idmap alloc module %s\n", backend));
-               ret = NT_STATUS_INVALID_PARAMETER;
-               goto fail;
+       if (dom == NULL) {
+               return NT_STATUS_UNSUCCESSFUL;
        }
 
-       ret = idmap_alloc_ctx->methods->init(params);
-
-       if (!NT_STATUS_IS_OK(ret)) {
-               DEBUG(0, ("ERROR: Initialization failed for alloc "
-                         "backend, deferred!\n"));
-               goto fail;
+       if (dom->methods->allocate_id == NULL) {
+               return NT_STATUS_NOT_IMPLEMENTED;
        }
 
-       TALLOC_FREE(modulename);
-       TALLOC_FREE(params);
-
-       *ctx = idmap_alloc_ctx;
-       return NT_STATUS_OK;
+       ret = dom->methods->allocate_id(dom, id);
 
-fail:
-       TALLOC_FREE(idmap_alloc_ctx);
        return ret;
 }
 
-/**************************************************************************
- idmap allocator interface functions
-**************************************************************************/
 
 NTSTATUS idmap_allocate_uid(struct unixid *id)
 {
-       struct idmap_alloc_context *ctx;
-       NTSTATUS ret;
-
-       if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) {
-               return ret;
-       }
-
        id->type = ID_TYPE_UID;
-       return ctx->methods->allocate_id(id);
+       return idmap_allocate_unixid(id);
 }
 
 NTSTATUS idmap_allocate_gid(struct unixid *id)
 {
-       struct idmap_alloc_context *ctx;
-       NTSTATUS ret;
-
-       if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) {
-               return ret;
-       }
-
        id->type = ID_TYPE_GID;
-       return ctx->methods->allocate_id(id);
+       return idmap_allocate_unixid(id);
 }
 
 NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id)
@@ -682,20 +610,30 @@ NTSTATUS idmap_backends_sid_to_unixid(const char *domain, struct id_map *id)
        struct idmap_domain *dom;
        struct id_map *maps[2];
 
-        DEBUG(10, ("idmap_backends_sid_to_unixid: domain = '%s', sid = [%s]\n",
-                   domain?domain:"NULL", sid_string_dbg(id->sid)));
+       DEBUG(10, ("idmap_backends_sid_to_unixid: domain = '%s', sid = [%s]\n",
+                  domain?domain:"NULL", sid_string_dbg(id->sid)));
 
        maps[0] = id;
        maps[1] = NULL;
 
        if (sid_check_is_in_builtin(id->sid)
-           || (sid_check_is_in_our_domain(id->sid))) {
+           || (sid_check_is_in_our_domain(id->sid)))
+       {
+               NTSTATUS status;
+
+               DEBUG(10, ("asking passdb...\n"));
 
                dom = idmap_init_passdb_domain(NULL);
                if (dom == NULL) {
                        return NT_STATUS_NONE_MAPPED;
                }
-               return dom->methods->sids_to_unixids(dom, maps);
+               status = dom->methods->sids_to_unixids(dom, maps);
+
+               if (NT_STATUS_IS_OK(status) && id->status == ID_MAPPED) {
+                       return status;
+               }
+
+               DEBUG(10, ("passdb could not map, asking backends...\n"));
        }
 
        dom = idmap_find_domain(domain);