7f0cecfaf016e6a48dd92187d01bc26690c2e70e
[metze/samba/wip.git] / source3 / rpcclient / cmd_iremotewinspool.c
1 /*
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4
5    Copyright (C) 2013-2016 Guenther Deschner <gd@samba.org>
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "rpcclient.h"
23 #include "../librpc/gen_ndr/ndr_winspool.h"
24 #include "libsmb/libsmb.h"
25 #include "auth/gensec/gensec.h"
26 #include "auth/credentials/credentials.h"
27 #include "rpc_client/init_spoolss.h"
28
29 /****************************************************************************
30 ****************************************************************************/
31
32 static WERROR cmd_iremotewinspool_async_open_printer(struct rpc_pipe_client *cli,
33                                                      TALLOC_CTX *mem_ctx,
34                                                      int argc, const char **argv)
35 {
36         NTSTATUS status;
37         WERROR werror;
38         struct policy_handle hnd;
39         struct spoolss_DevmodeContainer devmode_ctr;
40         struct spoolss_UserLevelCtr client_info_ctr;
41         struct spoolss_UserLevel1 level1;
42         uint32_t access_mask = PRINTER_ALL_ACCESS;
43         struct dcerpc_binding_handle *b = cli->binding_handle;
44         struct GUID uuid;
45         struct winspool_AsyncOpenPrinter r;
46         struct cli_credentials *creds = gensec_get_credentials(cli->auth->auth_ctx);
47
48         if (argc < 2) {
49                 printf("Usage: %s <printername> [access_mask]\n", argv[0]);
50                 return WERR_OK;
51         }
52
53         if (argc >= 3) {
54                 sscanf(argv[2], "%x", &access_mask);
55         }
56
57         status = GUID_from_string(IREMOTEWINSPOOL_OBJECT_GUID, &uuid);
58         if (!NT_STATUS_IS_OK(status)) {
59                 return WERR_NOT_ENOUGH_MEMORY;
60         }
61
62         ZERO_STRUCT(devmode_ctr);
63
64         werror = spoolss_init_spoolss_UserLevel1(mem_ctx,
65                                                  cli_credentials_get_username(creds),
66                                                  &level1);
67         if (!W_ERROR_IS_OK(werror)) {
68                 return werror;
69         }
70
71         level1.processor = PROCESSOR_ARCHITECTURE_AMD64;
72
73         client_info_ctr.level = 1;
74         client_info_ctr.user_info.level1 = &level1;
75
76         r.in.pPrinterName       = argv[1];
77         r.in.pDatatype          = "RAW";
78         r.in.pDevModeContainer  = &devmode_ctr;
79         r.in.AccessRequired     = access_mask;
80         r.in.pClientInfo        = &client_info_ctr;
81         r.out.pHandle           = &hnd;
82
83         /* Open the printer handle */
84
85         status = dcerpc_binding_handle_call(b,
86                                             &uuid,
87                                             &ndr_table_iremotewinspool,
88                                             NDR_WINSPOOL_ASYNCOPENPRINTER,
89                                             mem_ctx,
90                                             &r);
91         if (!NT_STATUS_IS_OK(status)) {
92                 return ntstatus_to_werror(status);
93         }
94         if (!W_ERROR_IS_OK(r.out.result)) {
95                 return r.out.result;
96         }
97
98         printf("Printer %s opened successfully\n", argv[1]);
99
100         return WERR_OK;
101 }
102
103 static WERROR cmd_iremotewinspool_async_core_printer_driver_installed(struct rpc_pipe_client *cli,
104                                                                       TALLOC_CTX *mem_ctx,
105                                                                       int argc, const char **argv)
106 {
107         NTSTATUS status;
108         struct dcerpc_binding_handle *b = cli->binding_handle;
109         struct GUID uuid, core_printer_driver_guid;
110         struct winspool_AsyncCorePrinterDriverInstalled r;
111         const char *guid_str = SPOOLSS_CORE_PRINT_PACKAGE_FILES_XPSDRV;
112         const char *architecture = SPOOLSS_ARCHITECTURE_x64;
113         int32_t pbDriverInstalled;
114
115         if (argc > 4) {
116                 printf("Usage: %s <CORE_PRINTER_DRIVER_GUID> [architecture]\n", argv[0]);
117                 return WERR_OK;
118         }
119
120         if (argc >= 2) {
121                 guid_str = argv[1];
122         }
123
124         if (argc >= 3) {
125                 architecture = argv[2];
126         }
127
128         status = GUID_from_string(IREMOTEWINSPOOL_OBJECT_GUID, &uuid);
129         if (!NT_STATUS_IS_OK(status)) {
130                 return WERR_NOT_ENOUGH_MEMORY;
131         }
132         status = GUID_from_string(guid_str, &core_printer_driver_guid);
133         if (!NT_STATUS_IS_OK(status)) {
134                 return WERR_NOT_ENOUGH_MEMORY;
135         }
136
137         r.in.pszServer          = NULL;
138         r.in.pszEnvironment     = architecture;
139         r.in.CoreDriverGUID     = core_printer_driver_guid;
140         r.in.ftDriverDate       = 0;
141         r.in.dwlDriverVersion   = 0;
142         r.out.pbDriverInstalled = &pbDriverInstalled;
143
144         status = dcerpc_binding_handle_call(b,
145                                             &uuid,
146                                             &ndr_table_iremotewinspool,
147                                             NDR_WINSPOOL_ASYNCCOREPRINTERDRIVERINSTALLED,
148                                             mem_ctx,
149                                             &r);
150         if (!NT_STATUS_IS_OK(status)) {
151                 return ntstatus_to_werror(status);
152         }
153         if (!HRES_IS_OK(r.out.result)) {
154                 return W_ERROR(WIN32_FROM_HRESULT(r.out.result));
155         }
156
157         printf("Core Printer Driver %s is%s installed\n", guid_str,
158                 *r.out.pbDriverInstalled ? "" : " NOT");
159
160         return WERR_OK;
161 }
162
163 /* List of commands exported by this module */
164 struct cmd_set iremotewinspool_commands[] = {
165
166         { "IRemoteWinspool"  },
167
168         { "winspool_AsyncOpenPrinter", RPC_RTYPE_WERROR, NULL,
169                 cmd_iremotewinspool_async_open_printer,
170                 &ndr_table_iremotewinspool,
171                 NULL, "Open printer handle", "" },
172
173         { "winspool_AsyncCorePrinterDriverInstalled", RPC_RTYPE_WERROR, NULL,
174                 cmd_iremotewinspool_async_core_printer_driver_installed,
175                 &ndr_table_iremotewinspool,
176                 NULL, "Query Core Printer Driver Installed", "" },
177
178         { NULL }
179 };