s3:net: rewrite "net idmap restore" using dbwrap
[amitay/samba.git] / source3 / utils / net_idmap.c
index d145693a223b9b90428b52d2e3226d1af487ac28..46014cab7cd27223be621404ace6611f8a66b657 100644 (file)
@@ -90,29 +90,100 @@ static int net_idmap_dump(struct net_context *c, int argc, const char **argv)
  Write entries from stdin to current local idmap
  **********************************************************/
 
+static int net_idmap_store_id_mapping(struct db_context *db,
+                                     enum id_type type,
+                                     unsigned long idval,
+                                     const char *sid_string)
+{
+       NTSTATUS status;
+       char *idstr = NULL;
+
+       switch(type) {
+       case ID_TYPE_UID:
+               idstr = talloc_asprintf(talloc_tos(), "UID %lu", idval);
+               break;
+       case ID_TYPE_GID:
+               idstr = talloc_asprintf(talloc_tos(), "GID %lu", idval);
+               break;
+       default:
+               d_fprintf(stderr, "Invalid id mapping type: %d\n", type);
+               return -1;
+       }
+
+       status = dbwrap_store_bystring(db, idstr,
+                                      string_term_tdb_data(sid_string),
+                                      TDB_REPLACE);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "Error storing ID -> SID: "
+                        "%s\n", nt_errstr(status));
+               talloc_free(idstr);
+               return -1;
+       }
+       status = dbwrap_store_bystring(db, sid_string,
+                                      string_term_tdb_data(idstr),
+                                      TDB_REPLACE);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "Error storing SID -> ID: "
+                        "%s\n", nt_errstr(status));
+               talloc_free(idstr);
+               return -1;
+       }
+
+       return 0;
+}
+
 static int net_idmap_restore(struct net_context *c, int argc, const char **argv)
 {
-       TALLOC_CTX *ctx;
-       FILE *input;
+       TALLOC_CTX *mem_ctx;
+       FILE *input = NULL;
+       struct db_context *db;
+       char *dbfile = NULL;
+       int ret = 0;
 
        if (c->display_usage) {
                d_printf("%s\n%s",
                         _("Usage:"),
-                        _("net idmap restore [inputfile]\n"
+                        _("net idmap restore [<inputfile>]\n"
                           "  Restore ID mappings from file\n"
-                          "    inputfile\tFile to load ID mappings from. If "
-                          "not given, load data from stdin.\n"));
+                          "    inputfile\tFile to load ID mappings from. If not "
+                          "given, load data from stdin.\n"));
                return 0;
        }
 
