More fix to initialize idmap statuses
[amitay/samba.git] / source3 / winbindd / idmap_tdb.c
index f2557cc2e6b97daca63a9323f1b176818feef43d..22c17578e6b8a99f839fec72c8c6855e942a4d83 100644 (file)
@@ -203,29 +203,21 @@ static bool idmap_tdb_upgrade(struct db_context *db)
        return True;
 }
 
-static NTSTATUS idmap_tdb_open_db(TALLOC_CTX *memctx,
-                                 bool check_config,
-                                 struct db_context **dbctx)
+static NTSTATUS idmap_tdb_load_ranges(void)
 {
-       NTSTATUS ret;
-       TALLOC_CTX *ctx;
-       char *tdbfile = NULL;
-       struct db_context *db = NULL;
-       int32_t version;
        uid_t low_uid = 0;
        uid_t high_uid = 0;
        gid_t low_gid = 0;
        gid_t high_gid = 0;
-       bool config_error = false;
 
-       /* load ranges */
-       if (!lp_idmap_uid(&low_uid, &high_uid)
-           || !lp_idmap_gid(&low_gid, &high_gid)) {
-               DEBUG(1, ("idmap uid or idmap gid missing\n"));
-               config_error = true;
-               if (check_config) {
-                       return NT_STATUS_UNSUCCESSFUL;
-               }
+       if (!lp_idmap_uid(&low_uid, &high_uid)) {
+               DEBUG(1, ("idmap uid missing\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (!lp_idmap_gid(&low_gid, &high_gid)) {
+               DEBUG(1, ("idmap gid missing\n"));
+               return NT_STATUS_UNSUCCESSFUL;
        }
 
        idmap_tdb_state.low_uid = low_uid;
@@ -235,29 +227,41 @@ static NTSTATUS idmap_tdb_open_db(TALLOC_CTX *memctx,
 
        if (idmap_tdb_state.high_uid <= idmap_tdb_state.low_uid) {
                DEBUG(1, ("idmap uid range missing or invalid\n"));
-               config_error = true;
-               if (check_config) {
-                       return NT_STATUS_UNSUCCESSFUL;
-               }
+               return NT_STATUS_UNSUCCESSFUL;
        }
 
        if (idmap_tdb_state.high_gid <= idmap_tdb_state.low_gid) {
                DEBUG(1, ("idmap gid range missing or invalid\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS idmap_tdb_open_db(TALLOC_CTX *memctx,
+                                 bool check_config,
+                                 struct db_context **dbctx)
+{
+       NTSTATUS ret;
+       TALLOC_CTX *ctx;
+       char *tdbfile = NULL;
+       struct db_context *db = NULL;
+       int32_t version;
+       bool config_error = false;
+
+       ret = idmap_tdb_load_ranges();
+       if (!NT_STATUS_IS_OK(ret)) {
                config_error = true;
                if (check_config) {
-                       return NT_STATUS_UNSUCCESSFUL;
+                       return ret;
                }
        }
 
        /* use our own context here */
-       ctx = talloc_new(memctx);
-       if (!ctx) {
-               DEBUG(0, ("Out of memory!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
+       ctx = talloc_stackframe();
 
        /* use the old database if present */
-       tdbfile = talloc_strdup(ctx, state_path("winbindd_idmap.tdb"));
+       tdbfile = state_path("winbindd_idmap.tdb");
        if (!tdbfile) {
                DEBUG(0, ("Out of memory!\n"));
                ret = NT_STATUS_NO_MEMORY;
@@ -402,6 +406,7 @@ static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid)
        const char *hwmtype;
        uint32_t high_hwm;
        uint32_t hwm;
+       int res;
 
        /* Get current high water mark */
        switch (xid->type) {
@@ -423,7 +428,14 @@ static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid)
                return NT_STATUS_INVALID_PARAMETER;
        }
 
+       res = idmap_alloc_db->transaction_start(idmap_alloc_db);
+       if (res != 0) {
+               DEBUG(1, (__location__ " Failed to start transaction.\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
        if ((hwm = dbwrap_fetch_int32(idmap_alloc_db, hwmkey)) == -1) {
+               idmap_alloc_db->transaction_cancel(idmap_alloc_db);
                return NT_STATUS_INTERNAL_DB_ERROR;
        }
 
@@ -431,6 +443,7 @@ static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid)
        if (hwm > high_hwm) {
                DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n", 
                          hwmtype, (unsigned long)high_hwm));
+               idmap_alloc_db->transaction_cancel(idmap_alloc_db);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
@@ -438,6 +451,7 @@ static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid)
        ret = dbwrap_change_uint32_atomic(idmap_alloc_db, hwmkey, &hwm, 1);
        if (ret != 0) {
                DEBUG(0, ("Fatal error while fetching a new %s value\n!", hwmtype));
+               idmap_alloc_db->transaction_cancel(idmap_alloc_db);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
@@ -445,9 +459,16 @@ static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid)
        if (hwm > high_hwm) {
                DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n", 
                          hwmtype, (unsigned long)high_hwm));
+               idmap_alloc_db->transaction_cancel(idmap_alloc_db);
                return NT_STATUS_UNSUCCESSFUL;
        }
-       
+
+       res = idmap_alloc_db->transaction_commit(idmap_alloc_db);
+       if (res != 0) {
+               DEBUG(1, (__location__ " Failed to commit transaction.\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
        xid->id = hwm;
        DEBUG(10,("New %s = %d\n", hwmtype, hwm));
 
@@ -754,6 +775,11 @@ static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma
        NTSTATUS ret;
        int i;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
 
        for (i = 0; ids[i]; i++) {
@@ -792,6 +818,11 @@ static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma
        NTSTATUS ret;
        int i;
 
+       /* initialize the status to avoid suprise */
+       for (i = 0; ids[i]; i++) {
+               ids[i]->status = ID_UNKNOWN;
+       }
+       
        ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
 
        for (i = 0; ids[i]; i++) {