s3-net: Add encoding=<CP> to 'net printing migrate'.
authorAndreas Schneider <asn@samba.org>
Tue, 12 Mar 2013 10:39:08 +0000 (11:39 +0100)
committerGünther Deschner <gd@samba.org>
Fri, 15 Mar 2013 11:11:03 +0000 (12:11 +0100)
This allows you to convert printing tdb's which are in e.g. in latin1 to
convert to UTF-8 and import them into the registry.

Reviewed-by: Günther Deschner <gd@samba.org>
source3/printing/nt_printing_migrate.c
source3/printing/nt_printing_migrate.h
source3/printing/nt_printing_migrate_internal.c
source3/utils/net_printing.c

index 94dc3daa568b3e5f50e295c974649b31c7bda60b..eacafa2a5f2cb8d895d6101547c9031462d81db9 100644 (file)
@@ -88,7 +88,8 @@ NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx,
                                     struct rpc_pipe_client *winreg_pipe,
                                     const char *key_name,
                                     unsigned char *data,
-                                    size_t length)
+                                    size_t length,
+                                    bool do_string_conversion)
 {
        struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
        enum ndr_err_code ndr_err;
@@ -105,6 +106,10 @@ NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx,
 
        ZERO_STRUCT(r);
 
+       if (do_string_conversion) {
+               r.string_flags = LIBNDR_FLAG_STR_ASCII;
+       }
+
        ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
                   (ndr_pull_flags_fn_t)ndr_pull_ntprinting_driver);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -150,7 +155,8 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx,
                                      struct rpc_pipe_client *winreg_pipe,
                                      const char *key_name,
                                      unsigned char *data,
-                                     size_t length)
+                                     size_t length,
+                                     bool do_string_conversion)
 {
        struct dcerpc_binding_handle *b = winreg_pipe->binding_handle;
        enum ndr_err_code ndr_err;
@@ -173,6 +179,10 @@ NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx,
 
        ZERO_STRUCT(r);
 
+       if (do_string_conversion) {
+               r.info.string_flags = LIBNDR_FLAG_STR_ASCII;
+       }
+
        ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
                   (ndr_pull_flags_fn_t) ndr_pull_ntprinting_printer);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
