LCOV - code coverage report
Current view: top level - source3/utils - net_rpc_printer.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 0 1096 0.0 %
Date: 2024-02-28 12:06:22 Functions: 0 32 0.0 %

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

Generated by: LCOV version 1.14