3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 /*
27 * SMB print interface.
28 */
29
30 #include <smbsrv/smb_kproto.h>
31 #include <sys/unistd.h>
32 #include <sys/stat.h>
33 #include <sys/types.h>
34 #include <sys/fcntl.h>
35 #include <smbsrv/smb_share.h>
36
37 /*
38 * Starts the creation of a new printer file, which will be deleted
39 * automatically once it has been closed and printed.
40 *
41 * SetupLength is the number of bytes in the first part of the resulting
42 * print spool file which contains printer-specific control strings.
43 *
61 uint32_t new_id;
62 uint16_t setup;
63 uint16_t mode;
64 int rc;
65 static uint32_t tmp_id = 10000;
66
67 bzero(op, sizeof (sr->arg.open));
68 rc = smbsr_decode_vwv(sr, "ww", &setup, &mode);
69 if (rc == 0)
70 rc = smbsr_decode_data(sr, "%S", sr, &identifier);
71
72 if (rc == 0) {
73 path = smb_srm_zalloc(sr, MAXPATHLEN);
74 op->fqi.fq_path.pn_path = path;
75 new_id = atomic_inc_32_nv(&tmp_id);
76 (void) snprintf(path, MAXPATHLEN, "%s%05u", identifier, new_id);
77 }
78
79 op->create_disposition = FILE_OVERWRITE_IF;
80 op->create_options = FILE_NON_DIRECTORY_FILE;
81 DTRACE_SMB_2(op__OpenPrintFile__start, smb_request_t *, sr,
82 struct open_param *, op);
83
84 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
85 }
86
87 void
88 smb_post_open_print_file(smb_request_t *sr)
89 {
90 DTRACE_SMB_1(op__OpenPrintFile__done, smb_request_t *, sr);
91 }
92
93 /*
94 * Creates a new spool file which will be later copied and
95 * deleted by cupsd. After the file is created, information
96 * related to the file will be placed in a spooldoc list
97 * to be later used by cupsd
98 *
99 * Return values
100 * rc 0 SDRC_SUCCESS
101 * rc non-zero SDRC_ERROR
102 */
103
104 smb_sdrc_t
105 smb_com_open_print_file(smb_request_t *sr)
106 {
107 int rc;
108 smb_kspooldoc_t *sp;
109 smb_kshare_t *si;
110 struct open_param *op = &sr->arg.open;
141 }
142 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
143 }
144
145 /*
146 * Close the specified file handle and queue the file for printing.
147 * The fid refers to a file previously created as a print spool file.
148 * On successful completion of this request, the file is queued for
149 * printing by the server.
150 *
151 * Servers that negotiate LANMAN1.0 or later allow all the the fid
152 * to be closed and printed via any close request.
153 */
154 smb_sdrc_t
155 smb_pre_close_print_file(smb_request_t *sr)
156 {
157 int rc;
158
159 rc = smbsr_decode_vwv(sr, "w", &sr->smb_fid);
160
161 DTRACE_SMB_1(op__ClosePrintFile__start, smb_request_t *, sr);
162 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
163 }
164
165 void
166 smb_post_close_print_file(smb_request_t *sr)
167 {
168 DTRACE_SMB_1(op__ClosePrintFile__done, smb_request_t *, sr);
169 }
170
171 /*
172 *
173 * Adds the print file fid to a list to be used as a search
174 * key in the spooldoc list. It then wakes up the smbd
175 * spool monitor thread to copy the spool file.
176 *
177 * Return values
178 * rc - 0 success
179 *
180 */
181
182 smb_sdrc_t
183 smb_com_close_print_file(smb_request_t *sr)
184 {
185 smb_sdrc_t rc;
186
187 /*
188 * If sv_cfg.skc_print_enable somehow went false while
192 if (!STYPE_ISPRN(sr->tid_tree->t_res_type)) {
193 smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
194 ERRDOS, ERROR_BAD_DEV_TYPE);
195 cmn_err(CE_WARN, "smb_com_close_print_file: SDRC_ERROR");
196 return (SDRC_ERROR);
197 }
198 rc = smb_com_close(sr);
199
200 smb_spool_add_fid(sr->sr_server, sr->smb_fid);
201
202 return (rc);
203 }
204
205 /*
206 * Get a list of print queue entries on the server. Support for
207 * this request is optional (not required for Windows clients).
208 */
209 smb_sdrc_t
210 smb_pre_get_print_queue(smb_request_t *sr)
211 {
212 DTRACE_SMB_1(op__GetPrintQueue__start, smb_request_t *, sr);
213 return (SDRC_SUCCESS);
214 }
215
216 void
217 smb_post_get_print_queue(smb_request_t *sr)
218 {
219 DTRACE_SMB_1(op__GetPrintQueue__done, smb_request_t *, sr);
220 }
221
222 smb_sdrc_t
223 smb_com_get_print_queue(smb_request_t *sr)
224 {
225 unsigned short max_count, start_ix;
226
227 if (smbsr_decode_vwv(sr, "ww", &max_count, &start_ix) != 0)
228 return (SDRC_ERROR);
229
230 if (smbsr_encode_result(sr, 2, 3, "bwwwbw", 2, 0, 0, 3, 1, 0))
231 return (SDRC_ERROR);
232
233 return (SDRC_SUCCESS);
234 }
235
236 /*
237 * Write (append) data to a print spool file. The fid must refer to
238 * a print spool file.
239 *
240 * The first SetupLength bytes (see SMB_COM_OPEN_PRINT_FILE) in the
241 * print spool file contain printer setup data.
242 *
243 * Servers that negotiate LANMAN1.0 or later also support the use of
244 * normal write requests with print spool files.
245 */
246 smb_sdrc_t
247 smb_pre_write_print_file(smb_request_t *sr)
248 {
249 smb_rw_param_t *param;
250 int rc;
251
252 param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
253 sr->arg.rw = param;
254 param->rw_magic = SMB_RW_MAGIC;
255
256 rc = smbsr_decode_vwv(sr, "w", &sr->smb_fid);
257
258 DTRACE_SMB_1(op__WritePrintFile__start, smb_request_t *, sr);
259 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
260 }
261
262 void
263 smb_post_write_print_file(smb_request_t *sr)
264 {
265 DTRACE_SMB_1(op__WritePrintFile__done, smb_request_t *, sr);
266
267 kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
268 }
269
270 smb_sdrc_t
271 smb_com_write_print_file(smb_request_t *sr)
272 {
273 smb_rw_param_t *param = sr->arg.rw;
274 smb_node_t *node;
275 smb_attr_t attr;
276 int rc;
277
278 if (sr->sr_server->sv_cfg.skc_print_enable == 0 ||
279 !STYPE_ISPRN(sr->tid_tree->t_res_type)) {
280 smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
281 ERRDOS, ERROR_BAD_DEV_TYPE);
282 return (SDRC_ERROR);
283 }
284
285 smbsr_lookup_file(sr);
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 /*
27 * SMB print interface.
28 */
29
30 #include <smbsrv/smb_kproto.h>
31 #include <sys/unistd.h>
32 #include <sys/stat.h>
33 #include <sys/types.h>
34 #include <sys/fcntl.h>
35 #include <smbsrv/smb_share.h>
36
37 /*
38 * Starts the creation of a new printer file, which will be deleted
39 * automatically once it has been closed and printed.
40 *
41 * SetupLength is the number of bytes in the first part of the resulting
42 * print spool file which contains printer-specific control strings.
43 *
61 uint32_t new_id;
62 uint16_t setup;
63 uint16_t mode;
64 int rc;
65 static uint32_t tmp_id = 10000;
66
67 bzero(op, sizeof (sr->arg.open));
68 rc = smbsr_decode_vwv(sr, "ww", &setup, &mode);
69 if (rc == 0)
70 rc = smbsr_decode_data(sr, "%S", sr, &identifier);
71
72 if (rc == 0) {
73 path = smb_srm_zalloc(sr, MAXPATHLEN);
74 op->fqi.fq_path.pn_path = path;
75 new_id = atomic_inc_32_nv(&tmp_id);
76 (void) snprintf(path, MAXPATHLEN, "%s%05u", identifier, new_id);
77 }
78
79 op->create_disposition = FILE_OVERWRITE_IF;
80 op->create_options = FILE_NON_DIRECTORY_FILE;
81 DTRACE_SMB_START(op__OpenPrintFile, smb_request_t *, sr); /* arg.open */
82
83 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
84 }
85
86 void
87 smb_post_open_print_file(smb_request_t *sr)
88 {
89 DTRACE_SMB_DONE(op__OpenPrintFile, smb_request_t *, sr);
90 }
91
92 /*
93 * Creates a new spool file which will be later copied and
94 * deleted by cupsd. After the file is created, information
95 * related to the file will be placed in a spooldoc list
96 * to be later used by cupsd
97 *
98 * Return values
99 * rc 0 SDRC_SUCCESS
100 * rc non-zero SDRC_ERROR
101 */
102
103 smb_sdrc_t
104 smb_com_open_print_file(smb_request_t *sr)
105 {
106 int rc;
107 smb_kspooldoc_t *sp;
108 smb_kshare_t *si;
109 struct open_param *op = &sr->arg.open;
140 }
141 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
142 }
143
144 /*
145 * Close the specified file handle and queue the file for printing.
146 * The fid refers to a file previously created as a print spool file.
147 * On successful completion of this request, the file is queued for
148 * printing by the server.
149 *
150 * Servers that negotiate LANMAN1.0 or later allow all the the fid
151 * to be closed and printed via any close request.
152 */
153 smb_sdrc_t
154 smb_pre_close_print_file(smb_request_t *sr)
155 {
156 int rc;
157
158 rc = smbsr_decode_vwv(sr, "w", &sr->smb_fid);
159
160 DTRACE_SMB_START(op__ClosePrintFile, smb_request_t *, sr);
161 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
162 }
163
164 void
165 smb_post_close_print_file(smb_request_t *sr)
166 {
167 DTRACE_SMB_DONE(op__ClosePrintFile, smb_request_t *, sr);
168 }
169
170 /*
171 *
172 * Adds the print file fid to a list to be used as a search
173 * key in the spooldoc list. It then wakes up the smbd
174 * spool monitor thread to copy the spool file.
175 *
176 * Return values
177 * rc - 0 success
178 *
179 */
180
181 smb_sdrc_t
182 smb_com_close_print_file(smb_request_t *sr)
183 {
184 smb_sdrc_t rc;
185
186 /*
187 * If sv_cfg.skc_print_enable somehow went false while
191 if (!STYPE_ISPRN(sr->tid_tree->t_res_type)) {
192 smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
193 ERRDOS, ERROR_BAD_DEV_TYPE);
194 cmn_err(CE_WARN, "smb_com_close_print_file: SDRC_ERROR");
195 return (SDRC_ERROR);
196 }
197 rc = smb_com_close(sr);
198
199 smb_spool_add_fid(sr->sr_server, sr->smb_fid);
200
201 return (rc);
202 }
203
204 /*
205 * Get a list of print queue entries on the server. Support for
206 * this request is optional (not required for Windows clients).
207 */
208 smb_sdrc_t
209 smb_pre_get_print_queue(smb_request_t *sr)
210 {
211 DTRACE_SMB_START(op__GetPrintQueue, smb_request_t *, sr);
212 return (SDRC_SUCCESS);
213 }
214
215 void
216 smb_post_get_print_queue(smb_request_t *sr)
217 {
218 DTRACE_SMB_DONE(op__GetPrintQueue, smb_request_t *, sr);
219 }
220
221 smb_sdrc_t
222 smb_com_get_print_queue(smb_request_t *sr)
223 {
224 unsigned short max_count, start_ix;
225
226 if (smbsr_decode_vwv(sr, "ww", &max_count, &start_ix) != 0)
227 return (SDRC_ERROR);
228
229 if (smbsr_encode_result(sr, 2, 3, "bwwwbw", 2, 0, 0, 3, 1, 0))
230 return (SDRC_ERROR);
231
232 return (SDRC_SUCCESS);
233 }
234
235 /*
236 * Write (append) data to a print spool file. The fid must refer to
237 * a print spool file.
238 *
239 * The first SetupLength bytes (see SMB_COM_OPEN_PRINT_FILE) in the
240 * print spool file contain printer setup data.
241 *
242 * Servers that negotiate LANMAN1.0 or later also support the use of
243 * normal write requests with print spool files.
244 */
245 smb_sdrc_t
246 smb_pre_write_print_file(smb_request_t *sr)
247 {
248 smb_rw_param_t *param;
249 int rc;
250
251 param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
252 sr->arg.rw = param;
253 param->rw_magic = SMB_RW_MAGIC;
254
255 rc = smbsr_decode_vwv(sr, "w", &sr->smb_fid);
256
257 DTRACE_SMB_START(op__WritePrintFile, smb_request_t *, sr);
258 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
259 }
260
261 void
262 smb_post_write_print_file(smb_request_t *sr)
263 {
264 DTRACE_SMB_DONE(op__WritePrintFile, smb_request_t *, sr);
265
266 kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
267 }
268
269 smb_sdrc_t
270 smb_com_write_print_file(smb_request_t *sr)
271 {
272 smb_rw_param_t *param = sr->arg.rw;
273 smb_node_t *node;
274 smb_attr_t attr;
275 int rc;
276
277 if (sr->sr_server->sv_cfg.skc_print_enable == 0 ||
278 !STYPE_ISPRN(sr->tid_tree->t_res_type)) {
279 smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
280 ERRDOS, ERROR_BAD_DEV_TYPE);
281 return (SDRC_ERROR);
282 }
283
284 smbsr_lookup_file(sr);
|