root/source3/utils/net_rpc_printer.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. display_print_driver3
  2. display_reg_value
  3. net_copy_fileattr
  4. net_copy_file
  5. net_copy_driverfile
  6. check_arch_dir
  7. copy_print_driver_3
  8. net_spoolss_enum_printers
  9. net_spoolss_open_printer_ex
  10. net_spoolss_getprinter
  11. net_spoolss_setprinter
  12. net_spoolss_setprinterdata
  13. net_spoolss_enumprinterkey
  14. net_spoolss_enumprinterdataex
  15. net_spoolss_setprinterdataex
  16. net_spoolss_enumforms
  17. net_spoolss_enumprinterdrivers
  18. net_spoolss_getprinterdriver
  19. net_spoolss_addprinterdriver
  20. get_printer_info
  21. rpc_printer_list_internals
  22. rpc_printer_driver_list_internals
  23. rpc_printer_publish_internals_args
  24. rpc_printer_publish_publish_internals
  25. rpc_printer_publish_unpublish_internals
  26. rpc_printer_publish_update_internals
  27. rpc_printer_publish_list_internals
  28. rpc_printer_migrate_security_internals
  29. rpc_printer_migrate_forms_internals
  30. rpc_printer_migrate_drivers_internals
  31. rpc_printer_migrate_printers_internals
  32. rpc_printer_migrate_settings_internals

   1 /*
   2    Samba Unix/Linux SMB client library
   3    Distributed SMB/CIFS Server Management Utility
   4    Copyright (C) 2004,2009 Guenther Deschner (gd@samba.org)
   5 
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 3 of the License, or
   9    (at your option) any later version.
  10 
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15 
  16    You should have received a copy of the GNU General Public License
  17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19 #include "includes.h"
  20 #include "utils/net.h"
  21 
  22 /* support itanium as well */
  23 static const struct print_architecture_table_node archi_table[]= {
  24 
  25         {"Windows 4.0",          "WIN40",       0 },
  26         {"Windows NT x86",       "W32X86",      2 },
  27         {"Windows NT x86",       "W32X86",      3 },
  28         {"Windows NT R4000",     "W32MIPS",     2 },
  29         {"Windows NT Alpha_AXP", "W32ALPHA",    2 },
  30         {"Windows NT PowerPC",   "W32PPC",      2 },
  31         {"Windows IA64",         "IA64",        3 },
  32         {"Windows x64",          "x64",         3 },
  33         {NULL,                   "",            -1 }
  34 };
  35 
  36 
  37 /**
  38  * This display-printdriver-functions was borrowed from rpcclient/cmd_spoolss.c.
  39  * It is here for debugging purpose and should be removed later on.
  40  **/
  41 
  42 /****************************************************************************
  43  Printer info level 3 display function.
  44 ****************************************************************************/
  45 
  46 static void display_print_driver3(struct spoolss_DriverInfo3 *r)
     /* [<][>][^][v][top][bottom][index][help] */
  47 {
  48         int i;
  49 
  50         if (!r) {
  51                 return;
  52         }
  53 
  54         printf("Printer Driver Info 3:\n");
  55         printf("\tVersion: [%x]\n", r->version);
  56         printf("\tDriver Name: [%s]\n", r->driver_name);
  57         printf("\tArchitecture: [%s]\n", r->architecture);
  58         printf("\tDriver Path: [%s]\n", r->driver_path);
  59         printf("\tDatafile: [%s]\n", r->data_file);
  60         printf("\tConfigfile: [%s]\n\n", r->config_file);
  61         printf("\tHelpfile: [%s]\n\n", r->help_file);
  62 
  63         for (i=0; r->dependent_files[i] != NULL; i++) {
  64                 printf("\tDependentfiles: [%s]\n", r->dependent_files[i]);
  65         }
  66 
  67         printf("\n");
  68 
  69         printf("\tMonitorname: [%s]\n", r->monitor_name);
  70         printf("\tDefaultdatatype: [%s]\n\n", r->default_datatype);
  71 }
  72 
  73 static void display_reg_value(const char *subkey, REGISTRY_VALUE value)
     /* [<][>][^][v][top][bottom][index][help] */
  74 {
  75         char *text;
  76 
  77         switch(value.type) {
  78         case REG_DWORD:
  79                 d_printf("\t[%s:%s]: REG_DWORD: 0x%08x\n", subkey, value.valuename,
  80                        *((uint32_t *) value.data_p));
  81                 break;
  82 
  83         case REG_SZ:
  84                 rpcstr_pull_talloc(talloc_tos(),
  85                                 &text,
  86                                 value.data_p,
  87                                 value.size,
  88                                 STR_TERMINATE);
  89                 if (!text) {
  90                         break;
  91                 }
  92                 d_printf("\t[%s:%s]: REG_SZ: %s\n", subkey, value.valuename, text);
  93                 break;
  94 
  95         case REG_BINARY:
  96                 d_printf("\t[%s:%s]: REG_BINARY: unknown length value not displayed\n",
  97                          subkey, value.valuename);
  98                 break;
  99 
 100         case REG_MULTI_SZ: {
 101                 uint32_t i, num_values;
 102                 char **values;
 103 
 104                 if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p,
 105                                                      value.size, &num_values,
 106                                                      &values))) {
 107                         d_printf("reg_pull_multi_sz failed\n");
 108                         break;
 109                 }
 110 
 111                 for (i=0; i<num_values; i++) {
 112                         d_printf("%s\n", values[i]);
 113                 }
 114                 TALLOC_FREE(values);
 115                 break;
 116         }
 117 
 118         default:
 119                 d_printf("\t%s: unknown type %d\n", value.valuename, value.type);
 120         }
 121 
 122 }
 123 
 124 /**
 125  * Copies ACLs, DOS-attributes and timestamps from one
 126  * file or directory from one connected share to another connected share
 127  *
 128  * @param c                     A net_context structure
 129  * @param mem_ctx               A talloc-context
 130  * @param cli_share_src         A connected cli_state
 131  * @param cli_share_dst         A connected cli_state
 132  * @param src_file              The source file-name
 133  * @param dst_file              The destination file-name
 134  * @param copy_acls             Whether to copy acls
 135  * @param copy_attrs            Whether to copy DOS attributes
 136  * @param copy_timestamps       Whether to preserve timestamps
 137  * @param is_file               Whether this file is a file or a dir
 138  *
 139  * @return Normal NTSTATUS return.
 140  **/
 141 
 142 NTSTATUS net_copy_fileattr(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 143                   TALLOC_CTX *mem_ctx,
 144                   struct cli_state *cli_share_src,
 145                   struct cli_state *cli_share_dst,
 146                   const char *src_name, const char *dst_name,
 147                   bool copy_acls, bool copy_attrs,
 148                   bool copy_timestamps, bool is_file)
 149 {
 150         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
 151         int fnum_src = 0;
 152         int fnum_dst = 0;
 153         SEC_DESC *sd = NULL;
 154         uint16_t attr;
 155         time_t f_atime, f_ctime, f_mtime;
 156 
 157 
 158         if (!copy_timestamps && !copy_acls && !copy_attrs)
 159                 return NT_STATUS_OK;
 160 
 161         /* open file/dir on the originating server */
 162 
 163         DEBUGADD(3,("opening %s %s on originating server\n",
 164                 is_file?"file":"dir", src_name));
 165 
 166         fnum_src = cli_nt_create(cli_share_src, src_name, READ_CONTROL_ACCESS);
 167         if (fnum_src == -1) {
 168                 DEBUGADD(0,("cannot open %s %s on originating server %s\n",
 169                         is_file?"file":"dir", src_name, cli_errstr(cli_share_src)));
 170                 nt_status = cli_nt_error(cli_share_src);
 171                 goto out;
 172         }
 173 
 174 
 175         if (copy_acls) {
 176 
 177                 /* get the security descriptor */
 178                 sd = cli_query_secdesc(cli_share_src, fnum_src, mem_ctx);
 179                 if (!sd) {
 180                         DEBUG(0,("failed to get security descriptor: %s\n",
 181                                 cli_errstr(cli_share_src)));
 182                         nt_status = cli_nt_error(cli_share_src);
 183                         goto out;
 184                 }
 185 
 186                 if (c->opt_verbose && DEBUGLEVEL >= 3)
 187                         display_sec_desc(sd);
 188         }
 189 
 190 
 191         if (copy_attrs || copy_timestamps) {
 192 
 193                 /* get file attributes */
 194                 if (!cli_getattrE(cli_share_src, fnum_src, &attr, NULL,
 195                                  &f_ctime, &f_atime, &f_mtime)) {
 196                         DEBUG(0,("failed to get file-attrs: %s\n",
 197                                 cli_errstr(cli_share_src)));
 198                         nt_status = cli_nt_error(cli_share_src);
 199                         goto out;
 200                 }
 201         }
 202 
 203 
 204         /* open the file/dir on the destination server */
 205 
 206         fnum_dst = cli_nt_create(cli_share_dst, dst_name, WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS);
 207         if (fnum_dst == -1) {
 208                 DEBUG(0,("failed to open %s on the destination server: %s: %s\n",
 209                         is_file?"file":"dir", dst_name, cli_errstr(cli_share_dst)));
 210                 nt_status = cli_nt_error(cli_share_dst);
 211                 goto out;
 212         }
 213 
 214         if (copy_timestamps) {
 215 
 216                 /* set timestamps */
 217                 if (!cli_setattrE(cli_share_dst, fnum_dst, f_ctime, f_atime, f_mtime)) {
 218                         DEBUG(0,("failed to set file-attrs (timestamps): %s\n",
 219                                 cli_errstr(cli_share_dst)));
 220                         nt_status = cli_nt_error(cli_share_dst);
 221                         goto out;
 222                 }
 223         }
 224 
 225         if (copy_acls) {
 226 
 227                 /* set acls */
 228                 if (!cli_set_secdesc(cli_share_dst, fnum_dst, sd)) {
 229                         DEBUG(0,("could not set secdesc on %s: %s\n",
 230                                 dst_name, cli_errstr(cli_share_dst)));
 231                         nt_status = cli_nt_error(cli_share_dst);
 232                         goto out;
 233                 }
 234         }
 235 
 236         if (copy_attrs) {
 237 
 238                 /* set attrs */
 239                 if (!cli_setatr(cli_share_dst, dst_name, attr, 0)) {
 240                         DEBUG(0,("failed to set file-attrs: %s\n",
 241                                 cli_errstr(cli_share_dst)));
 242                         nt_status = cli_nt_error(cli_share_dst);
 243                         goto out;
 244                 }
 245         }
 246 
 247 
 248         /* closing files */
 249 
 250         if (!cli_close(cli_share_src, fnum_src)) {
 251                 d_fprintf(stderr, "could not close %s on originating server: %s\n",
 252                         is_file?"file":"dir", cli_errstr(cli_share_src));
 253                 nt_status = cli_nt_error(cli_share_src);
 254                 goto out;
 255         }
 256 
 257         if (!cli_close(cli_share_dst, fnum_dst)) {
 258                 d_fprintf(stderr, "could not close %s on destination server: %s\n",
 259                         is_file?"file":"dir", cli_errstr(cli_share_dst));
 260                 nt_status = cli_nt_error(cli_share_dst);
 261                 goto out;
 262         }
 263 
 264 
 265         nt_status = NT_STATUS_OK;
 266 
 267 out:
 268 
 269         /* cleaning up */
 270         if (fnum_src)
 271                 cli_close(cli_share_src, fnum_src);
 272 
 273         if (fnum_dst)
 274                 cli_close(cli_share_dst, fnum_dst);
 275 
 276         return nt_status;
 277 }
 278 
 279 /**
 280  * Copy a file or directory from a connected share to another connected share
 281  *
 282  * @param c                     A net_context structure
 283  * @param mem_ctx               A talloc-context
 284  * @param cli_share_src         A connected cli_state
 285  * @param cli_share_dst         A connected cli_state
 286  * @param src_file              The source file-name
 287  * @param dst_file              The destination file-name
 288  * @param copy_acls             Whether to copy acls
 289  * @param copy_attrs            Whether to copy DOS attributes
 290  * @param copy_timestamps       Whether to preserve timestamps
 291  * @param is_file               Whether this file is a file or a dir
 292  *
 293  * @return Normal NTSTATUS return.
 294  **/
 295 
 296 NTSTATUS net_copy_file(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 297                        TALLOC_CTX *mem_ctx,
 298                        struct cli_state *cli_share_src,
 299                        struct cli_state *cli_share_dst,
 300                        const char *src_name, const char *dst_name,
 301                        bool copy_acls, bool copy_attrs,
 302                        bool copy_timestamps, bool is_file)
 303 {
 304         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
 305         int fnum_src = 0;
 306         int fnum_dst = 0;
 307         static int io_bufsize = 64512;
 308         int read_size = io_bufsize;
 309         char *data = NULL;
 310         off_t nread = 0;
 311 
 312 
 313         if (!src_name || !dst_name)
 314                 goto out;
 315 
 316         if (cli_share_src == NULL || cli_share_dst == NULL)
 317                 goto out;
 318 
 319         /* open on the originating server */
 320         DEBUGADD(3,("opening %s %s on originating server\n",
 321                 is_file ? "file":"dir", src_name));
 322         if (is_file)
 323                 fnum_src = cli_open(cli_share_src, src_name, O_RDONLY, DENY_NONE);
 324         else
 325                 fnum_src = cli_nt_create(cli_share_src, src_name, READ_CONTROL_ACCESS);
 326 
 327         if (fnum_src == -1) {
 328                 DEBUGADD(0,("cannot open %s %s on originating server %s\n",
 329                         is_file ? "file":"dir",
 330                         src_name, cli_errstr(cli_share_src)));
 331                 nt_status = cli_nt_error(cli_share_src);
 332                 goto out;
 333         }
 334 
 335 
 336         if (is_file) {
 337 
 338                 /* open file on the destination server */
 339                 DEBUGADD(3,("opening file %s on destination server\n", dst_name));
 340                 fnum_dst = cli_open(cli_share_dst, dst_name,
 341                                 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
 342 
 343                 if (fnum_dst == -1) {
 344                         DEBUGADD(1,("cannot create file %s on destination server: %s\n", 
 345                                 dst_name, cli_errstr(cli_share_dst)));
 346                         nt_status = cli_nt_error(cli_share_dst);
 347                         goto out;
 348                 }
 349 
 350                 /* allocate memory */
 351                 if (!(data = (char *)SMB_MALLOC(read_size))) {
 352                         d_fprintf(stderr, "malloc fail for size %d\n", read_size);
 353                         nt_status = NT_STATUS_NO_MEMORY;
 354                         goto out;
 355                 }
 356 
 357         }
 358 
 359 
 360         if (c->opt_verbose) {
 361 
 362                 d_printf("copying [\\\\%s\\%s%s] => [\\\\%s\\%s%s] "
 363                          "%s ACLs and %s DOS Attributes %s\n",
 364                         cli_share_src->desthost, cli_share_src->share, src_name,
 365                         cli_share_dst->desthost, cli_share_dst->share, dst_name,
 366                         copy_acls ?  "with" : "without",
 367                         copy_attrs ? "with" : "without",
 368                         copy_timestamps ? "(preserving timestamps)" : "" );
 369         }
 370 
 371 
 372         while (is_file) {
 373 
 374                 /* copying file */
 375                 int n, ret;
 376                 n = cli_read(cli_share_src, fnum_src, data, nread,
 377                                 read_size);
 378 
 379                 if (n <= 0)
 380                         break;
 381 
 382                 ret = cli_write(cli_share_dst, fnum_dst, 0, data,
 383                         nread, n);
 384 
 385                 if (n != ret) {
 386                         d_fprintf(stderr, "Error writing file: %s\n",
 387                                 cli_errstr(cli_share_dst));
 388                         nt_status = cli_nt_error(cli_share_dst);
 389                         goto out;
 390                 }
 391 
 392                 nread += n;
 393         }
 394 
 395 
 396         if (!is_file && !cli_chkpath(cli_share_dst, dst_name)) {
 397 
 398                 /* creating dir */
 399                 DEBUGADD(3,("creating dir %s on the destination server\n",
 400                         dst_name));
 401 
 402                 if (!cli_mkdir(cli_share_dst, dst_name)) {
 403                         DEBUG(0,("cannot create directory %s: %s\n",
 404                                 dst_name, cli_errstr(cli_share_dst)));
 405                         nt_status = NT_STATUS_NO_SUCH_FILE;
 406                 }
 407 
 408                 if (!cli_chkpath(cli_share_dst, dst_name)) {
 409                         d_fprintf(stderr, "cannot check for directory %s: %s\n",
 410                                 dst_name, cli_errstr(cli_share_dst));
 411                         goto out;
 412                 }
 413         }
 414 
 415 
 416         /* closing files */
 417         if (!cli_close(cli_share_src, fnum_src)) {
 418                 d_fprintf(stderr, "could not close file on originating server: %s\n",
 419                         cli_errstr(cli_share_src));
 420                 nt_status = cli_nt_error(cli_share_src);
 421                 goto out;
 422         }
 423 
 424         if (is_file && !cli_close(cli_share_dst, fnum_dst)) {
 425                 d_fprintf(stderr, "could not close file on destination server: %s\n",
 426                         cli_errstr(cli_share_dst));
 427                 nt_status = cli_nt_error(cli_share_dst);
 428                 goto out;
 429         }
 430 
 431         /* possibly we have to copy some file-attributes / acls / sd */
 432         nt_status = net_copy_fileattr(c, mem_ctx, cli_share_src, cli_share_dst,
 433                                       src_name, dst_name, copy_acls,
 434                                       copy_attrs, copy_timestamps, is_file);
 435         if (!NT_STATUS_IS_OK(nt_status))
 436                 goto out;
 437 
 438 
 439         nt_status = NT_STATUS_OK;
 440 
 441 out:
 442 
 443         /* cleaning up */
 444         if (fnum_src)
 445                 cli_close(cli_share_src, fnum_src);
 446 
 447         if (fnum_dst)
 448                 cli_close(cli_share_dst, fnum_dst);
 449 
 450         SAFE_FREE(data);
 451 
 452         return nt_status;
 453 }
 454 
 455 /**
 456  * Copy a driverfile from on connected share to another connected share
 457  * This silently assumes that a driver-file is picked up from
 458  *
 459  *      \\src_server\print$\{arch}\{version}\file
 460  *
 461  * and copied to
 462  *
 463  *      \\dst_server\print$\{arch}\file
 464  *
 465  * to be added via setdriver-calls later.
 466  * @param c                     A net_context structure
 467  * @param mem_ctx               A talloc-context
 468  * @param cli_share_src         A cli_state connected to source print$-share
 469  * @param cli_share_dst         A cli_state connected to destination print$-share
 470  * @param file                  The file-name to be copied
 471  * @param short_archi           The name of the driver-architecture (short form)
 472  *
 473  * @return Normal NTSTATUS return.
 474  **/
 475 
 476 static NTSTATUS net_copy_driverfile(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 477                                     TALLOC_CTX *mem_ctx,
 478                                     struct cli_state *cli_share_src,
 479                                     struct cli_state *cli_share_dst,
 480                                     const char *file, const char *short_archi) {
 481 
 482         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
 483         const char *p;
 484         char *src_name;
 485         char *dst_name;
 486         char *version;
 487         char *filename;
 488         char *tok;
 489 
 490         if (!file) {
 491                 return NT_STATUS_OK;
 492         }
 493 
 494         /* scroll through the file until we have the part
 495            beyond archi_table.short_archi */
 496         p = file;
 497         while (next_token_talloc(mem_ctx, &p, &tok, "\\")) {
 498                 if (strequal(tok, short_archi)) {
 499                         next_token_talloc(mem_ctx, &p, &version, "\\");
 500                         next_token_talloc(mem_ctx, &p, &filename, "\\");
 501                 }
 502         }
 503 
 504         /* build source file name */
 505         if (asprintf(&src_name, "\\%s\\%s\\%s", short_archi, version, filename) < 0 )
 506                 return NT_STATUS_NO_MEMORY;
 507 
 508 
 509         /* create destination file name */
 510         if (asprintf(&dst_name, "\\%s\\%s", short_archi, filename) < 0 )
 511                 return NT_STATUS_NO_MEMORY;
 512 
 513 
 514         /* finally copy the file */
 515         nt_status = net_copy_file(c, mem_ctx, cli_share_src, cli_share_dst,
 516                                   src_name, dst_name, false, false, false, true);
 517         if (!NT_STATUS_IS_OK(nt_status))
 518                 goto out;
 519 
 520         nt_status = NT_STATUS_OK;
 521 
 522 out:
 523         SAFE_FREE(src_name);
 524         SAFE_FREE(dst_name);
 525 
 526         return nt_status;
 527 }
 528 
 529 /**
 530  * Check for existing Architecture directory on a given server
 531  *
 532  * @param cli_share             A cli_state connected to a print$-share
 533  * @param short_archi           The Architecture for the print-driver
 534  *
 535  * @return Normal NTSTATUS return.
 536  **/
 537 
 538 static NTSTATUS check_arch_dir(struct cli_state *cli_share, const char *short_archi)
     /* [<][>][^][v][top][bottom][index][help] */
 539 {
 540 
 541         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
 542         char *dir;
 543 
 544         if (asprintf(&dir, "\\%s", short_archi) < 0) {
 545                 return NT_STATUS_NO_MEMORY;
 546         }
 547 
 548         DEBUG(10,("creating print-driver dir for architecture: %s\n",
 549                 short_archi));
 550 
 551         if (!cli_mkdir(cli_share, dir)) {
 552                 DEBUG(1,("cannot create directory %s: %s\n",
 553                          dir, cli_errstr(cli_share)));
 554                 nt_status = NT_STATUS_NO_SUCH_FILE;
 555         }
 556 
 557         if (!cli_chkpath(cli_share, dir)) {
 558                 d_fprintf(stderr, "cannot check %s: %s\n",
 559                         dir, cli_errstr(cli_share));
 560                 goto out;
 561         }
 562 
 563         nt_status = NT_STATUS_OK;
 564 
 565 out:
 566         SAFE_FREE(dir);
 567         return nt_status;
 568 }
 569 
 570 /**
 571  * Copy a print-driver (level 3) from one connected print$-share to another
 572  * connected print$-share
 573  *
 574  * @param c                     A net_context structure
 575  * @param mem_ctx               A talloc-context
 576  * @param cli_share_src         A cli_state connected to a print$-share
 577  * @param cli_share_dst         A cli_state connected to a print$-share
 578  * @param short_archi           The Architecture for the print-driver
 579  * @param i1                    The DRIVER_INFO_3-struct
 580  *
 581  * @return Normal NTSTATUS return.
 582  **/
 583 
 584 static NTSTATUS copy_print_driver_3(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 585                     TALLOC_CTX *mem_ctx,
 586                     struct cli_state *cli_share_src,
 587                     struct cli_state *cli_share_dst,
 588                     const char *short_archi,
 589                     struct spoolss_DriverInfo3 *r)
 590 {
 591         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
 592         int i;
 593 
 594         if (r == NULL) {
 595                 return nt_status;
 596         }
 597 
 598         if (c->opt_verbose)
 599                 d_printf("copying driver: [%s], for architecture: [%s], version: [%d]\n",
 600                           r->driver_name, short_archi, r->version);
 601 
 602         nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst,
 603                 r->driver_path, short_archi);
 604         if (!NT_STATUS_IS_OK(nt_status))
 605                 return nt_status;
 606 
 607         nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst,
 608                 r->data_file, short_archi);
 609         if (!NT_STATUS_IS_OK(nt_status))
 610                 return nt_status;
 611 
 612         nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst,
 613                 r->config_file, short_archi);
 614         if (!NT_STATUS_IS_OK(nt_status))
 615                 return nt_status;
 616 
 617         nt_status = net_copy_driverfile(c, mem_ctx, cli_share_src, cli_share_dst,
 618                 r->help_file, short_archi);
 619         if (!NT_STATUS_IS_OK(nt_status))
 620                 return nt_status;
 621 
 622         for (i=0; r->dependent_files[i] != NULL; i++) {
 623 
 624                 nt_status = net_copy_driverfile(c, mem_ctx,
 625                                 cli_share_src, cli_share_dst,
 626                                 r->dependent_files[i], short_archi);
 627                 if (!NT_STATUS_IS_OK(nt_status)) {
 628                         return nt_status;
 629                 }
 630         }
 631 
 632         return NT_STATUS_OK;
 633 }
 634 
 635 /**
 636  * net_spoolss-functions
 637  * =====================
 638  *
 639  * the net_spoolss-functions aim to simplify spoolss-client-functions
 640  * required during the migration-process wrt buffer-sizes, returned
 641  * error-codes, etc.
 642  *
 643  * this greatly reduces the complexitiy of the migrate-functions.
 644  *
 645  **/
 646 
 647 static bool net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
 648                                         TALLOC_CTX *mem_ctx,
 649                                         char *name,
 650                                         uint32_t flags,
 651                                         uint32_t level,
 652                                         uint32_t *num_printers,
 653                                         union spoolss_PrinterInfo **info)
 654 {
 655         WERROR result;
 656 
 657         /* enum printers */
 658 
 659         result = rpccli_spoolss_enumprinters(pipe_hnd, mem_ctx,
 660                                              flags,
 661                                              name,
 662                                              level,
 663                                              0,
 664                                              num_printers,
 665                                              info);
 666         if (!W_ERROR_IS_OK(result)) {
 667                 printf("cannot enum printers: %s\n", win_errstr(result));
 668                 return false;
 669         }
 670 
 671         return true;
 672 }
 673 
 674 static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
 675                                         TALLOC_CTX *mem_ctx,
 676                                         const char *printername,
 677                                         uint32_t access_required,
 678                                         const char *username,
 679                                         struct policy_handle *hnd)
 680 {
 681         WERROR result;
 682         fstring printername2;
 683 
 684         fstrcpy(printername2, pipe_hnd->srv_name_slash);
 685         fstrcat(printername2, "\\");
 686         fstrcat(printername2, printername);
 687 
 688         DEBUG(10,("connecting to: %s as %s for %s and access: %x\n",
 689                 pipe_hnd->srv_name_slash, username, printername2, access_required));
 690 
 691         /* open printer */
 692         result = rpccli_spoolss_openprinter_ex(pipe_hnd, mem_ctx,
 693                                                printername2,
 694                                                access_required,
 695                                                hnd);
 696 
 697         /* be more verbose */
 698         if (W_ERROR_V(result) == W_ERROR_V(WERR_ACCESS_DENIED)) {
 699                 d_fprintf(stderr, "no access to printer [%s] on [%s] for user [%s] granted\n",
 700                         printername2, pipe_hnd->srv_name_slash, username);
 701                 return false;
 702         }
 703 
 704         if (!W_ERROR_IS_OK(result)) {
 705                 d_fprintf(stderr, "cannot open printer %s on server %s: %s\n",
 706                         printername2, pipe_hnd->srv_name_slash, win_errstr(result));
 707                 return false;
 708         }
 709 
 710         DEBUG(2,("got printer handle for printer: %s, server: %s\n",
 711                 printername2, pipe_hnd->srv_name_slash));
 712 
 713         return true;
 714 }
 715 
 716 static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
 717                                 TALLOC_CTX *mem_ctx,
 718                                 struct policy_handle *hnd,
 719                                 uint32_t level,
 720                                 union spoolss_PrinterInfo *info)
 721 {
 722         WERROR result;
 723 
 724         /* getprinter call */
 725         result = rpccli_spoolss_getprinter(pipe_hnd, mem_ctx,
 726                                            hnd,
 727                                            level,
 728                                            0, /* offered */
 729                                            info);
 730         if (!W_ERROR_IS_OK(result)) {
 731                 printf("cannot get printer-info: %s\n", win_errstr(result));
 732                 return false;
 733         }
 734 
 735         return true;
 736 }
 737 
 738 static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
 739                                 TALLOC_CTX *mem_ctx,
 740                                 struct policy_handle *hnd,
 741                                 uint32_t level,
 742                                 union spoolss_PrinterInfo *info)
 743 {
 744         WERROR result;
 745         NTSTATUS status;
 746         struct spoolss_SetPrinterInfoCtr info_ctr;
 747         struct spoolss_DevmodeContainer devmode_ctr;
 748         struct sec_desc_buf secdesc_ctr;
 749 
 750         ZERO_STRUCT(devmode_ctr);
 751         ZERO_STRUCT(secdesc_ctr);
 752 
 753         /* setprinter call */
 754 
 755         info_ctr.level = level;
 756         switch (level) {
 757         case 0:
 758                 info_ctr.info.info0 = (struct spoolss_SetPrinterInfo0 *)&info->info0;
 759                 break;
 760         case 1:
 761                 info_ctr.info.info1 = (struct spoolss_SetPrinterInfo1 *)&info->info1;
 762                 break;
 763         case 2:
 764                 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info->info2;
 765                 break;
 766         case 3:
 767                 info_ctr.info.info3 = (struct spoolss_SetPrinterInfo3 *)&info->info3;
 768                 break;
 769         case 4:
 770                 info_ctr.info.info4 = (struct spoolss_SetPrinterInfo4 *)&info->info4;
 771                 break;
 772         case 5:
 773                 info_ctr.info.info5 = (struct spoolss_SetPrinterInfo5 *)&info->info5;
 774                 break;
 775         case 6:
 776                 info_ctr.info.info6 = (struct spoolss_SetPrinterInfo6 *)&info->info6;
 777                 break;
 778         case 7:
 779                 info_ctr.info.info7 = (struct spoolss_SetPrinterInfo7 *)&info->info7;
 780                 break;
 781 #if 0 /* FIXME GD */
 782         case 8:
 783                 info_ctr.info.info8 = (struct spoolss_SetPrinterInfo8 *)&info->info8;
 784                 break;
 785         case 9:
 786                 info_ctr.info.info9 = (struct spoolss_SetPrinterInfo9 *)&info->info9;
 787                 break;
 788 #endif
 789         default:
 790                 break; /* FIXME */
 791         }
 792 
 793         status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx,
 794                                            hnd,
 795                                            &info_ctr,
 796                                            &devmode_ctr,
 797                                            &secdesc_ctr,
 798                                            0, /* command */
 799                                            &result);
 800 
 801         if (!W_ERROR_IS_OK(result)) {
 802                 printf("cannot set printer-info: %s\n", win_errstr(result));
 803                 return false;
 804         }
 805 
 806         return true;
 807 }
 808 
 809 
 810 static bool net_spoolss_setprinterdata(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
 811                                        TALLOC_CTX *mem_ctx,
 812                                        struct policy_handle *hnd,
 813                                        const char *value_name,
 814                                        enum winreg_Type type,
 815                                        union spoolss_PrinterData data)
 816 {
 817         WERROR result;
 818         NTSTATUS status;
 819 
 820         /* setprinterdata call */
 821         status = rpccli_spoolss_SetPrinterData(pipe_hnd, mem_ctx,
 822                                                hnd,
 823                                                value_name,
 824                                                type,
 825                                                data,
 826                                                0, /* autocalculated */
 827                                                &result);
 828 
 829         if (!W_ERROR_IS_OK(result)) {
 830                 printf ("unable to set printerdata: %s\n", win_errstr(result));
 831                 return false;
 832         }
 833 
 834         return true;
 835 }
 836 
 837 
 838 static bool net_spoolss_enumprinterkey(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
 839                                         TALLOC_CTX *mem_ctx,
 840                                         struct policy_handle *hnd,
 841                                         const char *keyname,
 842                                         const char ***keylist)
 843 {
 844         WERROR result;
 845 
 846         /* enumprinterkey call */
 847         result = rpccli_spoolss_enumprinterkey(pipe_hnd, mem_ctx, hnd, keyname, keylist, 0);
 848 
 849         if (!W_ERROR_IS_OK(result)) {
 850                 printf("enumprinterkey failed: %s\n", win_errstr(result));
 851                 return false;
 852         }
 853 
 854         return true;
 855 }
 856 
 857 static bool net_spoolss_enumprinterdataex(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
 858                                         TALLOC_CTX *mem_ctx,
 859                                         uint32_t offered,
 860                                         struct policy_handle *hnd,
 861                                         const char *keyname,
 862                                         uint32_t *count,
 863                                         struct spoolss_PrinterEnumValues **info)
 864 {
 865         WERROR result;
 866 
 867         /* enumprinterdataex call */
 868         result = rpccli_spoolss_enumprinterdataex(pipe_hnd, mem_ctx,
 869                                                   hnd,
 870                                                   keyname,
 871                                                   0, /* offered */
 872                                                   count,
 873                                                   info);
 874 
 875         if (!W_ERROR_IS_OK(result)) {
 876                 printf("enumprinterdataex failed: %s\n", win_errstr(result));
 877                 return false;
 878         }
 879 
 880         return true;
 881 }
 882 
 883 
 884 static bool net_spoolss_setprinterdataex(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
 885                                         TALLOC_CTX *mem_ctx,
 886                                         struct policy_handle *hnd,
 887                                         const char *keyname,
 888                                         REGISTRY_VALUE *value)
 889 {
 890         WERROR result;
 891         NTSTATUS status;
 892 
 893         /* setprinterdataex call */
 894         status = rpccli_spoolss_SetPrinterDataEx(pipe_hnd, mem_ctx,
 895                                                  hnd,
 896                                                  keyname,
 897                                                  value->valuename,
 898                                                  value->type,
 899                                                  value->data_p,
 900                                                  value->size,
 901                                                  &result);
 902 
 903         if (!W_ERROR_IS_OK(result)) {
 904                 printf("could not set printerdataex: %s\n", win_errstr(result));
 905                 return false;
 906         }
 907 
 908         return true;
 909 }
 910 
 911 static bool net_spoolss_enumforms(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
 912                                 TALLOC_CTX *mem_ctx,
 913                                 struct policy_handle *hnd,
 914                                 int level,
 915                                 uint32_t *num_forms,
 916                                 union spoolss_FormInfo **forms)
 917 {
 918         WERROR result;
 919 
 920         /* enumforms call */
 921         result = rpccli_spoolss_enumforms(pipe_hnd, mem_ctx,
 922                                           hnd,
 923                                           level,
 924                                           0,
 925                                           num_forms,
 926                                           forms);
 927         if (!W_ERROR_IS_OK(result)) {
 928                 printf("could not enum forms: %s\n", win_errstr(result));
 929                 return false;
 930         }
 931 
 932         return true;
 933 }
 934 
 935 static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
 936                                         TALLOC_CTX *mem_ctx,
 937                                         uint32_t level, const char *env,
 938                                         uint32_t *count,
 939                                         union spoolss_DriverInfo **info)
 940 {
 941         WERROR result;
 942 
 943         /* enumprinterdrivers call */
 944         result = rpccli_spoolss_enumprinterdrivers(pipe_hnd, mem_ctx,
 945                                                    pipe_hnd->srv_name_slash,
 946                                                    env,
 947                                                    level,
 948                                                    0,
 949                                                    count,
 950                                                    info);
 951         if (!W_ERROR_IS_OK(result)) {
 952                 printf("cannot enum drivers: %s\n", win_errstr(result));
 953                 return false;
 954         }
 955 
 956         return true;
 957 }
 958 
 959 static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
 960                              TALLOC_CTX *mem_ctx,
 961                              struct policy_handle *hnd, uint32_t level,
 962                              const char *env, int version,
 963                              union spoolss_DriverInfo *info)
 964 {
 965         WERROR result;
 966         uint32_t server_major_version;
 967         uint32_t server_minor_version;
 968 
 969         /* getprinterdriver call */
 970         result = rpccli_spoolss_getprinterdriver2(pipe_hnd, mem_ctx,
 971                                                   hnd,
 972                                                   env,
 973                                                   level,
 974                                                   0,
 975                                                   version,
 976                                                   2,
 977                                                   info,
 978                                                   &server_major_version,
 979                                                   &server_minor_version);
 980         if (!W_ERROR_IS_OK(result)) {
 981                 DEBUG(1,("cannot get driver (for architecture: %s): %s\n",
 982                         env, win_errstr(result)));
 983                 if (W_ERROR_V(result) != W_ERROR_V(WERR_UNKNOWN_PRINTER_DRIVER) &&
 984                     W_ERROR_V(result) != W_ERROR_V(WERR_INVALID_ENVIRONMENT)) {
 985                         printf("cannot get driver: %s\n", win_errstr(result));
 986                 }
 987                 return false;
 988         }
 989 
 990         return true;
 991 }
 992 
 993 
 994 static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
 995                              TALLOC_CTX *mem_ctx, uint32_t level,
 996                              union spoolss_DriverInfo *info)
 997 {
 998         WERROR result;
 999         NTSTATUS status;
1000         struct spoolss_AddDriverInfoCtr info_ctr;
1001 
1002         info_ctr.level = level;
1003 
1004         switch (level) {
1005         case 2:
1006                 info_ctr.info.info2 = (struct spoolss_AddDriverInfo2 *)&info->info2;
1007                 break;
1008         case 3:
1009                 info_ctr.info.info3 = (struct spoolss_AddDriverInfo3 *)&info->info3;
1010                 break;
1011         default:
1012                 printf("unsupported info level: %d\n", level);
1013                 return false;
1014         }
1015 
1016         /* addprinterdriver call */
1017         status = rpccli_spoolss_AddPrinterDriver(pipe_hnd, mem_ctx,
1018                                                  pipe_hnd->srv_name_slash,
1019                                                  &info_ctr,
1020                                                  &result);
1021         /* be more verbose */
1022         if (W_ERROR_V(result) == W_ERROR_V(WERR_ACCESS_DENIED)) {
1023                 printf("You are not allowed to add drivers\n");
1024                 return false;
1025         }
1026         if (!W_ERROR_IS_OK(result)) {
1027                 printf("cannot add driver: %s\n", win_errstr(result));
1028                 return false;
1029         }
1030 
1031         return true;
1032 }
1033 
1034 /**
1035  * abstraction function to get uint32_t num_printers and PRINTER_INFO_CTR ctr
1036  * for a single printer or for all printers depending on argc/argv
1037  **/
1038 
1039 static bool get_printer_info(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
1040                         TALLOC_CTX *mem_ctx,
1041                         int level,
1042                         int argc,
1043                         const char **argv,
1044                         uint32_t *num_printers,
1045                         union spoolss_PrinterInfo **info_p)
1046 {
1047         struct policy_handle hnd;
1048 
1049         /* no arguments given, enumerate all printers */
1050         if (argc == 0) {
1051 
1052                 if (!net_spoolss_enum_printers(pipe_hnd, mem_ctx, NULL,
1053                                 PRINTER_ENUM_LOCAL|PRINTER_ENUM_SHARED,
1054                                 level, num_printers, info_p))
1055                         return false;
1056 
1057                 goto out;
1058         }
1059 
1060         /* argument given, get a single printer by name */
1061         if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, argv[0],
1062                                          MAXIMUM_ALLOWED_ACCESS,
1063                                          pipe_hnd->auth->user_name,
1064                                          &hnd))
1065                 return false;
1066 
1067         if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, *info_p)) {
1068                 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL);
1069                 return false;
1070         }
1071 
1072         rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL);
1073 
1074         *num_printers = 1;
1075 
1076 out:
1077         DEBUG(3,("got %d printers\n", *num_printers));
1078 
1079         return true;
1080 
1081 }
1082 
1083 /**
1084  * List print-queues (including local printers that are not shared)
1085  *
1086  * All parameters are provided by the run_rpc_command function, except for
1087  * argc, argv which are passed through.
1088  *
1089  * @param c     A net_context structure
1090  * @param domain_sid The domain sid aquired from the remote server
1091  * @param cli A cli_state connected to the server.
1092  * @param mem_ctx Talloc context, destoyed on compleation of the function.
1093  * @param argc  Standard main() style argc
1094  * @param argv  Standard main() style argv.  Initial components are already
1095  *              stripped
1096  *
1097  * @return Normal NTSTATUS return.
1098  **/
1099 
1100 NTSTATUS rpc_printer_list_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
1101                                         const DOM_SID *domain_sid,
1102                                         const char *domain_name,
1103                                         struct cli_state *cli,
1104                                         struct rpc_pipe_client *pipe_hnd,
1105                                         TALLOC_CTX *mem_ctx,
1106                                         int argc,
1107                                         const char **argv)
1108 {
1109         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1110         uint32_t i, num_printers;
1111         uint32_t level = 2;
1112         const char *printername, *sharename;
1113         union spoolss_PrinterInfo *info;
1114 
1115         printf("listing printers\n");
1116 
1117         if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info))
1118                 return nt_status;
1119 
1120         for (i = 0; i < num_printers; i++) {
1121 
1122                 /* do some initialization */
1123                 printername = info[i].info2.printername;
1124                 sharename = info[i].info2.sharename;
1125 
1126                 if (printername && sharename) {
1127                         d_printf("printer %d: %s, shared as: %s\n",
1128                                 i+1, printername, sharename);
1129                 }
1130         }
1131 
1132         return NT_STATUS_OK;
1133 }
1134 
1135 /**
1136  * List printer-drivers from a server
1137  *
1138  * All parameters are provided by the run_rpc_command function, except for
1139  * argc, argv which are passed through.
1140  *
1141  * @param c     A net_context structure
1142  * @param domain_sid The domain sid aquired from the remote server
1143  * @param cli A cli_state connected to the server.
1144  * @param mem_ctx Talloc context, destoyed on compleation of the function.
1145  * @param argc  Standard main() style argc
1146  * @param argv  Standard main() style argv.  Initial components are already
1147  *              stripped
1148  *
1149  * @return Normal NTSTATUS return.
1150  **/
1151 
1152 NTSTATUS rpc_printer_driver_list_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
1153                                                 const DOM_SID *domain_sid,
1154                                                 const char *domain_name,
1155                                                 struct cli_state *cli,
1156                                                 struct rpc_pipe_client *pipe_hnd,
1157                                                 TALLOC_CTX *mem_ctx,
1158                                                 int argc,
1159                                                 const char **argv)
1160 {
1161         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1162         uint32_t i;
1163         uint32_t level = 3;
1164         union spoolss_DriverInfo *info;
1165         int d;
1166 
1167         printf("listing printer-drivers\n");
1168 
1169         for (i=0; archi_table[i].long_archi!=NULL; i++) {
1170 
1171                 uint32_t num_drivers;
1172 
1173                 /* enum remote drivers */
1174                 if (!net_spoolss_enumprinterdrivers(pipe_hnd, mem_ctx, level,
1175                                 archi_table[i].long_archi,
1176                                 &num_drivers, &info)) {
1177                         nt_status = NT_STATUS_UNSUCCESSFUL;
1178                         goto done;
1179                 }
1180 
1181                 if (num_drivers == 0) {
1182                         d_printf ("no drivers found on server for architecture: [%s].\n",
1183                                 archi_table[i].long_archi);
1184                         continue;
1185                 }
1186 
1187                 d_printf("got %d printer-drivers for architecture: [%s]\n",
1188                         num_drivers, archi_table[i].long_archi);
1189 
1190 
1191                 /* do something for all drivers for architecture */
1192                 for (d = 0; d < num_drivers; d++) {
1193                         display_print_driver3(&info[d].info3);
1194                 }
1195         }
1196 
1197         nt_status = NT_STATUS_OK;
1198 
1199 done:
1200         return nt_status;
1201 
1202 }
1203 
1204 /**
1205  * Publish print-queues with args-wrapper
1206  *
1207  * @param cli A cli_state connected to the server.
1208  * @param mem_ctx Talloc context, destoyed on compleation of the function.
1209  * @param argc  Standard main() style argc
1210  * @param argv  Standard main() style argv.  Initial components are already
1211  *              stripped
1212  * @param action
1213  *
1214  * @return Normal NTSTATUS return.
1215  **/
1216 
1217 static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_hnd,
     /* [<][>][^][v][top][bottom][index][help] */
