s3: piddir creation fix part 2.
[ira/wip.git] / source3 / winbindd / idmap_tdb2.c
index cb295ba00365dcf21bb6dbc869b53efe66da269b..7098da1ed775289241950152b55ea115429bbd18 100644 (file)
 */
 
 #include "includes.h"
+#include "system/filesys.h"
 #include "winbindd.h"
+#include "idmap.h"
 #include "idmap_rw.h"
+#include "dbwrap/dbwrap.h"
+#include "dbwrap/dbwrap_open.h"
+#include "../libcli/security/dom_sid.h"
+#include "util_tdb.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_IDMAP
@@ -54,6 +60,7 @@ struct idmap_tdb2_context {
  */
 static NTSTATUS idmap_tdb2_init_hwm(struct idmap_domain *dom)
 {
+       NTSTATUS status;
        uint32 low_id;
        struct idmap_tdb2_context *ctx;
 
@@ -61,24 +68,24 @@ static NTSTATUS idmap_tdb2_init_hwm(struct idmap_domain *dom)
 
        /* Create high water marks for group and user id */
 
-       low_id = dbwrap_fetch_int32(ctx->db, HWM_USER);
-       if ((low_id == -1) || (low_id < dom->low_id)) {
-               if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32(
-                                            ctx->db, HWM_USER,
-                                            dom->low_id))) {
+       status = dbwrap_fetch_uint32(ctx->db, HWM_USER, &low_id);
+       if (!NT_STATUS_IS_OK(status) || (low_id < dom->low_id)) {
+               status = dbwrap_trans_store_uint32(ctx->db, HWM_USER,
+                                                  dom->low_id);
+               if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0, ("Unable to initialise user hwm in idmap "
-                                 "database\n"));
+                                 "database: %s\n", nt_errstr(status)));
                        return NT_STATUS_INTERNAL_DB_ERROR;
                }
        }
 
-       low_id = dbwrap_fetch_int32(ctx->db, HWM_GROUP);
-       if ((low_id == -1) || (low_id < dom->low_id)) {
-               if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32(
-                                            ctx->db, HWM_GROUP,
-                                            dom->low_id))) {
+       status = dbwrap_fetch_uint32(ctx->db, HWM_GROUP, &low_id);
+       if (!NT_STATUS_IS_OK(status) || (low_id < dom->low_id)) {
+               status = dbwrap_trans_store_uint32(ctx->db, HWM_GROUP,
+                                                  dom->low_id);
+               if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(0, ("Unable to initialise group hwm in idmap "
-                                 "database\n"));
+                                 "database: %s\n", nt_errstr(status)));
                        return NT_STATUS_INTERNAL_DB_ERROR;
                }
        }
@@ -102,16 +109,12 @@ static NTSTATUS idmap_tdb2_open_db(struct idmap_domain *dom)
                return NT_STATUS_OK;
        }
 
-       db_path = lp_parm_talloc_string(-1, "tdb", "idmap2.tdb", NULL);
-       if (db_path == NULL) {
-               /* fall back to the private directory, which, despite
-                  its name, is usually on shared storage */
-               db_path = talloc_asprintf(NULL, "%s/idmap2.tdb", lp_private_dir());
-       }
+       db_path = talloc_asprintf(NULL, "%s/idmap2.tdb", lp_private_dir());
        NT_STATUS_HAVE_NO_MEMORY(db_path);
 
        /* Open idmap repository */
