The branch, v3-6-test has been updated via 8a5c064 s3:net idmap: implement net idmap delete via cdd4e8f s3:net idmap dump: report correct database file when failed to open idmap db. via bfeec5d s3:net idmap dump: use net_idmap_dbfile via 400bc40 s3:net idmap restore: correctly abort operation if dbfile could not be determined via 307a6a0 s3:net idmap: fix error reporting in net_idmap_dbfile() via 9343788 s3:net factor out net_idmap_dbfile via 5ac5852 s3:net idmap restore: fix segfault on missing input file via a185d48 s3:net add option --db via b6a199c s3:testparm: add "--option" to testparm via f1401f2 s3:popt: add POPT_COMMON_OPTION to provide only the "--option" feature via 0e6a7c3 s3:loadparm: skip leading spaces in parameter values from the command line from 9c5c31c s3:rpc_server: create binding_handle in rpc_pipe_open_external()
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test - Log ----------------------------------------------------------------- commit 8a5c06486096c54749f174eb8b1ad7f82d17e253 Author: Gregor Beck <gb...@sernet.de> Date: Wed Feb 9 00:04:48 2011 +0100 s3:net idmap: implement net idmap delete Autobuild-User: Michael Adam <ob...@samba.org> Autobuild-Date: Wed Feb 9 15:06:06 CET 2011 on sn-devel-104 commit cdd4e8f543597cecfad8c1a79160d78ad1e8a358 Author: Michael Adam <ob...@samba.org> Date: Wed Feb 9 13:47:21 2011 +0100 s3:net idmap dump: report correct database file when failed to open idmap db. commit bfeec5d71254f0574607b31d572a61d1966c8b80 Author: Gregor Beck <gb...@sernet.de> Date: Tue Feb 8 12:40:23 2011 +0100 s3:net idmap dump: use net_idmap_dbfile commit 400bc40645132bea5cec1be87a1381ddcf4e1952 Author: Michael Adam <ob...@samba.org> Date: Tue Feb 8 23:24:57 2011 +0100 s3:net idmap restore: correctly abort operation if dbfile could not be determined commit 307a6a09bb4f9b77efa0f9bfd5eb1ddf65a0327f Author: Michael Adam <ob...@samba.org> Date: Tue Feb 8 23:16:31 2011 +0100 s3:net idmap: fix error reporting in net_idmap_dbfile() The last case which results in dbfile == NULL is not an out of memory case but means no --db has been specified and the idmap backend is not supported for auto-determining the idmap tdb file. commit 934378881eeca28974bba43ce61559fe794b0539 Author: Gregor Beck <gb...@sernet.de> Date: Tue Feb 8 12:06:07 2011 +0100 s3:net factor out net_idmap_dbfile commit 5ac5852d434208502cdb206cb0c810927e2ccda5 Author: Gregor Beck <gb...@sernet.de> Date: Tue Feb 8 12:03:08 2011 +0100 s3:net idmap restore: fix segfault on missing input file commit a185d48ba466d5718a4bb0f6cc8b26bac99ae963 Author: Gregor Beck <gb...@sernet.de> Date: Tue Feb 8 12:01:34 2011 +0100 s3:net add option --db commit b6a199c475bca2dc78936522b018dce6b8cf9eef Author: Michael Adam <ob...@samba.org> Date: Wed Feb 9 13:45:22 2011 +0100 s3:testparm: add "--option" to testparm This way one can test the --option feature with testparm. E.g.: testparm -s -v --option="parameter=value" | grep parameter should print "parameter = value" commit f1401f26545f4b2261ca8df5229b0d9c553d2984 Author: Michael Adam <ob...@samba.org> Date: Wed Feb 9 13:44:42 2011 +0100 s3:popt: add POPT_COMMON_OPTION to provide only the "--option" feature commit 0e6a7c3a4643826ca0c274a39c3b0385679ce66c Author: Michael Adam <ob...@samba.org> Date: Wed Feb 9 13:42:38 2011 +0100 s3:loadparm: skip leading spaces in parameter values from the command line ----------------------------------------------------------------------- Summary of changes: source3/include/popt_common.h | 2 + source3/lib/popt_common.c | 5 + source3/param/loadparm.c | 7 +- source3/utils/net.c | 3 +- source3/utils/net.h | 1 + source3/utils/net_idmap.c | 246 ++++++++++++++++++++++++++++++++++------- source3/utils/testparm.c | 1 + 7 files changed, 221 insertions(+), 44 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/popt_common.h b/source3/include/popt_common.h index 040fae9..70d7278 100644 --- a/source3/include/popt_common.h +++ b/source3/include/popt_common.h @@ -29,6 +29,7 @@ extern struct poptOption popt_common_configfile[]; extern struct poptOption popt_common_version[]; extern struct poptOption popt_common_credentials[]; extern struct poptOption popt_common_debuglevel[]; +extern struct poptOption popt_common_option[]; extern const struct poptOption popt_common_dynconfig[]; #ifndef POPT_TABLEEND @@ -44,6 +45,7 @@ extern const struct poptOption popt_common_dynconfig[]; CONST_DISCARD(poptOption *, popt_common_dynconfig), 0, \ "Build-time configuration overrides:", NULL }, #define POPT_COMMON_DEBUGLEVEL { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debuglevel, 0, "Common samba debugging:", NULL }, +#define POPT_COMMON_OPTION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_option, 0, "Common samba commandline config:", NULL }, struct user_auth_info { char *username; diff --git a/source3/lib/popt_common.c b/source3/lib/popt_common.c index 3290643..8ff2b80 100644 --- a/source3/lib/popt_common.c +++ b/source3/lib/popt_common.c @@ -193,6 +193,11 @@ struct poptOption popt_common_debuglevel[] = { POPT_TABLEEND }; +struct poptOption popt_common_option[] = { + { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_POST, (void *)popt_common_callback }, + { "option", 0, POPT_ARG_STRING, NULL, OPT_OPTION, "Set smb.conf option from command line", "name=value" }, + POPT_TABLEEND +}; /* Handle command line options: * --sbindir diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index e57d5ea..04f3561 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -8045,7 +8045,12 @@ bool lp_set_option(const char *option) *p = 0; - ret = lp_set_cmdline(s, p+1); + /* skip white spaces after the = sign */ + do { + p++; + } while (*p == ' '); + + ret = lp_set_cmdline(s, p); talloc_free(s); return ret; } diff --git a/source3/utils/net.c b/source3/utils/net.c index 8415e7a..965cd44 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -813,7 +813,8 @@ static struct functable net_func[] = { {"force-full-repl", 0, POPT_ARG_NONE, &c->opt_force_full_repl}, {"single-obj-repl", 0, POPT_ARG_NONE, &c->opt_single_obj_repl}, {"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries}, - + /* Options for 'net idmap'*/ + {"db", 0, POPT_ARG_STRING, &c->opt_db}, POPT_COMMON_SAMBA { 0, 0, 0, 0} }; diff --git a/source3/utils/net.h b/source3/utils/net.h index d09d990..cefbc4e 100644 --- a/source3/utils/net.h +++ b/source3/utils/net.h @@ -73,6 +73,7 @@ struct net_context { int opt_ccache; int opt_single_obj_repl; int opt_clean_old_entries; + const char *opt_db; int opt_have_ip; struct sockaddr_storage opt_dest_ip; diff --git a/source3/utils/net_idmap.c b/source3/utils/net_idmap.c index 7551354..e7bac53 100644 --- a/source3/utils/net_idmap.c +++ b/source3/utils/net_idmap.c @@ -55,6 +55,45 @@ static int net_idmap_dump_one_entry(struct db_record *rec, return 0; } +static const char* net_idmap_dbfile(struct net_context *c) +{ + const char* dbfile = NULL; + + if (c->opt_db != NULL) { + dbfile = talloc_strdup(talloc_tos(), c->opt_db); + if (dbfile == NULL) { + d_fprintf(stderr, _("Out of memory!\n")); + } + } else if (strequal(lp_idmap_backend(), "tdb")) { + dbfile = state_path("winbindd_idmap.tdb"); + if (dbfile == NULL) { + d_fprintf(stderr, _("Out of memory!\n")); + } + } else if (strequal(lp_idmap_backend(), "tdb2")) { + dbfile = lp_parm_talloc_string(-1, "tdb", "idmap2.tdb", NULL); + if (dbfile == NULL) { + dbfile = talloc_asprintf(talloc_tos(), "%s/idmap2.tdb", + lp_private_dir()); + } + if (dbfile == NULL) { + d_fprintf(stderr, _("Out of memory!\n")); + } + } else { + char* backend = talloc_strdup(talloc_tos(), lp_idmap_backend()); + char* args = strchr(backend, ':'); + if (args != NULL) { + *args = '\0'; + } + + d_printf(_("Sorry, 'idmap backend = %s' is currently not supported\n"), + backend); + + talloc_free(backend); + } + + return dbfile; +} + /*********************************************************** Dump the current idmap **********************************************************/ @@ -62,11 +101,13 @@ static int net_idmap_dump(struct net_context *c, int argc, const char **argv) { struct db_context *db; TALLOC_CTX *mem_ctx; + const char* dbfile; + int ret = -1; - if ( argc != 1 || c->display_usage) { + if ( argc > 1 || c->display_usage) { d_printf("%s\n%s", _("Usage:"), - _("net idmap dump <inputfile>\n" + _("net idmap dump [[--db=]<inputfile>]\n" " Dump current ID mapping.\n" " inputfile\tTDB file to read mappings from.\n")); return c->display_usage?0:-1; @@ -74,19 +115,25 @@ static int net_idmap_dump(struct net_context *c, int argc, const char **argv) mem_ctx = talloc_stackframe(); - db = db_open(mem_ctx, argv[0], 0, TDB_DEFAULT, O_RDONLY, 0); + dbfile = (argc > 0) ? argv[0] : net_idmap_dbfile(c); + if (dbfile == NULL) { + goto done; + } + d_fprintf(stderr, _("dumping id mapping from %s\n"), dbfile); + + db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDONLY, 0); if (db == NULL) { d_fprintf(stderr, _("Could not open idmap db (%s): %s\n"), - argv[0], strerror(errno)); - talloc_free(mem_ctx); - return -1; + dbfile, strerror(errno)); + goto done; } db->traverse_read(db, net_idmap_dump_one_entry, NULL); + ret = 0; +done: talloc_free(mem_ctx); - - return 0; + return ret; } /*********************************************************** @@ -140,14 +187,15 @@ static int net_idmap_restore(struct net_context *c, int argc, const char **argv) TALLOC_CTX *mem_ctx; FILE *input = NULL; struct db_context *db; - char *dbfile = NULL; + const char *dbfile = NULL; int ret = 0; if (c->display_usage) { d_printf("%s\n%s", _("Usage:"), - _("net idmap restore [<inputfile>]\n" + _("net idmap restore [--db=<TDB>] [<inputfile>]\n" " Restore ID mappings from file\n" + " TDB\tFile to store ID mappings to." " inputfile\tFile to load ID mappings from. If not " "given, load data from stdin.\n")); return 0; @@ -155,41 +203,23 @@ static int net_idmap_restore(struct net_context *c, int argc, const char **argv) 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); + dbfile = net_idmap_dbfile(c); + if (dbfile == NULL) { ret = -1; goto done; } - d_fprintf(stderr, _("restoring id mapping to %s data base in '%s'\n"), - lp_idmap_backend(), dbfile); + d_fprintf(stderr, _("restoring id mapping to %s\n"), dbfile); if (argc == 1) { input = fopen(argv[0], "r"); + if (input == NULL) { + d_fprintf(stderr, _("Could not open input file (%s): %s\n"), + argv[0], strerror(errno)); + ret = -1; + goto done; + } } else { input = stdin; } @@ -275,13 +305,145 @@ done: return ret; } +static +NTSTATUS dbwrap_delete_mapping(struct db_context *db, TDB_DATA key1, bool force) +{ + TALLOC_CTX* mem_ctx = talloc_tos(); + struct db_record *rec1=NULL, *rec2=NULL; + TDB_DATA key2; + bool is_valid_mapping; + NTSTATUS status = NT_STATUS_OK; + + rec1 = db->fetch_locked(db, mem_ctx, key1); + if (rec1 == NULL) { + DEBUG(1, ("failed to fetch: %.*s\n", (int)key1.dsize, key1.dptr)); + status = NT_STATUS_NO_MEMORY; + goto done; + } + key2 = rec1->value; + if (key2.dptr == NULL) { + DEBUG(1, ("could not find %.*s\n", (int)key1.dsize, key1.dptr)); + status = NT_STATUS_NOT_FOUND; + goto done; + } + + DEBUG(2, ("mapping: %.*s -> %.*s\n", + (int)key1.dsize, key1.dptr, (int)key2.dsize, key2.dptr)); + + rec2 = db->fetch_locked(db, mem_ctx, key2); + if (rec2 == NULL) { + DEBUG(1, ("failed to fetch: %.*s\n", (int)key2.dsize, key2.dptr)); + status = NT_STATUS_NO_MEMORY; + goto done; + } + + is_valid_mapping = tdb_data_equal(key1, rec2->value); + + if (!is_valid_mapping) { + DEBUG(1, ("invalid mapping: %.*s -> %.*s -> %.*s\n", + (int)key1.dsize, key1.dptr, (int)key2.dsize, key2.dptr, + (int)rec2->value.dsize, rec2->value.dptr )); + if ( !force ) { + status = NT_STATUS_FILE_INVALID; + goto done; + } + } + + status = rec1->delete_rec(rec1); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("failed to delete: %.*s\n", (int)key1.dsize, key1.dptr)); + goto done; + } + + if (is_valid_mapping) { + status = rec2->delete_rec(rec2); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("failed to delete: %.*s\n", (int)key2.dsize, key2.dptr)); + } + } +done: + TALLOC_FREE(rec1); + TALLOC_FREE(rec2); + return status; +} + +static +NTSTATUS delete_mapping_action(struct db_context *db, void* data) +{ + return dbwrap_delete_mapping(db, *(TDB_DATA*)data, false); +} +static +NTSTATUS delete_mapping_action_force(struct db_context *db, void* data) +{ + return dbwrap_delete_mapping(db, *(TDB_DATA*)data, true); +} + /*********************************************************** Delete a SID mapping from a winbindd_idmap.tdb **********************************************************/ +static bool delete_args_ok(int argc, const char **argv) +{ + if (argc != 1) + return false; + if (strncmp(argv[0], "S-", 2) == 0) + return true; + if (strncmp(argv[0], "GID ", 4) == 0) + return true; + if (strncmp(argv[0], "UID ", 4) == 0) + return true; + return false; +} + static int net_idmap_delete(struct net_context *c, int argc, const char **argv) { - d_printf("%s\n", _("Not implemented yet")); - return -1; + int ret = -1; + struct db_context *db; + TALLOC_CTX *mem_ctx; + TDB_DATA key; + NTSTATUS status; + const char* dbfile; + + if ( !delete_args_ok(argc,argv) || c->display_usage) { + d_printf("%s\n%s", + _("Usage:"), + _("net idmap delete [-f] [--db=<TDB>] <ID>\n" + " Delete mapping of ID from TDB.\n" + " -f\tforce\n" + " TDB\tidmap database\n" + " ID\tSID|GID|UID\n")); + return c->display_usage ? 0 : -1; + } + + mem_ctx = talloc_stackframe(); + + dbfile = net_idmap_dbfile(c); + if (dbfile == NULL) { + goto done; + } + d_fprintf(stderr, _("deleting id mapping from %s\n"), dbfile); + + db = db_open(mem_ctx, dbfile, 0, TDB_DEFAULT, O_RDWR, 0); + if (db == NULL) { + d_fprintf(stderr, _("Could not open idmap db (%s): %s\n"), + dbfile, strerror(errno)); + goto done; + } + + key = string_term_tdb_data(argv[0]); + + status = dbwrap_trans_do(db, (c->opt_force + ? delete_mapping_action_force + : delete_mapping_action), &key); + + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, _("could not delete mapping: %s\n"), + nt_errstr(status)); + goto done; + } + ret = 0; +done: + talloc_free(mem_ctx); + return ret; } static int net_idmap_set(struct net_context *c, int argc, const char **argv) @@ -470,9 +632,9 @@ int net_idmap(struct net_context *c, int argc, const char **argv) "delete", net_idmap_delete, NET_TRANSPORT_LOCAL, - N_("Not implemented yet"), - N_("net idmap delete\n" - " Not implemented yet") + N_("Delete ID mapping"), + N_("net idmap delete <ID>\n" + " Delete ID mapping") }, { "secret", diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c index b17d61b..1a011a5 100644 --- a/source3/utils/testparm.c +++ b/source3/utils/testparm.c @@ -339,6 +339,7 @@ rameter is ignored when using CUPS libraries.\n", {"section-name", '\0', POPT_ARG_STRING, §ion_name, 0, "Limit testparm to a named section" }, POPT_COMMON_VERSION POPT_COMMON_DEBUGLEVEL + POPT_COMMON_OPTION POPT_TABLEEND }; -- Samba Shared Repository