1218                                         TALLOC_CTX *mem_ctx,
1219                                         int argc,
1220                                         const char **argv,
1221                                         uint32_t action)
1222 {
1223         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1224         uint32_t i, num_printers;
1225         uint32_t level = 7;
1226         const char *printername, *sharename;
1227         union spoolss_PrinterInfo *info_enum;
1228         union spoolss_PrinterInfo info;
1229         struct spoolss_SetPrinterInfoCtr info_ctr;
1230         struct spoolss_DevmodeContainer devmode_ctr;
1231         struct sec_desc_buf secdesc_ctr;
1232         struct policy_handle hnd;
1233         WERROR result;
1234         const char *action_str;
1235 
1236         if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum))
1237                 return nt_status;
1238 
1239         for (i = 0; i < num_printers; i++) {
1240 
1241                 /* do some initialization */
1242                 printername = info_enum[i].info2.printername;
1243                 sharename = info_enum[i].info2.sharename;
1244                 if (!printername || !sharename) {
1245                         goto done;
1246                 }
1247 
1248                 /* open printer handle */
1249                 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
1250                         PRINTER_ALL_ACCESS, pipe_hnd->auth->user_name, &hnd))
1251                         goto done;
1252 
1253                 /* check for existing dst printer */
1254                 if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info))
1255                         goto done;
1256 
1257                 /* check action and set string */
1258                 switch (action) {
1259                 case DSPRINT_PUBLISH:
1260                         action_str = "published";
1261                         break;
1262                 case DSPRINT_UPDATE:
1263                         action_str = "updated";
1264                         break;
1265                 case DSPRINT_UNPUBLISH:
1266                         action_str = "unpublished";
1267                         break;
1268                 default:
1269                         action_str = "unknown action";
1270                         printf("unkown action: %d\n", action);
1271                         break;
1272                 }
1273 
1274                 info.info7.action = action;
1275                 info_ctr.level = 7;
1276                 info_ctr.info.info7 = (struct spoolss_SetPrinterInfo7 *)&info.info7;
1277 
1278                 ZERO_STRUCT(devmode_ctr);
1279                 ZERO_STRUCT(secdesc_ctr);
1280 
1281                 nt_status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx,
1282                                                       &hnd,
1283                                                       &info_ctr,
1284                                                       &devmode_ctr,
1285                                                       &secdesc_ctr,
1286                                                       0, /* command */
1287                                                       &result);
1288 
1289                 if (!W_ERROR_IS_OK(result) && (W_ERROR_V(result) != W_ERROR_V(WERR_IO_PENDING))) {
1290                         printf("cannot set printer-info: %s\n", win_errstr(result));
1291                         goto done;
1292                 }
1293 
1294                 printf("successfully %s printer %s in Active Directory\n", action_str, sharename);
1295         }
1296 
1297         nt_status = NT_STATUS_OK;
1298 
1299 done:
1300         if (is_valid_policy_hnd(&hnd))
1301                 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL);
1302 
1303         return nt_status;
1304 }
1305 
1306 NTSTATUS rpc_printer_publish_publish_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
1307                                                 const DOM_SID *domain_sid,
1308                                                 const char *domain_name,
1309                                                 struct cli_state *cli,
1310                                                 struct rpc_pipe_client *pipe_hnd,
1311                                                 TALLOC_CTX *mem_ctx,
1312                                                 int argc,
1313                                                 const char **argv)
1314 {
1315         return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_PUBLISH);
1316 }
1317 
1318 NTSTATUS rpc_printer_publish_unpublish_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
1319                                                 const DOM_SID *domain_sid,
1320                                                 const char *domain_name,
1321                                                 struct cli_state *cli,
1322                                                 struct rpc_pipe_client *pipe_hnd,
1323                                                 TALLOC_CTX *mem_ctx,
1324                                                 int argc,
1325                                                 const char **argv)
1326 {
1327         return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_UNPUBLISH);
1328 }
1329 
1330 NTSTATUS rpc_printer_publish_update_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
1331                                                 const DOM_SID *domain_sid,
1332                                                 const char *domain_name,
1333                                                 struct cli_state *cli,
1334                                                 struct rpc_pipe_client *pipe_hnd,
1335                                                 TALLOC_CTX *mem_ctx,
1336                                                 int argc,
1337                                                 const char **argv)
1338 {
1339         return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_UPDATE);
1340 }
1341 
1342 /**
1343  * List print-queues w.r.t. their publishing state
1344  *
1345  * All parameters are provided by the run_rpc_command function, except for
1346  * argc, argv which are passed through.
1347  *
1348  * @param c     A net_context structure
1349  * @param domain_sid The domain sid aquired from the remote server
1350  * @param cli A cli_state connected to the server.
1351  * @param mem_ctx Talloc context, destoyed on compleation of the function.
1352  * @param argc  Standard main() style argc
1353  * @param argv  Standard main() style argv.  Initial components are already
1354  *              stripped
1355  *
1356  * @return Normal NTSTATUS return.
1357  **/
1358 
1359 NTSTATUS rpc_printer_publish_list_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
1360                                                 const DOM_SID *domain_sid,
1361                                                 const char *domain_name,
1362                                                 struct cli_state *cli,
1363                                                 struct rpc_pipe_client *pipe_hnd,
1364                                                 TALLOC_CTX *mem_ctx,
1365                                                 int argc,
1366                                                 const char **argv)
1367 {
1368         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1369         uint32_t i, num_printers;
1370         uint32_t level = 7;
1371         const char *printername, *sharename;
1372         union spoolss_PrinterInfo *info_enum;
1373         union spoolss_PrinterInfo info;
1374         struct policy_handle hnd;
1375         int state;
1376 
1377         if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum))
1378                 return nt_status;
1379 
1380         for (i = 0; i < num_printers; i++) {
1381 
1382                 /* do some initialization */
1383                 printername = info_enum[i].info2.printername;
1384                 sharename = info_enum[i].info2.sharename;
1385 
1386                 if (!printername || !sharename) {
1387                         goto done;
1388                 }
1389 
1390                 /* open printer handle */
1391                 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
1392                         PRINTER_ALL_ACCESS, cli->user_name, &hnd))
1393                         goto done;
1394 
1395                 /* check for existing dst printer */
1396                 if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info))
1397                         goto done;
1398 
1399                 if (!info.info7.guid) {
1400                         goto done;
1401                 }
1402                 state = info.info7.action;
1403                 switch (state) {
1404                         case DSPRINT_PUBLISH:
1405                                 printf("printer [%s] is published", sharename);
1406                                 if (c->opt_verbose)
1407                                         printf(", guid: %s", info.info7.guid);
1408                                 printf("\n");
1409                                 break;
1410                         case DSPRINT_UNPUBLISH:
1411                                 printf("printer [%s] is unpublished\n", sharename);
1412                                 break;
1413                         case DSPRINT_UPDATE:
1414                                 printf("printer [%s] is currently updating\n", sharename);
1415                                 break;
1416                         default:
1417                                 printf("unkown state: %d\n", state);
1418                                 break;
1419                 }
1420         }
1421 
1422         nt_status = NT_STATUS_OK;
1423 
1424 done:
1425         if (is_valid_policy_hnd(&hnd))
1426                 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL);
1427 
1428         return nt_status;
1429 }
1430 
1431 /**
1432  * Migrate Printer-ACLs from a source server to the destination server
1433  *
1434  * All parameters are provided by the run_rpc_command function, except for
1435  * argc, argv which are passed through.
1436  *
1437  * @param c     A net_context structure
1438  * @param domain_sid The domain sid aquired from the remote server
1439  * @param cli A cli_state connected to the server.
1440  * @param mem_ctx Talloc context, destoyed on compleation of the function.
1441  * @param argc  Standard main() style argc
1442  * @param argv  Standard main() style argv.  Initial components are already
1443  *              stripped
1444  *
1445  * @return Normal NTSTATUS return.
1446  **/
1447 
1448 NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
1449                                                 const DOM_SID *domain_sid,
1450                                                 const char *domain_name,
1451                                                 struct cli_state *cli,
1452                                                 struct rpc_pipe_client *pipe_hnd,
1453                                                 TALLOC_CTX *mem_ctx,
1454                                                 int argc,
1455                                                 const char **argv)
1456 {
1457         /* TODO: what now, info2 or info3 ?
1458            convince jerry that we should add clientside setacls level 3 at least
1459         */
1460         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1461         uint32_t i = 0;
1462         uint32_t num_printers;
1463         uint32_t level = 2;
1464         const char *printername, *sharename;
1465         struct rpc_pipe_client *pipe_hnd_dst = NULL;
1466         struct policy_handle hnd_src, hnd_dst;
1467         union spoolss_PrinterInfo *info_enum;
1468         struct cli_state *cli_dst = NULL;
1469         union spoolss_PrinterInfo info_src, info_dst;
1470 
1471         DEBUG(3,("copying printer ACLs\n"));
1472 
1473         /* connect destination PI_SPOOLSS */
1474         nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
1475                                      &ndr_table_spoolss.syntax_id);
1476         if (!NT_STATUS_IS_OK(nt_status))
1477                 return nt_status;
1478 
1479 
1480         /* enum source printers */
1481         if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) {
1482                 nt_status = NT_STATUS_UNSUCCESSFUL;
1483                 goto done;
1484         }
1485 
1486         if (!num_printers) {
1487                 printf ("no printers found on server.\n");
1488                 nt_status = NT_STATUS_OK;
1489                 goto done;
1490         }
1491 
1492         /* do something for all printers */
1493         for (i = 0; i < num_printers; i++) {
1494 
1495                 /* do some initialization */
1496                 printername = info_enum[i].info2.printername;
1497                 sharename = info_enum[i].info2.sharename;
1498 
1499                 if (!printername || !sharename) {
1500                         nt_status = NT_STATUS_UNSUCCESSFUL;
1501                         goto done;
1502                 }
1503 
1504                 /* we can reset NT_STATUS here because we do not
1505                    get any real NT_STATUS-codes anymore from now on */
1506                 nt_status = NT_STATUS_UNSUCCESSFUL;
1507 
1508                 d_printf("migrating printer ACLs for:     [%s] / [%s]\n",
1509                         printername, sharename);
1510 
1511                 /* according to msdn you have specify these access-rights
1512                    to see the security descriptor
1513                         - READ_CONTROL (DACL)
1514                         - ACCESS_SYSTEM_SECURITY (SACL)
1515                 */
1516 
1517                 /* open src printer handle */
1518                 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
1519                         MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
1520                         goto done;
1521 
1522                 /* open dst printer handle */
1523                 if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
1524                         PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst))
1525                         goto done;
1526 
1527                 /* check for existing dst printer */
1528                 if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst))
1529                         goto done;
1530 
1531                 /* check for existing src printer */
1532                 if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, 3, &info_src))
1533                         goto done;
1534 
1535                 /* Copy Security Descriptor */
1536 
1537                 /* copy secdesc (info level 2) */
1538                 info_dst.info2.devmode = NULL;
1539                 info_dst.info2.secdesc = dup_sec_desc(mem_ctx, info_src.info3.secdesc);
1540 
1541                 if (c->opt_verbose)
1542                         display_sec_desc(info_dst.info2.secdesc);
1543 
1544                 if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst))
1545                         goto done;
1546 
1547                 DEBUGADD(1,("\tSetPrinter of SECDESC succeeded\n"));
1548 
1549 
1550                 /* close printer handles here */
1551                 if (is_valid_policy_hnd(&hnd_src)) {
1552                         rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
1553                 }
1554 
1555                 if (is_valid_policy_hnd(&hnd_dst)) {
1556                         rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
1557                 }
1558 
1559         }
1560 
1561         nt_status = NT_STATUS_OK;
1562 
1563 done:
1564 
1565         if (is_valid_policy_hnd(&hnd_src)) {
1566                 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
1567         }
1568 
1569         if (is_valid_policy_hnd(&hnd_dst)) {
1570                 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
1571         }
1572 
1573         if (cli_dst) {
1574                 cli_shutdown(cli_dst);
1575         }
1576         return nt_status;
1577 }
1578 
1579 /**
1580  * Migrate printer-forms from a src server to the dst server
1581  *
1582  * All parameters are provided by the run_rpc_command function, except for
1583  * argc, argv which are passed through.
1584  *
1585  * @param c     A net_context structure
1586  * @param domain_sid The domain sid aquired from the remote server
1587  * @param cli A cli_state connected to the server.
1588  * @param mem_ctx Talloc context, destoyed on compleation of the function.
1589  * @param argc  Standard main() style argc
1590  * @param argv  Standard main() style argv.  Initial components are already
1591  *              stripped
1592  *
1593  * @return Normal NTSTATUS return.
1594  **/
1595 
1596 NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
1597                                                 const DOM_SID *domain_sid,
1598                                                 const char *domain_name,
1599                                                 struct cli_state *cli,
1600                                                 struct rpc_pipe_client *pipe_hnd,
1601                                                 TALLOC_CTX *mem_ctx,
1602                                                 int argc,
1603                                                 const char **argv)
1604 {
1605         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1606         WERROR result;
1607         uint32_t i, f;
1608         uint32_t num_printers;
1609         uint32_t level = 1;
1610         const char *printername, *sharename;
1611         struct rpc_pipe_client *pipe_hnd_dst = NULL;
1612         struct policy_handle hnd_src, hnd_dst;
1613         union spoolss_PrinterInfo *info_enum;
1614         union spoolss_PrinterInfo info_dst;
1615         uint32_t num_forms;
1616         union spoolss_FormInfo *forms;
1617         struct cli_state *cli_dst = NULL;
1618 
1619         DEBUG(3,("copying forms\n"));
1620 
1621         /* connect destination PI_SPOOLSS */
1622         nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
1623                                      &ndr_table_spoolss.syntax_id);
1624         if (!NT_STATUS_IS_OK(nt_status))
1625                 return nt_status;
1626 
1627         /* enum src printers */
1628         if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum)) {
1629                 nt_status = NT_STATUS_UNSUCCESSFUL;
1630                 goto done;
1631         }
1632 
1633         if (!num_printers) {
1634                 printf ("no printers found on server.\n");
1635                 nt_status = NT_STATUS_OK;
1636                 goto done;
1637         }
1638 
1639         /* do something for all printers */
1640         for (i = 0; i < num_printers; i++) {
1641 
1642                 /* do some initialization */
1643                 printername = info_enum[i].info2.printername;
1644                 sharename = info_enum[i].info2.sharename;
1645 
1646                 if (!printername || !sharename) {
1647                         nt_status = NT_STATUS_UNSUCCESSFUL;
1648                         goto done;
1649                 }
1650                 /* we can reset NT_STATUS here because we do not
1651                    get any real NT_STATUS-codes anymore from now on */
1652                 nt_status = NT_STATUS_UNSUCCESSFUL;
1653 
1654                 d_printf("migrating printer forms for:    [%s] / [%s]\n",
1655                         printername, sharename);
1656 
1657 
1658                 /* open src printer handle */
1659                 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
1660                         MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
1661                         goto done;
1662 
1663                 /* open dst printer handle */
1664                 if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
1665                         PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst))
1666                         goto done;
1667 
1668                 /* check for existing dst printer */
1669                 if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst))
1670                         goto done;
1671 
1672                 /* finally migrate forms */
1673                 if (!net_spoolss_enumforms(pipe_hnd, mem_ctx, &hnd_src, level, &num_forms, &forms))
1674                         goto done;
1675 
1676                 DEBUG(1,("got %d forms for printer\n", num_forms));
1677 
1678 
1679                 for (f = 0; f < num_forms; f++) {
1680 
1681                         union spoolss_AddFormInfo info;
1682                         NTSTATUS status;
1683 
1684                         /* only migrate FORM_PRINTER types, according to jerry
1685                            FORM_BUILTIN-types are hard-coded in samba */
1686                         if (forms[f].info1.flags != SPOOLSS_FORM_PRINTER)
1687                                 continue;
1688 
1689                         if (c->opt_verbose)
1690                                 d_printf("\tmigrating form # %d [%s] of type [%d]\n",
1691                                         f, forms[f].info1.form_name,
1692                                         forms[f].info1.flags);
1693 
1694                         info.info1 = (struct spoolss_AddFormInfo1 *)&forms[f].info1;
1695 
1696                         /* FIXME: there might be something wrong with samba's
1697                            builtin-forms */
1698                         status = rpccli_spoolss_AddForm(pipe_hnd_dst, mem_ctx,
1699                                                         &hnd_dst,
1700                                                         1,
1701                                                         info,
1702                                                         &result);
1703                         if (!W_ERROR_IS_OK(result)) {
1704                                 d_printf("\tAddForm form %d: [%s] refused.\n",
1705                                         f, forms[f].info1.form_name);
1706                                 continue;
1707                         }
1708 
1709                         DEBUGADD(1,("\tAddForm of [%s] succeeded\n",
1710                                 forms[f].info1.form_name));
1711                 }
1712 
1713 
1714                 /* close printer handles here */
1715                 if (is_valid_policy_hnd(&hnd_src)) {
1716                         rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
1717                 }
1718 
1719                 if (is_valid_policy_hnd(&hnd_dst)) {
1720                         rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
1721                 }
1722         }
1723 
1724         nt_status = NT_STATUS_OK;
1725 
1726 done:
1727 
1728         if (is_valid_policy_hnd(&hnd_src))
1729                 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
1730 
1731         if (is_valid_policy_hnd(&hnd_dst))
1732                 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
1733 
1734         if (cli_dst) {
1735                 cli_shutdown(cli_dst);
1736         }
1737         return nt_status;
1738 }
1739 
1740 /**
1741  * Migrate printer-drivers from a src server to the dst server
1742  *
1743  * All parameters are provided by the run_rpc_command function, except for
1744  * argc, argv which are passed through.
1745  *
1746  * @param c     A net_context structure
1747  * @param domain_sid The domain sid aquired from the remote server
1748  * @param cli A cli_state connected to the server.
1749  * @param mem_ctx Talloc context, destoyed on compleation of the function.
1750  * @param argc  Standard main() style argc
1751  * @param argv  Standard main() style argv.  Initial components are already
1752  *              stripped
1753  *
1754  * @return Normal NTSTATUS return.
1755  **/
1756 
1757 NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
1758                                                 const DOM_SID *domain_sid,
1759                                                 const char *domain_name,
1760                                                 struct cli_state *cli,
1761                                                 struct rpc_pipe_client *pipe_hnd,
1762                                                 TALLOC_CTX *mem_ctx,
1763                                                 int argc,
1764                                                 const char **argv)
1765 {
1766         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1767         uint32_t i, p;
1768         uint32_t num_printers;
1769         uint32_t level = 3;
1770         const char *printername, *sharename;
1771         bool got_src_driver_share = false;
1772         bool got_dst_driver_share = false;
1773         struct rpc_pipe_client *pipe_hnd_dst = NULL;
1774         struct policy_handle hnd_src, hnd_dst;
1775         union spoolss_DriverInfo drv_info_src;
1776         union spoolss_PrinterInfo *info_enum;
1777         union spoolss_PrinterInfo info_dst;
1778         struct cli_state *cli_dst = NULL;
1779         struct cli_state *cli_share_src = NULL;
1780         struct cli_state *cli_share_dst = NULL;
1781         const char *drivername = NULL;
1782 
1783         DEBUG(3,("copying printer-drivers\n"));
1784 
1785         nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
1786                                      &ndr_table_spoolss.syntax_id);
1787         if (!NT_STATUS_IS_OK(nt_status))
1788                 return nt_status;
1789 
1790         /* open print$-share on the src server */
1791         nt_status = connect_to_service(c, &cli_share_src, &cli->dest_ss,
1792                         cli->desthost, "print$", "A:");
1793         if (!NT_STATUS_IS_OK(nt_status))
1794                 goto done;
1795 
1796         got_src_driver_share = true;
1797 
1798 
1799         /* open print$-share on the dst server */
1800         nt_status = connect_to_service(c, &cli_share_dst, &cli_dst->dest_ss,
1801                         cli_dst->desthost, "print$", "A:");
1802         if (!NT_STATUS_IS_OK(nt_status))
1803                 return nt_status;
1804 
1805         got_dst_driver_share = true;
1806 
1807 
1808         /* enum src printers */
1809         if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &info_enum)) {
1810                 nt_status = NT_STATUS_UNSUCCESSFUL;
1811                 goto done;
1812         }
1813 
1814         if (num_printers == 0) {
1815                 printf ("no printers found on server.\n");
1816                 nt_status = NT_STATUS_OK;
1817                 goto done;
1818         }
1819 
1820 
1821         /* do something for all printers */
1822         for (p = 0; p < num_printers; p++) {
1823 
1824                 /* do some initialization */
1825                 printername = info_enum[p].info2.printername;
1826                 sharename = info_enum[p].info2.sharename;
1827 
1828                 if (!printername || !sharename) {
1829                         nt_status = NT_STATUS_UNSUCCESSFUL;
1830                         goto done;
1831                 }
1832 
1833                 /* we can reset NT_STATUS here because we do not
1834                    get any real NT_STATUS-codes anymore from now on */
1835                 nt_status = NT_STATUS_UNSUCCESSFUL;
1836 
1837                 d_printf("migrating printer driver for:   [%s] / [%s]\n",
1838                         printername, sharename);
1839 
1840                 /* open dst printer handle */
1841                 if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
1842                         PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst))
1843                         goto done;
1844 
1845                 /* check for existing dst printer */
1846                 if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst))
1847                         goto done;
1848 
1849 
1850                 /* open src printer handle */
1851                 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
1852                                                  MAXIMUM_ALLOWED_ACCESS,
1853                                                  pipe_hnd->auth->user_name,
1854                                                  &hnd_src))
1855                         goto done;
1856 
1857                 /* in a first step call getdriver for each shared printer (per arch)
1858                    to get a list of all files that have to be copied */
1859 
1860                 for (i=0; archi_table[i].long_archi!=NULL; i++) {
1861 
1862                         /* getdriver src */
1863                         if (!net_spoolss_getprinterdriver(pipe_hnd, mem_ctx, &hnd_src,
1864                                         level, archi_table[i].long_archi,
1865                                         archi_table[i].version, &drv_info_src))
1866                                 continue;
1867 
1868                         drivername = drv_info_src.info3.driver_name;
1869 
1870                         if (c->opt_verbose)
1871                                 display_print_driver3(&drv_info_src.info3);
1872 
1873                         /* check arch dir */
1874                         nt_status = check_arch_dir(cli_share_dst, archi_table[i].short_archi);
1875                         if (!NT_STATUS_IS_OK(nt_status))
1876                                 goto done;
1877 
1878 
1879                         /* copy driver-files */
1880                         nt_status = copy_print_driver_3(c, mem_ctx, cli_share_src, cli_share_dst,
1881                                                         archi_table[i].short_archi,
1882                                                         &drv_info_src.info3);
1883                         if (!NT_STATUS_IS_OK(nt_status))
1884                                 goto done;
1885 
1886 
1887                         /* adddriver dst */
1888                         if (!net_spoolss_addprinterdriver(pipe_hnd_dst, mem_ctx, level, &drv_info_src)) {
1889                                 nt_status = NT_STATUS_UNSUCCESSFUL;
1890                                 goto done;
1891                         }
1892 
1893                         DEBUGADD(1,("Sucessfully added driver [%s] for printer [%s]\n",
1894                                 drivername, printername));
1895 
1896                 }
1897 
1898                 if (!drivername || strlen(drivername) == 0) {
1899                         DEBUGADD(1,("Did not get driver for printer %s\n",
1900                                     printername));
1901                         goto done;
1902                 }
1903 
1904                 /* setdriver dst */
1905                 info_dst.info2.drivername = drivername;
1906 
1907                 if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) {
1908                         nt_status = NT_STATUS_UNSUCCESSFUL;
1909                         goto done;
1910                 }
1911 
1912                 DEBUGADD(1,("Sucessfully set driver %s for printer %s\n",
1913                         drivername, printername));
1914 
1915                 /* close dst */
1916                 if (is_valid_policy_hnd(&hnd_dst)) {
1917                         rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
1918                 }
1919 
1920                 /* close src */
1921                 if (is_valid_policy_hnd(&hnd_src)) {
1922                         rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
1923                 }
1924         }
1925 
1926         nt_status = NT_STATUS_OK;
1927 
1928 done:
1929 
1930         if (is_valid_policy_hnd(&hnd_src))
1931                 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
1932 
1933         if (is_valid_policy_hnd(&hnd_dst))
1934                 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
1935 
1936         if (cli_dst) {
1937                 cli_shutdown(cli_dst);
1938         }
1939 
1940         if (got_src_driver_share)
1941                 cli_shutdown(cli_share_src);
1942 
1943         if (got_dst_driver_share)
1944                 cli_shutdown(cli_share_dst);
1945 
1946         return nt_status;
1947 
1948 }
1949 
1950 /**
1951  * Migrate printer-queues from a src to the dst server
1952  * (requires a working "addprinter command" to be installed for the local smbd)
1953  *
1954  * All parameters are provided by the run_rpc_command function, except for
1955  * argc, argv which are passed through.
1956  *
1957  * @param c     A net_context structure
1958  * @param domain_sid The domain sid aquired from the remote server
1959  * @param cli A cli_state connected to the server.
1960  * @param mem_ctx Talloc context, destoyed on compleation of the function.
1961  * @param argc  Standard main() style argc
1962  * @param argv  Standard main() style argv.  Initial components are already
1963  *              stripped
1964  *
1965  * @return Normal NTSTATUS return.
1966  **/
1967 
1968 NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
1969                                                 const DOM_SID *domain_sid,
1970                                                 const char *domain_name,
1971                                                 struct cli_state *cli,
1972                                                 struct rpc_pipe_client *pipe_hnd,
1973                                                 TALLOC_CTX *mem_ctx,
1974                                                 int argc,
1975                                                 const char **argv)
1976 {
1977         WERROR result;
1978         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
1979         uint32_t i = 0, num_printers;
1980         uint32_t level = 2;
1981         union spoolss_PrinterInfo info_dst, info_src;
1982         union spoolss_PrinterInfo *info_enum;
1983         struct cli_state *cli_dst = NULL;
1984         struct policy_handle hnd_dst, hnd_src;
1985         const char *printername, *sharename;
1986         struct rpc_pipe_client *pipe_hnd_dst = NULL;
1987         struct spoolss_SetPrinterInfoCtr info_ctr;
1988 
1989         DEBUG(3,("copying printers\n"));
1990 
1991         /* connect destination PI_SPOOLSS */
1992         nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
1993                                      &ndr_table_spoolss.syntax_id);
1994         if (!NT_STATUS_IS_OK(nt_status))
1995                 return nt_status;
1996 
1997         /* enum printers */
1998         if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) {
1999                 nt_status = NT_STATUS_UNSUCCESSFUL;
2000                 goto done;
2001         }
2002 
2003         if (!num_printers) {
2004                 printf ("no printers found on server.\n");
2005                 nt_status = NT_STATUS_OK;
2006                 goto done;
2007         }
2008 
2009         /* do something for all printers */
2010         for (i = 0; i < num_printers; i++) {
2011 
2012                 /* do some initialization */
2013                 printername = info_enum[i].info2.printername;
2014                 sharename = info_enum[i].info2.sharename;
2015 
2016                 if (!printername || !sharename) {
2017                         nt_status = NT_STATUS_UNSUCCESSFUL;
2018                         goto done;
2019                 }
2020                 /* we can reset NT_STATUS here because we do not
2021                    get any real NT_STATUS-codes anymore from now on */
2022                 nt_status = NT_STATUS_UNSUCCESSFUL;
2023 
2024                 d_printf("migrating printer queue for:    [%s] / [%s]\n",
2025                         printername, sharename);
2026 
2027                 /* open dst printer handle */
2028                 if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
2029                         PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) {
2030 
2031                         DEBUG(1,("could not open printer: %s\n", sharename));
2032                 }
2033 
2034                 /* check for existing dst printer */
2035                 if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) {
2036                         printf ("could not get printer, creating printer.\n");
2037                 } else {
2038                         DEBUG(1,("printer already exists: %s\n", sharename));
2039                         /* close printer handle here - dst only, not got src yet. */
2040                         if (is_valid_policy_hnd(&hnd_dst)) {
2041                                 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
2042                         }
2043                         continue;
2044                 }
2045 
2046                 /* now get again src printer ctr via getprinter,
2047                    we first need a handle for that */
2048 
2049                 /* open src printer handle */
2050                 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
2051                         MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
2052                         goto done;
2053 
2054                 /* getprinter on the src server */
2055                 if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &info_src))
2056                         goto done;
2057 
2058                 /* copy each src printer to a dst printer 1:1,
2059                    maybe some values have to be changed though */
2060                 d_printf("creating printer: %s\n", printername);
2061 
2062                 info_ctr.level = level;
2063                 info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info_src.info2;
2064 
2065                 result = rpccli_spoolss_addprinterex(pipe_hnd_dst,
2066                                                      mem_ctx,
2067                                                      &info_ctr);
2068 
2069                 if (W_ERROR_IS_OK(result))
2070                         d_printf ("printer [%s] successfully added.\n", printername);
2071                 else if (W_ERROR_V(result) == W_ERROR_V(WERR_PRINTER_ALREADY_EXISTS))
2072                         d_fprintf (stderr, "printer [%s] already exists.\n", printername);
2073                 else {
2074                         d_fprintf (stderr, "could not create printer [%s]\n", printername);
2075                         goto done;
2076                 }
2077 
2078                 /* close printer handles here */
2079                 if (is_valid_policy_hnd(&hnd_src)) {
2080                         rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
2081                 }
2082 
2083                 if (is_valid_policy_hnd(&hnd_dst)) {
2084                         rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
2085                 }
2086         }
2087 
2088         nt_status = NT_STATUS_OK;
2089 
2090 done:
2091         if (is_valid_policy_hnd(&hnd_src))
2092                 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
2093 
2094         if (is_valid_policy_hnd(&hnd_dst))
2095                 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
2096 
2097         if (cli_dst) {
2098                 cli_shutdown(cli_dst);
2099         }
2100         return nt_status;
2101 }
2102 
2103 /**
2104  * Migrate Printer-Settings from a src server to the dst server
2105  * (for this to work, printers and drivers already have to be migrated earlier)
2106  *
2107  * All parameters are provided by the run_rpc_command function, except for
2108  * argc, argv which are passed through.
2109  *
2110  * @param c     A net_context structure
2111  * @param domain_sid The domain sid aquired from the remote server
2112  * @param cli A cli_state connected to the server.
2113  * @param mem_ctx Talloc context, destoyed on compleation of the function.
2114  * @param argc  Standard main() style argc
2115  * @param argv  Standard main() style argv.  Initial components are already
2116  *              stripped
2117  *
2118  * @return Normal NTSTATUS return.
2119  **/
2120 
2121 NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
2122                                                 const DOM_SID *domain_sid,
2123                                                 const char *domain_name,
2124                                                 struct cli_state *cli,
2125                                                 struct rpc_pipe_client *pipe_hnd,
2126                                                 TALLOC_CTX *mem_ctx,
2127                                                 int argc,
2128                                                 const char **argv)
2129 {
2130 
2131         /* FIXME: Here the nightmare begins */
2132 
2133         WERROR result;
2134         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
2135         uint32_t i = 0, p = 0, j = 0;
2136         uint32_t num_printers;
2137         uint32_t level = 2;
2138         const char *printername, *sharename;
2139         struct rpc_pipe_client *pipe_hnd_dst = NULL;
2140         struct policy_handle hnd_src, hnd_dst;
2141         union spoolss_PrinterInfo *info_enum;
2142         union spoolss_PrinterInfo info_dst_publish;
2143         union spoolss_PrinterInfo info_dst;
2144         struct cli_state *cli_dst = NULL;
2145         char *devicename = NULL, *unc_name = NULL, *url = NULL;
2146         const char *longname;
2147         const char **keylist = NULL;
2148 
2149         /* FIXME GD */
2150         ZERO_STRUCT(info_dst_publish);
2151 
2152         DEBUG(3,("copying printer settings\n"));
2153 
2154         /* connect destination PI_SPOOLSS */
2155         nt_status = connect_dst_pipe(c, &cli_dst, &pipe_hnd_dst,
2156                                      &ndr_table_spoolss.syntax_id);
2157         if (!NT_STATUS_IS_OK(nt_status))
2158                 return nt_status;
2159 
2160         /* enum src printers */
2161         if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &info_enum)) {
2162                 nt_status = NT_STATUS_UNSUCCESSFUL;
2163                 goto done;
2164         }
2165 
2166         if (!num_printers) {
2167                 printf ("no printers found on server.\n");
2168                 nt_status = NT_STATUS_OK;
2169                 goto done;
2170         }
2171 
2172 
2173         /* needed for dns-strings in regkeys */
2174         longname = get_mydnsfullname();
2175         if (!longname) {
2176                 nt_status = NT_STATUS_UNSUCCESSFUL;
2177                 goto done;
2178         }
2179 
2180         /* do something for all printers */
2181         for (i = 0; i < num_printers; i++) {
2182 
2183                 uint32_t value_offered = 0, value_needed;
2184                 uint32_t data_offered = 0, data_needed;
2185                 enum winreg_Type type;
2186                 uint8_t *buffer = NULL;
2187                 const char *value_name = NULL;
2188 
2189                 /* do some initialization */
2190                 printername = info_enum[i].info2.printername;
2191                 sharename = info_enum[i].info2.sharename;
2192 
2193                 if (!printername || !sharename) {
2194                         nt_status = NT_STATUS_UNSUCCESSFUL;
2195                         goto done;
2196                 }
2197                 /* we can reset NT_STATUS here because we do not
2198                    get any real NT_STATUS-codes anymore from now on */
2199                 nt_status = NT_STATUS_UNSUCCESSFUL;
2200 
2201                 d_printf("migrating printer settings for: [%s] / [%s]\n",
2202                         printername, sharename);
2203 
2204 
2205                 /* open src printer handle */
2206                 if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename,
2207                         MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src))
2208                         goto done;
2209 
2210                 /* open dst printer handle */
2211                 if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename,
2212                         PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst))
2213                         goto done;
2214 
2215                 /* check for existing dst printer */
2216                 if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst,
2217                                 level, &info_dst))
2218                         goto done;
2219 
2220 
2221                 /* STEP 1: COPY DEVICE-MODE and other
2222                            PRINTER_INFO_2-attributes
2223                 */
2224 
2225                 info_dst.info2 = info_enum[i].info2;
2226 
2227                 /* why is the port always disconnected when the printer
2228                    is correctly installed (incl. driver ???) */
2229                 info_dst.info2.portname = SAMBA_PRINTER_PORT_NAME;
2230 
2231                 /* check if printer is published */
2232                 if (info_enum[i].info2.attributes & PRINTER_ATTRIBUTE_PUBLISHED) {
2233 
2234                         /* check for existing dst printer */
2235                         if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish))
2236                                 goto done;
2237 
2238                         info_dst_publish.info7.action = DSPRINT_PUBLISH;
2239 
2240                         /* ignore false from setprinter due to WERR_IO_PENDING */
2241                         net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish);
2242 
2243                         DEBUG(3,("republished printer\n"));
2244                 }
2245 
2246                 if (info_enum[i].info2.devmode != NULL) {
2247 
2248                         /* copy devmode (info level 2) */
2249                         info_dst.info2.devmode = info_enum[i].info2.devmode;
2250 
2251                         /* do not copy security descriptor (we have another
2252                          * command for that) */
2253                         info_dst.info2.secdesc = NULL;
2254 
2255 #if 0
2256                         info_dst.info2.devmode.devicename =
2257                                 talloc_asprintf(mem_ctx, "\\\\%s\\%s",
2258                                                 longname, printername);
2259                         if (!info_dst.info2.devmode.devicename) {
2260                                 nt_status = NT_STATUS_NO_MEMORY;
2261                                 goto done;
2262                         }
2263 #endif
2264                         if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst,
2265                                                     level, &info_dst))
2266                                 goto done;
2267 
2268                         DEBUGADD(1,("\tSetPrinter of DEVICEMODE succeeded\n"));
2269                 }
2270 
2271                 /* STEP 2: COPY REGISTRY VALUES */
2272 
2273                 /* please keep in mind that samba parse_spools gives horribly
2274                    crippled results when used to rpccli_spoolss_enumprinterdataex
2275                    a win2k3-server.  (Bugzilla #1851)
2276                    FIXME: IIRC I've seen it too on a win2k-server
2277                 */
2278 
2279                 /* enumerate data on src handle */
2280                 nt_status = rpccli_spoolss_EnumPrinterData(pipe_hnd, mem_ctx,
2281                                                            &hnd_src,
2282                                                            p,
2283                                                            value_name,
2284                                                            value_offered,
2285                                                            &value_needed,
2286                                                            &type,
2287                                                            buffer,
2288                                                            data_offered,
2289                                                            &data_needed,
2290                                                            &result);
2291 
2292                 data_offered    = data_needed;
2293                 value_offered   = value_needed;
2294                 buffer          = talloc_zero_array(mem_ctx, uint8_t, data_needed);
2295                 value_name      = talloc_zero_array(mem_ctx, char, value_needed);
2296 
2297                 /* loop for all printerdata of "PrinterDriverData" */
2298                 while (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(result)) {
2299 
2300                         nt_status = rpccli_spoolss_EnumPrinterData(pipe_hnd, mem_ctx,
2301                                                                    &hnd_src,
2302                                                                    p++,
2303                                                                    value_name,
2304                                                                    value_offered,
2305                                                                    &value_needed,
2306                                                                    &type,
2307                                                                    buffer,
2308                                                                    data_offered,
2309                                                                    &data_needed,
2310                                                                    &result);
2311                         /* loop for all reg_keys */
2312                         if (NT_STATUS_IS_OK(nt_status) && W_ERROR_IS_OK(result)) {
2313 
2314                                 REGISTRY_VALUE v;
2315                                 DATA_BLOB blob;
2316                                 union spoolss_PrinterData printer_data;
2317 
2318                                 /* display_value */
2319                                 if (c->opt_verbose) {
2320                                         fstrcpy(v.valuename, value_name);
2321                                         v.type = type;
2322                                         v.size = data_offered;
2323                                         v.data_p = buffer;
2324                                         display_reg_value(SPOOL_PRINTERDATA_KEY, v);
2325                                 }
2326 
2327                                 result = pull_spoolss_PrinterData(mem_ctx,
2328                                                                   &blob,
2329                                                                   &printer_data,
2330                                                                   type);
2331                                 if (!W_ERROR_IS_OK(result)) {
2332                                         goto done;
2333                                 }
2334 
2335                                 /* set_value */
2336                                 if (!net_spoolss_setprinterdata(pipe_hnd_dst, mem_ctx,
2337                                                                 &hnd_dst, value_name,
2338                                                                 type, printer_data))
2339                                         goto done;
2340 
2341                                 DEBUGADD(1,("\tSetPrinterData of [%s] succeeded\n",
2342                                         v.valuename));
2343                         }
2344                 }
2345 
2346                 /* STEP 3: COPY SUBKEY VALUES */
2347 
2348                 /* here we need to enum all printer_keys and then work
2349                    on the result with enum_printer_key_ex. nt4 does not
2350                    respond to enumprinterkey, win2k does, so continue
2351                    in case of an error */
2352 
2353                 if (!net_spoolss_enumprinterkey(pipe_hnd, mem_ctx, &hnd_src, "", &keylist)) {
2354                         printf("got no key-data\n");
2355                         continue;
2356                 }
2357 
2358 
2359                 /* work on a list of printer keys
2360                    each key has to be enumerated to get all required
2361                    information.  information is then set via setprinterdataex-calls */
2362 
2363                 if (keylist == NULL)
2364                         continue;
2365 
2366                 for (i=0; keylist && keylist[i] != NULL; i++) {
2367 
2368                         const char *subkey = keylist[i];
2369                         uint32_t count;
2370                         struct spoolss_PrinterEnumValues *info;
2371 
2372                         /* enumerate all src subkeys */
2373                         if (!net_spoolss_enumprinterdataex(pipe_hnd, mem_ctx, 0,
2374                                                            &hnd_src, subkey,
2375                                                            &count, &info)) {
2376                                 goto done;
2377                         }
2378 
2379                         for (j=0; j < count; j++) {
2380 
2381                                 REGISTRY_VALUE value;
2382                                 UNISTR2 data;
2383 
2384                                 /* although samba replies with sane data in most cases we
2385                                    should try to avoid writing wrong registry data */
2386 
2387                                 if (strequal(info[j].value_name, SPOOL_REG_PORTNAME) ||
2388                                     strequal(info[j].value_name, SPOOL_REG_UNCNAME) ||
2389                                     strequal(info[j].value_name, SPOOL_REG_URL) ||
2390                                     strequal(info[j].value_name, SPOOL_REG_SHORTSERVERNAME) ||
2391                                     strequal(info[j].value_name, SPOOL_REG_SERVERNAME)) {
2392 
2393                                         if (strequal(info[j].value_name, SPOOL_REG_PORTNAME)) {
2394 
2395                                                 /* although windows uses a multi-sz, we use a sz */
2396                                                 init_unistr2(&data, SAMBA_PRINTER_PORT_NAME, UNI_STR_TERMINATE);
2397                                                 fstrcpy(value.valuename, SPOOL_REG_PORTNAME);
2398                                         }
2399 
2400                                         if (strequal(info[j].value_name, SPOOL_REG_UNCNAME)) {
2401 
2402                                                 if (asprintf(&unc_name, "\\\\%s\\%s", longname, sharename) < 0) {
2403                                                         nt_status = NT_STATUS_NO_MEMORY;
2404                                                         goto done;
2405                                                 }
2406                                                 init_unistr2(&data, unc_name, UNI_STR_TERMINATE);
2407                                                 fstrcpy(value.valuename, SPOOL_REG_UNCNAME);
2408                                         }
2409 
2410                                         if (strequal(info[j].value_name, SPOOL_REG_URL)) {
2411 
2412                                                 continue;
2413 
2414 #if 0
2415                                                 /* FIXME: should we really do that ??? */
2416                                                 if (asprintf(&url, "http://%s:631/printers/%s", longname, sharename) < 0) {
2417                                                         nt_status = NT_STATUS_NO_MEMORY;
2418                                                         goto done;
2419                                                 }
2420                                                 init_unistr2(&data, url, UNI_STR_TERMINATE);
2421                                                 fstrcpy(value.valuename, SPOOL_REG_URL);
2422 #endif
2423                                         }
2424 
2425                                         if (strequal(info[j].value_name, SPOOL_REG_SERVERNAME)) {
2426 
2427                                                 init_unistr2(&data, longname, UNI_STR_TERMINATE);
2428                                                 fstrcpy(value.valuename, SPOOL_REG_SERVERNAME);
2429                                         }
2430 
2431                                         if (strequal(info[j].value_name, SPOOL_REG_SHORTSERVERNAME)) {
2432 
2433                                                 init_unistr2(&data, global_myname(), UNI_STR_TERMINATE);
2434                                                 fstrcpy(value.valuename, SPOOL_REG_SHORTSERVERNAME);
2435                                         }
2436 
2437                                         value.type = REG_SZ;
2438                                         value.size = data.uni_str_len * 2;
2439                                         if (value.size) {
2440                                                 value.data_p = (uint8_t *)TALLOC_MEMDUP(mem_ctx, data.buffer, value.size);
2441                                         } else {
2442                                                 value.data_p = NULL;
2443                                         }
2444 
2445                                         if (c->opt_verbose)
2446                                                 display_reg_value(subkey, value);
2447 
2448                                         /* here we have to set all subkeys on the dst server */
2449                                         if (!net_spoolss_setprinterdataex(pipe_hnd_dst, mem_ctx, &hnd_dst,
2450                                                         subkey, &value))
2451                                                 goto done;
2452 
2453                                 } else {
2454 
2455                                         REGISTRY_VALUE v;
2456                                         DATA_BLOB blob;
2457 
2458                                         result = push_spoolss_PrinterData(mem_ctx, &blob,
2459                                                                           info[j].type,
2460                                                                           info[j].data);
2461                                         if (!W_ERROR_IS_OK(result)) {
2462                                                 goto done;
2463                                         }
2464 
2465                                         fstrcpy(v.valuename, info[j].value_name);
2466                                         v.type = info[j].type;
2467                                         v.data_p = blob.data;
2468                                         v.size = blob.length;
2469 
2470                                         if (c->opt_verbose) {
2471                                                 display_reg_value(subkey, v);
2472                                         }
2473 
2474                                         /* here we have to set all subkeys on the dst server */
2475                                         if (!net_spoolss_setprinterdataex(pipe_hnd_dst, mem_ctx, &hnd_dst,
2476                                                         subkey, &v)) {
2477                                                 goto done;
2478                                         }
2479 
2480                                 }
2481 
2482                                 DEBUGADD(1,("\tSetPrinterDataEx of key [%s\\%s] succeeded\n",
2483                                                 subkey, info[j].value_name));
2484 
2485                         }
2486                 }
2487 
2488                 TALLOC_FREE(keylist);
2489 
2490                 /* close printer handles here */
2491                 if (is_valid_policy_hnd(&hnd_src)) {
2492                         rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
2493                 }
2494 
2495                 if (is_valid_policy_hnd(&hnd_dst)) {
2496                         rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
2497                 }
2498 
2499         }
2500 
2501         nt_status = NT_STATUS_OK;
2502 
2503 done:
2504         SAFE_FREE(devicename);
2505         SAFE_FREE(url);
2506         SAFE_FREE(unc_name);
2507 
2508         if (is_valid_policy_hnd(&hnd_src))
2509                 rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL);
2510 
2511         if (is_valid_policy_hnd(&hnd_dst))
2512                 rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL);
2513 
2514         if (cli_dst) {
2515                 cli_shutdown(cli_dst);
2516         }
2517         return nt_status;
2518 }

/* [<][>][^][v][top][bottom][index][help] */