-       if (! winbind_ping()) {
-               d_fprintf(stderr,
-                         _("To use net idmap Winbindd must be running.\n"));
-               return -1;
+       mem_ctx = talloc_stackframe();
+
+       if (strequal(lp_idmap_backend(), "tdb")) {
+               dbfile = state_path("winbindd_idmap.tdb");
+               if (dbfile == NULL) {
+                       d_fprintf(stderr, _("Out of memory!\n"));
+                       return -1;
+               }
+       } else if (strequal(lp_idmap_backend(), "tdb2")) {
+               dbfile = lp_parm_talloc_string(-1, "tdb", "idmap2.tdb", NULL);
+               if (dbfile == NULL) {
+                       dbfile = talloc_asprintf(mem_ctx, "%s/idmap2.tdb",
+                                                lp_private_dir());
+               }
+       } else {
+               char *backend, *args;
+
+               backend = talloc_strdup(mem_ctx, lp_idmap_backend());
+               args = strchr(backend, ':');
+               if (args != NULL) {
+                       *args = '\0';
+               }
+
+               d_printf(_("Sorry, 'net idmap restore' is currently not "
+                          "supported for idmap backend = %s.\n"
+                          "Only tdb and tdb2 are supported.\n"),
+                        backend);
+
+               ret = -1;
+               goto done;
        }
 
-       ctx = talloc_new(NULL);
-       ALLOC_CHECK(ctx);
+       d_fprintf(stderr, _("restoring id mapping to %s data base in '%s'\n"),
+                 lp_idmap_backend(), dbfile);
 
        if (argc == 1) {
                input = fopen(argv[0], "r");
@@ -120,13 +191,24 @@ static int net_idmap_restore(struct net_context *c, int argc, const char **argv)
                input = stdin;
        }
 
+       db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);
+       if (db == NULL) {
+               d_fprintf(stderr, _("Could not open idmap db (%s): %s\n"),
+                         dbfile, strerror(errno));
+               ret = -1;
+               goto done;
+       }
+
+       if (db->transaction_start(db) != 0) {
+               d_fprintf(stderr, _("Failed to start transaction.\n"));
+               ret = -1;
+               goto done;
+       }
+
        while (!feof(input)) {
                char line[128], sid_string[128];
                int len;
-               struct wbcDomainSid sid;
-               enum id_type type = ID_TYPE_NOT_SPECIFIED;
                unsigned long idval;
-               wbcErr wbc_status;
 
                if (fgets(line, 127, input) == NULL)
                        break;
@@ -136,62 +218,58 @@ static int net_idmap_restore(struct net_context *c, int argc, const char **argv)
                if ( (len > 0) && (line[len-1] == '\n') )
                        line[len-1] = '\0';
 
-               if (sscanf(line, "GID %lu %128s", &idval, sid_string) == 2) {
-                       type = ID_TYPE_GID;
-               } else if (sscanf(line, "UID %lu %128s", &idval, sid_string) == 2) {
-                       type = ID_TYPE_UID;
+               if (sscanf(line, "GID %lu %128s", &idval, sid_string) == 2)
+               {
+                       ret = net_idmap_store_id_mapping(db, ID_TYPE_GID,
+                                                        idval, sid_string);
+                       if (ret != 0) {
+                               break;
+                       }
+               } else if (sscanf(line, "UID %lu %128s", &idval, sid_string) == 2)
+               {
+                       ret = net_idmap_store_id_mapping(db, ID_TYPE_UID,
+                                                        idval, sid_string);
+                       if (ret != 0) {
+                               break;
+                       }
                } else if (sscanf(line, "USER HWM %lu", &idval) == 1) {
-                       /* set uid hwm */
-                       wbc_status = wbcSetUidHwm(idval);
-                       if (!WBC_ERROR_IS_OK(wbc_status)) {
-                               d_fprintf(stderr,
-                                         _("Could not set USER HWM: %s\n"),
-                                         wbcErrorString(wbc_status));
+                       ret = dbwrap_store_int32(db, "USER HWM", idval);
+                       if (ret != 0) {
+                               d_fprintf(stderr, _("Could not store USER HWM.\n"));
+                               break;
                        }
-                       continue;
                } else if (sscanf(line, "GROUP HWM %lu", &idval) == 1) {
-                       /* set gid hwm */
-                       wbc_status = wbcSetGidHwm(idval);
-                       if (!WBC_ERROR_IS_OK(wbc_status)) {
+                       ret = dbwrap_store_int32(db, "GROUP HWM", idval);
+                       if (ret != 0) {
                                d_fprintf(stderr,
-                                         _("Could not set GROUP HWM: %s\n"),
-                                         wbcErrorString(wbc_status));
+                                         _("Could not store GROUP HWM.\n"));
+                               break;
                        }
-                       continue;
                } else {
                        d_fprintf(stderr, _("ignoring invalid line [%s]\n"),
                                  line);
                        continue;
                }
+       }
 
-               wbc_status = wbcStringToSid(sid_string, &sid);
-               if (!WBC_ERROR_IS_OK(wbc_status)) {
-                       d_fprintf(stderr, _("ignoring invalid sid [%s]: %s\n"),
-                                 sid_string, wbcErrorString(wbc_status));
-                       continue;
-               }
-
-               if (type == ID_TYPE_UID) {
-                       wbc_status = wbcSetUidMapping(idval, &sid);
-               } else {
-                       wbc_status = wbcSetGidMapping(idval, &sid);
+       if (ret == 0) {
+               if(db->transaction_commit(db) != 0) {
+                       d_fprintf(stderr, _("Failed to commit transaction.\n"));
+                       ret = -1;
                }
-               if (!WBC_ERROR_IS_OK(wbc_status)) {
-                       d_fprintf(stderr,
-                                 _("Could not set mapping of %s %lu to sid %s: %s\n"),
-                                (type == ID_TYPE_GID) ? "GID" : "UID",
-                                idval, sid_string,
-                                wbcErrorString(wbc_status));
-                       continue;
+       } else {
+               if (db->transaction_cancel(db) != 0) {
+                       d_fprintf(stderr, _("Failed to cancel transaction.\n"));
                }
        }
 
-       if (input != stdin) {
+done:
+       if ((input != NULL) && (input != stdin)) {
                fclose(input);
        }
 
-       talloc_free(ctx);
-       return 0;
+       talloc_free(mem_ctx);
+       return ret;
 }
 
 /***********************************************************