1/* 2 Unix SMB/CIFS implementation. 3 RPC pipe client 4 5 Copyright (C) Gerald Carter 2001-2002, 6 Copyright (C) Tim Potter 2000-2002, 7 Copyright (C) Andrew Tridgell 1994-2000, 8 Copyright (C) Luke Kenneth Casson Leighton 1996-2000, 9 Copyright (C) Jean-Francois Micouleau 1999-2000. 10 11 This program is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 2 of the License, or 14 (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program; if not, write to the Free Software 23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24*/ 25 26#include "includes.h" 27 28/* 29 * SPOOLSS Client RPC's used by servers as the notification 30 * back channel. 31 */ 32 33/* Send a ReplyOpenPrinter request. This rpc is made by the printer 34 server to the printer client in response to a rffpcnex request. 35 The rrfpcnex request names a printer and a handle (the printerlocal 36 value) and this rpc establishes a back-channel over which printer 37 notifications are performed. */ 38 39WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, 40 const char *printer, uint32 printerlocal, uint32 type, 41 POLICY_HND *handle) 42{ 43 prs_struct qbuf, rbuf; 44 SPOOL_Q_REPLYOPENPRINTER q; 45 SPOOL_R_REPLYOPENPRINTER r; 46 WERROR result = W_ERROR(ERRgeneral); 47 48 /* Initialise input parameters */ 49 50 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); 51 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); 52 53 make_spoolss_q_replyopenprinter(&q, printer, printerlocal, type); 54 55 /* Marshall data and send request */ 56 57 if (!spoolss_io_q_replyopenprinter("", &q, &qbuf, 0) || 58 !rpc_api_pipe_req (cli, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf)) 59 goto done; 60 61 /* Unmarshall response */ 62 63 if (!spoolss_io_r_replyopenprinter("", &r, &rbuf, 0)) 64 goto done; 65 66 /* Return result */ 67 68 memcpy(handle, &r.handle, sizeof(r.handle)); 69 result = r.status; 70 71done: 72 prs_mem_free(&qbuf); 73 prs_mem_free(&rbuf); 74 75 return result; 76} 77 78/* Close a back-channel notification connection */ 79 80WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, 81 POLICY_HND *handle) 82{ 83 prs_struct qbuf, rbuf; 84 SPOOL_Q_REPLYCLOSEPRINTER q; 85 SPOOL_R_REPLYCLOSEPRINTER r; 86 WERROR result = W_ERROR(ERRgeneral); 87 88 /* Initialise input parameters */ 89 90 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); 91 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); 92 93 make_spoolss_q_reply_closeprinter(&q, handle); 94 95 /* Marshall data and send request */ 96 97 if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) || 98 !rpc_api_pipe_req (cli, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf)) 99 goto done; 100 101 /* Unmarshall response */ 102 103 if (!spoolss_io_r_replycloseprinter("", &r, &rbuf, 0)) 104 goto done; 105 106 /* Return result */ 107 108 result = r.status; 109 110done: 111 prs_mem_free(&qbuf); 112 prs_mem_free(&rbuf); 113 114 return result; 115} 116 117/********************************************************************* 118 This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change 119 notification event when the registration **did not** use 120 SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor. 121 Also see cli_spolss_reply_rrpcn() 122 *********************************************************************/ 123 124WERROR cli_spoolss_routerreplyprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, 125 POLICY_HND *pol, uint32 condition, uint32 change_id) 126{ 127 prs_struct qbuf, rbuf; 128 SPOOL_Q_ROUTERREPLYPRINTER q; 129 SPOOL_R_ROUTERREPLYPRINTER r; 130 WERROR result = W_ERROR(ERRgeneral); 131 132 /* Initialise input parameters */ 133 134 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); 135 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); 136 137 make_spoolss_q_routerreplyprinter(&q, pol, condition, change_id); 138 139 /* Marshall data and send request */ 140 141 if (!spoolss_io_q_routerreplyprinter("", &q, &qbuf, 0) || 142 !rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf)) 143 goto done; 144 145 /* Unmarshall response */ 146 147 if (!spoolss_io_r_routerreplyprinter("", &r, &rbuf, 0)) 148 goto done; 149 150 /* Return output parameters */ 151 152 result = r.status; 153 154done: 155 prs_mem_free(&qbuf); 156 prs_mem_free(&rbuf); 157 158 return result; 159} 160 161/********************************************************************* 162 This SPOOLSS_REPLY_RRPCN function is used to send a change 163 notification event when the registration **did** use 164 SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor 165 Also see cli_spoolss_routereplyprinter() 166 *********************************************************************/ 167 168WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx, 169 POLICY_HND *pol, uint32 notify_data_len, 170 SPOOL_NOTIFY_INFO_DATA *notify_data, 171 uint32 change_low, uint32 change_high) 172{ 173 prs_struct qbuf, rbuf; 174 SPOOL_Q_REPLY_RRPCN q; 175 SPOOL_R_REPLY_RRPCN r; 176 WERROR result = W_ERROR(ERRgeneral); 177 SPOOL_NOTIFY_INFO notify_info; 178 179 ZERO_STRUCT(q); 180 ZERO_STRUCT(r); 181 182 /* Initialise parse structures */ 183 184 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); 185 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); 186 187 ZERO_STRUCT(notify_info); 188 189 /* Initialise input parameters */ 190 191 notify_info.version = 0x2; 192 notify_info.flags = 0x00020000; /* ?? */ 193 notify_info.count = notify_data_len; 194 notify_info.data = notify_data; 195 196 /* create and send a MSRPC command with api */ 197 /* store the parameters */ 198 199 make_spoolss_q_reply_rrpcn(&q, pol, change_low, change_high, 200 ¬ify_info); 201 202 /* Marshall data and send request */ 203 204 if(!spoolss_io_q_reply_rrpcn("", &q, &qbuf, 0) || 205 !rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &qbuf, &rbuf)) 206 goto done; 207 208 /* Unmarshall response */ 209 210 if(!spoolss_io_r_reply_rrpcn("", &r, &rbuf, 0)) 211 goto done; 212 213 if (r.unknown0 == 0x00080000) 214 DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n")); 215 else if ( r.unknown0 != 0x0 ) 216 DEBUG(8,("cli_spoolss_reply_rrpcn: unknown0 is non-zero [0x%x]\n", r.unknown0)); 217 218 result = r.status; 219 220done: 221 prs_mem_free(&qbuf); 222 prs_mem_free(&rbuf); 223 224 return result; 225} 226 227/********************************************************************* 228 *********************************************************************/ 229 230WERROR cli_spoolss_rffpcnex(struct cli_state *cli, TALLOC_CTX *mem_ctx, 231 POLICY_HND *pol, uint32 flags, uint32 options, 232 const char *localmachine, uint32 printerlocal, 233 SPOOL_NOTIFY_OPTION *option) 234{ 235 prs_struct qbuf, rbuf; 236 SPOOL_Q_RFFPCNEX q; 237 SPOOL_R_RFFPCNEX r; 238 WERROR result = W_ERROR(ERRgeneral); 239 240 ZERO_STRUCT(q); 241 ZERO_STRUCT(r); 242 243 /* Initialise parse structures */ 244 245 prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); 246 prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); 247 248 /* Initialise input parameters */ 249 250 make_spoolss_q_rffpcnex( 251 &q, pol, flags, options, localmachine, printerlocal, 252 option); 253 254 /* Marshall data and send request */ 255 256 if(!spoolss_io_q_rffpcnex("", &q, &qbuf, 0) || 257 !rpc_api_pipe_req(cli, SPOOLSS_RFFPCNEX, &qbuf, &rbuf)) 258 goto done; 259 260 /* Unmarshall response */ 261 262 if(!spoolss_io_r_rffpcnex("", &r, &rbuf, 0)) 263 goto done; 264 265 result = r.status; 266 267done: 268 prs_mem_free(&qbuf); 269 prs_mem_free(&rbuf); 270 271 return result; 272} 273