s3:net: rewrite "net idmap restore" using dbwrap
authorMichael Adam <obnox@samba.org>
Thu, 22 Jan 2009 12:33:54 +0000 (13:33 +0100)
committerMichael Adam <obnox@samba.org>
Sat, 14 Aug 2010 00:10:30 +0000 (02:10 +0200)
This removes the use of libwbclient from "net idmap".

This detects the idmap backend from the current smb.conf
and stores the id mapping tables in the corresponding data bases.
Currently, only tdb and tdb2 backends are supported.
Support for the ldap backend may be implemented later.

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;
 }
 
 /***********************************************************