s3-privs Remove unused function
[ira/wip.git] / source3 / winbindd / idmap.c
index 685062ec4aaebf1b41c5d7302a8aaa63a106e0dc..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".
  */
@@ -228,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;
@@ -250,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));
@@ -309,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;
        }
@@ -355,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;
        }
@@ -386,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"));
        }
@@ -464,11 +531,6 @@ 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);
@@ -548,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);