From a03e2cacafacabda3fe75c784c0c360e5384339f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 22 Jan 2009 13:33:54 +0100 Subject: s3:net: rewrite "net idmap restore" using dbwrap 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 | 182 +++++++++++++++++++++++++++++++++------------- 1 file changed, 130 insertions(+), 52 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c index d145693a22..46014cab7c 100644 --- a/source3/utils/net_idmap.c +++ b/source3/utils/net_idmap.c @@ -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 []\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; } /*********************************************************** -- cgit