index 3da8db462683a016db54f92b36e74bcd8fbc5486..0c9800ddcd5ced3d3c1cff2a344fdb2ea31a58e8 100644 (file)
@@ -30,12 +30,14 @@ NTSTATUS printing_tdb_migrate_driver(TALLOC_CTX *mem_ctx,
                                     struct rpc_pipe_client *winreg_pipe,
                                     const char *key_name,
                                     unsigned char *data,
-                                    size_t length);
+                                    size_t length,
+                                    bool do_string_conversion);
 NTSTATUS printing_tdb_migrate_printer(TALLOC_CTX *mem_ctx,
                                      struct rpc_pipe_client *winreg_pipe,
                                      const char *key_name,
                                      unsigned char *data,
-                                     size_t length);
+                                     size_t length,
+                                     bool do_string_conversion);
 NTSTATUS printing_tdb_migrate_secdesc(TALLOC_CTX *mem_ctx,
                                      struct rpc_pipe_client *winreg_pipe,
                                      const char *key_name,
index 7142a5cb2414355c9c7582f1d7298149d159cf3d..200db07fe2f529f5a300b67924a3df250f480b11 100644 (file)
@@ -114,7 +114,8 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx,
                                                winreg_pipe,
                                                (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
                                                dbuf.dptr,
-                                               dbuf.dsize);
+                                               dbuf.dsize,
+                                               false);
                        SAFE_FREE(dbuf.dptr);
                        if (!NT_STATUS_IS_OK(status)) {
                                tdb_close(tdb);
@@ -130,7 +131,8 @@ static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx,
                                                 winreg_pipe,
                                                 printer_name,
                                                 dbuf.dptr,
-                                                dbuf.dsize);
+                                                dbuf.dsize,
+                                                false);
                        SAFE_FREE(dbuf.dptr);
                        if (!NT_STATUS_IS_OK(status)) {
                                tdb_close(tdb);
index 870f0c3ec35dc7e045932ecb10fc0f7ab3b8a9eb..0df5f35007273e5965649d2212f94bed019aee37 100644 (file)
 #define PRINTERS_PREFIX "PRINTERS/"
 #define SECDESC_PREFIX "SECDESC/"
 
+#define ARG_ENCODING "encoding="
+
+struct printing_opts {
+       const char *encoding;
+       const char *tdb;
+};
+
+static NTSTATUS printing_parse_args(TALLOC_CTX *mem_ctx,
+                                   struct printing_opts **popts,
+                                   int argc, const char **argv)
+{
+       size_t c;
+       struct printing_opts *o;
+
+       if (argc == 0) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       o = talloc_zero(mem_ctx, struct printing_opts);
+       if (o == NULL) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       for (c = 0; c < argc; c++) {
+               if (strnequal(argv[c], ARG_ENCODING, sizeof(ARG_ENCODING) - 1)) {
+                       o->encoding = talloc_strdup(o,
+                                       argv[c] + sizeof(ARG_ENCODING) - 1);
+                       if (o->encoding == NULL) {
+                               return NT_STATUS_NO_MEMORY;
+                       }
+               } else {
+                       o->tdb = talloc_strdup(o, argv[c]);
+                       if (o->tdb == NULL) {
+                               return NT_STATUS_NO_MEMORY;
+                       }
+               }
+       }
+
+       *popts = o;
+       return NT_STATUS_OK;
+}
+
 static void dump_form(TALLOC_CTX *mem_ctx,
                      const char *key_name,
                      unsigned char *data,
@@ -229,23 +271,39 @@ static NTSTATUS printing_migrate_internal(struct net_context *c,
                                          int argc,
                                          const char **argv)
 {
+       struct printing_opts *o;
        TALLOC_CTX *tmp_ctx;
        TDB_CONTEXT *tdb;
        TDB_DATA kbuf, dbuf;
        NTSTATUS status;
+       const char *save_dos_charset = lp_dos_charset();
+       bool do_string_conversion = false;
 
        tmp_ctx = talloc_new(mem_ctx);
        if (tmp_ctx == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0600);
+       status = printing_parse_args(tmp_ctx, &o, argc, argv);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, _("failed to parse arguments\n"));
+               goto done;
+       }
+
+       tdb = tdb_open_log(o->tdb, 0, TDB_DEFAULT, O_RDONLY, 0600);
        if (tdb == NULL) {
-               d_fprintf(stderr, _("failed to open tdb file: %s\n"), argv[0]);
+               d_fprintf(stderr, _("failed to open tdb file: %s\n"), o->tdb);
                status = NT_STATUS_NO_SUCH_FILE;
                goto done;
        }
 
+       if (o->encoding != NULL) {
+               lp_set_cmdline("dos charset", o->encoding);
+               d_fprintf(stderr, _("do string conversion from %s to %s\n"),
+                                   lp_dos_charset(), lp_unix_charset());
+               do_string_conversion = true;
+       }
+
        for (kbuf = tdb_firstkey_compat(tdb);
             kbuf.dptr;
             kbuf = tdb_nextkey_compat(tdb, kbuf))
@@ -270,7 +328,8 @@ static NTSTATUS printing_migrate_internal(struct net_context *c,
                                       winreg_pipe,
                                       (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
                                       dbuf.dptr,
-                                      dbuf.dsize);
+                                      dbuf.dsize,
+                                      do_string_conversion);
                        SAFE_FREE(dbuf.dptr);
                        continue;
                }
@@ -280,7 +339,8 @@ static NTSTATUS printing_migrate_internal(struct net_context *c,
                                        winreg_pipe,
                                        (const char *) kbuf.dptr + strlen(PRINTERS_PREFIX),
                                        dbuf.dptr,
-                                       dbuf.dsize);
+                                       dbuf.dsize,
+                                       do_string_conversion);
                        SAFE_FREE(dbuf.dptr);
                        continue;
                }
@@ -312,6 +372,7 @@ static NTSTATUS printing_migrate_internal(struct net_context *c,
        status = NT_STATUS_OK;
 
  done:
+       lp_set_cmdline("dos charset", save_dos_charset);
        talloc_free(tmp_ctx);
        return status;
 }
@@ -322,10 +383,14 @@ static int net_printing_migrate(struct net_context *c,
 {
        if (argc < 1 || c->display_usage) {
                d_printf(  "%s\n"
-                          "net printing migrate <file.tdb>\n"
+                          "net printing migrate [options] <file.tdb>\n"
                           "    %s\n",
                         _("Usage:"),
                         _("Migrate tdb printing files to new storage"));
+               d_printf(_("Valid options:\n"));
+               d_printf(_("    encoding=<CP>   Set the Code Page of the tdb file.\n"
+                          "                    See iconv -l for the list of CP values\n"
+                          "                    (CP1252 is Western latin1, CP1251 is Cyrillic).\n"));
                return 0;
        }