-       ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);
+       ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644,
+                         DBWRAP_LOCK_ORDER_1);
        TALLOC_FREE(db_path);
 
        if (ctx->db == NULL) {
@@ -144,8 +147,8 @@ static NTSTATUS idmap_tdb2_allocate_id_action(struct db_context *db,
 
        state = (struct idmap_tdb2_allocate_id_context *)private_data;
 
-       hwm = dbwrap_fetch_int32(db, state->hwmkey);
-       if (hwm == -1) {
+       ret = dbwrap_fetch_uint32(db, state->hwmkey, &hwm);
+       if (!NT_STATUS_IS_OK(ret)) {
                ret = NT_STATUS_INTERNAL_DB_ERROR;
                goto done;
        }
@@ -263,14 +266,18 @@ static NTSTATUS idmap_tdb2_get_new_id(struct idmap_domain *dom,
   IDMAP MAPPING TDB BACKEND
 */
 
+static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom,
+                                      const struct id_map *map);
+
 /*
   Initialise idmap database. 
 */
-static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom,
-                                  const char *params)
+static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom)
 {
        NTSTATUS ret;
        struct idmap_tdb2_context *ctx;
+       char *config_option = NULL;
+       const char * idmap_script = NULL;
 
        ctx = talloc_zero(dom, struct idmap_tdb2_context);
        if ( ! ctx) {
@@ -278,27 +285,28 @@ static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (strequal(dom->name, "*")) {
-               ctx->script = lp_parm_const_string(-1, "idmap", "script", NULL);
-               if (ctx->script) {
-                       DEBUG(1, ("using idmap script '%s'\n", ctx->script));
-               }
-       } else {
-               char *config_option = NULL;
+       config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
+       if (config_option == NULL) {
+               DEBUG(0, ("Out of memory!\n"));
+               ret = NT_STATUS_NO_MEMORY;
+               goto failed;
+       }
+       ctx->script = lp_parm_const_string(-1, config_option, "script", NULL);
+       talloc_free(config_option);
 
-               config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
-               if ( ! config_option) {
-                       DEBUG(0, ("Out of memory!\n"));
-                       ret = NT_STATUS_NO_MEMORY;
-                       goto failed;
-               }
+       idmap_script = lp_parm_const_string(-1, "idmap", "script", NULL);
+       if (idmap_script != NULL) {
+               DEBUG(0, ("Warning: 'idmap:script' is deprecated. "
+                         " Please use 'idmap config * : script' instead!\n"));
+       }
 
-               ctx->script = lp_parm_const_string(-1, config_option, "script", NULL);
-               if (ctx->script) {
-                       DEBUG(1, ("using idmap script '%s'\n", ctx->script));
-               }
+       if (strequal(dom->name, "*") && ctx->script == NULL) {
+               /* fall back to idmap:script for backwards compatibility */
+               ctx->script = idmap_script;
+       }
 
-               talloc_free(config_option);
+       if (ctx->script) {
+               DEBUG(1, ("using idmap script '%s'\n", ctx->script));
        }
 
        ctx->rw_ops = talloc_zero(ctx, struct idmap_rw_ops);
@@ -348,8 +356,8 @@ static NTSTATUS idmap_tdb2_set_mapping_action(struct db_context *db,
        DEBUG(10, ("Storing %s <-> %s map\n", state->ksidstr, state->kidstr));
 
        /* check wheter sid mapping is already present in db */
-       data = dbwrap_fetch_bystring(db, tmp_ctx, state->ksidstr);
-       if (data.dptr) {
+       ret = dbwrap_fetch_bystring(db, tmp_ctx, state->ksidstr, &data);
+       if (!NT_STATUS_IS_OK(ret)) {
                ret = NT_STATUS_OBJECT_NAME_COLLISION;
                goto done;
        }
@@ -447,43 +455,12 @@ done:
 static NTSTATUS idmap_tdb2_new_mapping(struct idmap_domain *dom, struct id_map *map)
 {
        NTSTATUS ret;
+       struct idmap_tdb2_context *ctx;
 
-       if (map == NULL) {
-               ret = NT_STATUS_INVALID_PARAMETER;
-               goto done;
-       }
-
-       if ((map->xid.type != ID_TYPE_UID) && (map->xid.type != ID_TYPE_GID)) {
-               ret = NT_STATUS_INVALID_PARAMETER;
-               goto done;
-       }
-
-       if (map->sid == NULL) {
-               ret = NT_STATUS_INVALID_PARAMETER;
-               goto done;
-       }
-
-       ret = idmap_tdb2_get_new_id(dom, &map->xid);
-       if (!NT_STATUS_IS_OK(ret)) {
-               DEBUG(3, ("Could not allocate id: %s\n", nt_errstr(ret)));
-               goto done;
-       }
-
-       DEBUG(10, ("Setting mapping: %s <-> %s %lu\n",
-                  sid_string_dbg(map->sid),
-                  (map->xid.type == ID_TYPE_UID) ? "UID" : "GID",
-                  (unsigned long)map->xid.id));
-
-       map->status = ID_MAPPED;
+       ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
 
-       /* store the mapping */
-       ret = idmap_tdb2_set_mapping(dom, map);
-       if (!NT_STATUS_IS_OK(ret)) {
-               DEBUG(3, ("Could not store the new mapping: %s\n",
-                         nt_errstr(ret)));
-       }
+       ret = idmap_rw_new_mapping(dom, ctx->rw_ops, map);
 
-done:
        return ret;
 }
 
@@ -600,9 +577,6 @@ static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_domain *dom, struct id_map *ma
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       /* final SAFE_FREE safe */
-       data.dptr = NULL;
-
        if (keystr == NULL) {
                DEBUG(0, ("Out of memory!\n"));
                ret = NT_STATUS_NO_MEMORY;
@@ -612,9 +586,9 @@ static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_domain *dom, struct id_map *ma
        DEBUG(10,("Fetching record %s\n", keystr));
 
        /* Check if the mapping exists */
-       data = dbwrap_fetch_bystring(ctx->db, keystr, keystr);
+       status = dbwrap_fetch_bystring(ctx->db, keystr, keystr, &data);
 
-       if (!data.dptr) {
+       if (!NT_STATUS_IS_OK(status)) {
                char *sidstr;
                struct idmap_tdb2_set_mapping_context store_state;
 
@@ -625,8 +599,6 @@ static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_domain *dom, struct id_map *ma
                }
 
                ret = idmap_tdb2_script(ctx, map, "IDTOSID %s", keystr);
-
-               /* store it on shared storage */
                if (!NT_STATUS_IS_OK(ret)) {
                        goto done;
                }
@@ -688,8 +660,8 @@ static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_domain *dom, struct id_map *ma
        DEBUG(10,("Fetching record %s\n", keystr));
 
        /* Check if sid is present in database */
-       data = dbwrap_fetch_bystring(ctx->db, tmp_ctx, keystr);
-       if (!data.dptr) {
+       ret = dbwrap_fetch_bystring(ctx->db, tmp_ctx, keystr, &data);
+       if (!NT_STATUS_IS_OK(ret)) {
                char *idstr;
                struct idmap_tdb2_set_mapping_context store_state;
 
@@ -701,7 +673,6 @@ static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_domain *dom, struct id_map *ma
                }
 
                ret = idmap_tdb2_script(ctx, map, "SIDTOID %s", keystr);
-               /* store it on shared storage */
                if (!NT_STATUS_IS_OK(ret)) {
                        goto done;
                }
@@ -897,24 +868,14 @@ static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_m
 }
 
 
-/*
-  Close the idmap tdb instance
-*/
-static NTSTATUS idmap_tdb2_close(struct idmap_domain *dom)
-{
-       /* don't do anything */
-       return NT_STATUS_OK;
-}
-
 static struct idmap_methods db_methods = {
        .init            = idmap_tdb2_db_init,
        .unixids_to_sids = idmap_tdb2_unixids_to_sids,
        .sids_to_unixids = idmap_tdb2_sids_to_unixids,
-       .allocate_id     = idmap_tdb2_get_new_id,
-       .close_fn        = idmap_tdb2_close
+       .allocate_id     = idmap_tdb2_get_new_id
 };
 
-NTSTATUS idmap_tdb2_init(void)
+NTSTATUS samba_init_module(void)
 {
        return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "tdb2", &db_methods);
 }