18d7e4166Sjose borrego /*
28d7e4166Sjose borrego * CDDL HEADER START
38d7e4166Sjose borrego *
48d7e4166Sjose borrego * The contents of this file are subject to the terms of the
58d7e4166Sjose borrego * Common Development and Distribution License (the "License").
68d7e4166Sjose borrego * You may not use this file except in compliance with the License.
78d7e4166Sjose borrego *
88d7e4166Sjose borrego * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98d7e4166Sjose borrego * or http://www.opensolaris.org/os/licensing.
108d7e4166Sjose borrego * See the License for the specific language governing permissions
118d7e4166Sjose borrego * and limitations under the License.
128d7e4166Sjose borrego *
138d7e4166Sjose borrego * When distributing Covered Code, include this CDDL HEADER in each
148d7e4166Sjose borrego * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158d7e4166Sjose borrego * If applicable, add the following below this CDDL HEADER, with the
168d7e4166Sjose borrego * fields enclosed by brackets "[]" replaced with your own identifying
178d7e4166Sjose borrego * information: Portions Copyright [yyyy] [name of copyright owner]
188d7e4166Sjose borrego *
198d7e4166Sjose borrego * CDDL HEADER END
208d7e4166Sjose borrego */
218d7e4166Sjose borrego /*
22cb174861Sjoyce mcintosh * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
2368b2bbf2SGordon Ross * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
248d7e4166Sjose borrego */
258d7e4166Sjose borrego
268d7e4166Sjose borrego /*
278d7e4166Sjose borrego * Printing and Spooling RPC service.
288d7e4166Sjose borrego */
29fd9ee8b5Sjoyce mcintosh #include <sys/types.h>
30fd9ee8b5Sjoyce mcintosh #include <sys/stat.h>
31fd9ee8b5Sjoyce mcintosh #include <sys/utsname.h>
32b819cea2SGordon Ross #include <sys/atomic.h>
33cb174861Sjoyce mcintosh #include <unistd.h>
348d7e4166Sjose borrego #include <stdlib.h>
358d7e4166Sjose borrego #include <strings.h>
36fd9ee8b5Sjoyce mcintosh #include <fcntl.h>
37fd9ee8b5Sjoyce mcintosh #include <errno.h>
38*3299f39fSGordon Ross #include <libmlrpc/libmlrpc.h>
398d7e4166Sjose borrego #include <smbsrv/libsmb.h>
408d7e4166Sjose borrego #include <smbsrv/libmlsvc.h>
41fd9ee8b5Sjoyce mcintosh #include <smbsrv/smb.h>
428d7e4166Sjose borrego #include <smbsrv/ndl/spoolss.ndl>
43fd9ee8b5Sjoyce mcintosh #include <smbsrv/ndl/winreg.ndl>
44cb174861Sjoyce mcintosh #include <smb/nterror.h>
458d7e4166Sjose borrego #include <smbsrv/smbinfo.h>
468d7e4166Sjose borrego #include <smbsrv/nmpipes.h>
47cb174861Sjoyce mcintosh #include <mlsvc.h>
48cb174861Sjoyce mcintosh
4986d7016bSGordon Ross #ifdef HAVE_CUPS
5086d7016bSGordon Ross
51fd9ee8b5Sjoyce mcintosh #define SPOOLSS_PRINTER "Postscript"
52fd9ee8b5Sjoyce mcintosh
53cb174861Sjoyce mcintosh typedef struct smb_spool {
54fd9ee8b5Sjoyce mcintosh list_t sp_list;
55fd9ee8b5Sjoyce mcintosh int sp_cnt;
56fd9ee8b5Sjoyce mcintosh rwlock_t sp_rwl;
57fd9ee8b5Sjoyce mcintosh int sp_initialized;
58cb174861Sjoyce mcintosh } smb_spool_t;
59cb174861Sjoyce mcintosh
60fd9ee8b5Sjoyce mcintosh typedef struct smb_spooldoc {
61fd9ee8b5Sjoyce mcintosh uint32_t sd_magic;
62fd9ee8b5Sjoyce mcintosh list_node_t sd_lnd;
63fd9ee8b5Sjoyce mcintosh smb_inaddr_t sd_ipaddr;
64fd9ee8b5Sjoyce mcintosh int sd_spool_num;
65fd9ee8b5Sjoyce mcintosh char sd_username[MAXNAMELEN];
66fd9ee8b5Sjoyce mcintosh char sd_path[MAXPATHLEN];
67fd9ee8b5Sjoyce mcintosh char sd_doc_name[MAXNAMELEN];
68fd9ee8b5Sjoyce mcintosh char sd_printer_name[MAXPATHLEN];
69fd9ee8b5Sjoyce mcintosh int32_t sd_fd;
70fd9ee8b5Sjoyce mcintosh ndr_hdid_t sd_handle;
71fd9ee8b5Sjoyce mcintosh } smb_spooldoc_t;
72fd9ee8b5Sjoyce mcintosh
73fd9ee8b5Sjoyce mcintosh typedef struct {
74fd9ee8b5Sjoyce mcintosh char *name;
75fd9ee8b5Sjoyce mcintosh uint32_t value;
76fd9ee8b5Sjoyce mcintosh } spoolss_winreg_t;
77fd9ee8b5Sjoyce mcintosh
78fd9ee8b5Sjoyce mcintosh typedef struct {
79fd9ee8b5Sjoyce mcintosh uint8_t *sd_buf;
80fd9ee8b5Sjoyce mcintosh uint32_t sd_size;
81fd9ee8b5Sjoyce mcintosh } spoolss_sd_t;
82fd9ee8b5Sjoyce mcintosh
83cb174861Sjoyce mcintosh static uint32_t spoolss_cnt;
84cb174861Sjoyce mcintosh static smb_spool_t spoolss_splist;
85cb174861Sjoyce mcintosh
86fd9ee8b5Sjoyce mcintosh void (*spoolss_copyfile_callback)(smb_inaddr_t *, char *, char *, char *);
87cb174861Sjoyce mcintosh
88cb174861Sjoyce mcintosh DECL_FIXUP_STRUCT(spoolss_GetPrinter_result_u);
89cb174861Sjoyce mcintosh DECL_FIXUP_STRUCT(spoolss_GetPrinter_result);
90cb174861Sjoyce mcintosh DECL_FIXUP_STRUCT(spoolss_GetPrinter);
918d7e4166Sjose borrego
92cb174861Sjoyce mcintosh DECL_FIXUP_STRUCT(spoolss_RPC_V2_NOTIFY_INFO_DATA_DATA);
93cb174861Sjoyce mcintosh DECL_FIXUP_STRUCT(spoolss_RPC_V2_NOTIFY_INFO_DATA);
94cb174861Sjoyce mcintosh DECL_FIXUP_STRUCT(spoolss_RPC_V2_NOTIFY_INFO);
95cb174861Sjoyce mcintosh DECL_FIXUP_STRUCT(spoolss_RFNPCNEX);
96cb174861Sjoyce mcintosh
97cb174861Sjoyce mcintosh uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *);
98fd9ee8b5Sjoyce mcintosh static int spoolss_getservername(char *, size_t);
99fd9ee8b5Sjoyce mcintosh static uint32_t spoolss_make_sd(ndr_xa_t *, spoolss_sd_t *);
100fd9ee8b5Sjoyce mcintosh static uint32_t spoolss_format_sd(smb_sd_t *);
101fd9ee8b5Sjoyce mcintosh static int spoolss_find_document(ndr_hdid_t *);
102cb174861Sjoyce mcintosh
103cb174861Sjoyce mcintosh static int spoolss_s_OpenPrinter(void *, ndr_xa_t *);
104cb174861Sjoyce mcintosh static int spoolss_s_ClosePrinter(void *, ndr_xa_t *);
105cb174861Sjoyce mcintosh static int spoolss_s_AbortPrinter(void *, ndr_xa_t *);
106cb174861Sjoyce mcintosh static int spoolss_s_ResetPrinter(void *, ndr_xa_t *);
107cb174861Sjoyce mcintosh static int spoolss_s_GetPrinter(void *, ndr_xa_t *);
108cb174861Sjoyce mcintosh static int spoolss_s_GetPrinterData(void *, ndr_xa_t *);
109cb174861Sjoyce mcintosh static int spoolss_s_AddJob(void *, ndr_xa_t *);
110cb174861Sjoyce mcintosh static int spoolss_s_GetJob(void *, ndr_xa_t *);
111cb174861Sjoyce mcintosh static int spoolss_s_EnumJobs(void *, ndr_xa_t *);
112cb174861Sjoyce mcintosh static int spoolss_s_ScheduleJob(void *, ndr_xa_t *);
113cb174861Sjoyce mcintosh static int spoolss_s_StartDocPrinter(void *, ndr_xa_t *);
114cb174861Sjoyce mcintosh static int spoolss_s_EndDocPrinter(void *, ndr_xa_t *);
115cb174861Sjoyce mcintosh static int spoolss_s_StartPagePrinter(void *, ndr_xa_t *);
116cb174861Sjoyce mcintosh static int spoolss_s_EndPagePrinter(void *, ndr_xa_t *);
117cb174861Sjoyce mcintosh static int spoolss_s_rfnpcnex(void *, ndr_xa_t *);
118cb174861Sjoyce mcintosh static int spoolss_s_WritePrinter(void *, ndr_xa_t *);
119fd9ee8b5Sjoyce mcintosh static int spoolss_s_AddForm(void *, ndr_xa_t *);
120fd9ee8b5Sjoyce mcintosh static int spoolss_s_DeleteForm(void *, ndr_xa_t *);
121cb174861Sjoyce mcintosh static int spoolss_s_EnumForms(void *, ndr_xa_t *);
122fd9ee8b5Sjoyce mcintosh static int spoolss_s_AddMonitor(void *, ndr_xa_t *);
123fd9ee8b5Sjoyce mcintosh static int spoolss_s_DeleteMonitor(void *, ndr_xa_t *);
124fd9ee8b5Sjoyce mcintosh static int spoolss_s_DeletePort(void *, ndr_xa_t *);
125fd9ee8b5Sjoyce mcintosh static int spoolss_s_AddPortEx(void *, ndr_xa_t *);
126fd9ee8b5Sjoyce mcintosh static int spoolss_s_SetPort(void *, ndr_xa_t *);
127cb174861Sjoyce mcintosh static int spoolss_s_stub(void *, ndr_xa_t *);
1288d7e4166Sjose borrego
1298d7e4166Sjose borrego static ndr_stub_table_t spoolss_stub_table[] = {
130cb174861Sjoyce mcintosh { spoolss_s_GetJob, SPOOLSS_OPNUM_GetJob },
131cb174861Sjoyce mcintosh { spoolss_s_EnumJobs, SPOOLSS_OPNUM_EnumJobs },
132cb174861Sjoyce mcintosh { spoolss_s_stub, SPOOLSS_OPNUM_DeletePrinter },
133cb174861Sjoyce mcintosh { spoolss_s_GetPrinter, SPOOLSS_OPNUM_GetPrinter },
134cb174861Sjoyce mcintosh { spoolss_s_stub, SPOOLSS_OPNUM_GetPrinterDriver },
135cb174861Sjoyce mcintosh { spoolss_s_stub, SPOOLSS_OPNUM_DeletePrinterDriver },
1368d7e4166Sjose borrego { spoolss_s_OpenPrinter, SPOOLSS_OPNUM_OpenPrinter },
137cb174861Sjoyce mcintosh { spoolss_s_StartDocPrinter, SPOOLSS_OPNUM_StartDocPrinter },
138cb174861Sjoyce mcintosh { spoolss_s_WritePrinter, SPOOLSS_OPNUM_WritePrinter },
139cb174861Sjoyce mcintosh { spoolss_s_EndDocPrinter, SPOOLSS_OPNUM_EndDocPrinter },
140cb174861Sjoyce mcintosh { spoolss_s_StartPagePrinter, SPOOLSS_OPNUM_StartPagePrinter },
141cb174861Sjoyce mcintosh { spoolss_s_EndPagePrinter, SPOOLSS_OPNUM_EndPagePrinter },
142cb174861Sjoyce mcintosh { spoolss_s_AbortPrinter, SPOOLSS_OPNUM_AbortPrinter },
143cb174861Sjoyce mcintosh { spoolss_s_ResetPrinter, SPOOLSS_OPNUM_ResetPrinter },
144cb174861Sjoyce mcintosh { spoolss_s_AddJob, SPOOLSS_OPNUM_AddJob },
145cb174861Sjoyce mcintosh { spoolss_s_ScheduleJob, SPOOLSS_OPNUM_ScheduleJob },
146cb174861Sjoyce mcintosh { spoolss_s_GetPrinterData, SPOOLSS_OPNUM_GetPrinterData },
147cb174861Sjoyce mcintosh { spoolss_s_ClosePrinter, SPOOLSS_OPNUM_ClosePrinter },
148fd9ee8b5Sjoyce mcintosh { spoolss_s_AddForm, SPOOLSS_OPNUM_AddForm },
149fd9ee8b5Sjoyce mcintosh { spoolss_s_DeleteForm, SPOOLSS_OPNUM_DeleteForm },
150cb174861Sjoyce mcintosh { spoolss_s_EnumForms, SPOOLSS_OPNUM_EnumForms },
151fd9ee8b5Sjoyce mcintosh { spoolss_s_AddMonitor, SPOOLSS_OPNUM_AddMonitor },
152fd9ee8b5Sjoyce mcintosh { spoolss_s_DeleteMonitor, SPOOLSS_OPNUM_DeleteMonitor },
153fd9ee8b5Sjoyce mcintosh { spoolss_s_DeletePort, SPOOLSS_OPNUM_DeletePort },
154fd9ee8b5Sjoyce mcintosh { spoolss_s_AddPortEx, SPOOLSS_OPNUM_AddPortEx },
155fd9ee8b5Sjoyce mcintosh { spoolss_s_SetPort, SPOOLSS_OPNUM_SetPort },
156cb174861Sjoyce mcintosh { spoolss_s_stub, SPOOLSS_OPNUM_GetPrinterDriver2 },
157cb174861Sjoyce mcintosh { spoolss_s_stub, SPOOLSS_OPNUM_FCPN },
158cb174861Sjoyce mcintosh { spoolss_s_stub, SPOOLSS_OPNUM_ReplyOpenPrinter },
159cb174861Sjoyce mcintosh { spoolss_s_stub, SPOOLSS_OPNUM_ReplyClosePrinter },
160cb174861Sjoyce mcintosh { spoolss_s_stub, SPOOLSS_OPNUM_RFFPCNEX },
161cb174861Sjoyce mcintosh { spoolss_s_rfnpcnex, SPOOLSS_OPNUM_RFNPCNEX },
162cb174861Sjoyce mcintosh { spoolss_s_stub, SPOOLSS_OPNUM_RRPCN },
163cb174861Sjoyce mcintosh { spoolss_s_OpenPrinter, SPOOLSS_OPNUM_OpenPrinterEx },
164cb174861Sjoyce mcintosh { spoolss_s_stub, SPOOLSS_OPNUM_EnumPrinterData },
165cb174861Sjoyce mcintosh { spoolss_s_stub, SPOOLSS_OPNUM_EnumPrinterDataEx },
166cb174861Sjoyce mcintosh { spoolss_s_stub, SPOOLSS_OPNUM_EnumPrinterKey },
1678d7e4166Sjose borrego {0}
1688d7e4166Sjose borrego };
1698d7e4166Sjose borrego
1708d7e4166Sjose borrego static ndr_service_t spoolss_service = {
1718d7e4166Sjose borrego "SPOOLSS", /* name */
1728d7e4166Sjose borrego "Print Spool Service", /* desc */
1738d7e4166Sjose borrego "\\spoolss", /* endpoint */
1748d7e4166Sjose borrego PIPE_SPOOLSS, /* sec_addr_port */
175cb174861Sjoyce mcintosh "12345678-1234-abcd-ef00-0123456789ab", 1, /* abstract */
1768d7e4166Sjose borrego NDR_TRANSFER_SYNTAX_UUID, 2, /* transfer */
1778d7e4166Sjose borrego 0, /* no bind_instance_size */
1788d7e4166Sjose borrego 0, /* no bind_req() */
1798d7e4166Sjose borrego 0, /* no unbind_and_close() */
1808d7e4166Sjose borrego 0, /* use generic_call_stub() */
1818d7e4166Sjose borrego &TYPEINFO(spoolss_interface), /* interface ti */
1828d7e4166Sjose borrego spoolss_stub_table /* stub_table */
1838d7e4166Sjose borrego };
1848d7e4166Sjose borrego
1858d7e4166Sjose borrego void
spoolss_initialize(void)1868d7e4166Sjose borrego spoolss_initialize(void)
1878d7e4166Sjose borrego {
188fd9ee8b5Sjoyce mcintosh if (!spoolss_splist.sp_initialized) {
189fd9ee8b5Sjoyce mcintosh list_create(&spoolss_splist.sp_list,
190fd9ee8b5Sjoyce mcintosh sizeof (smb_spooldoc_t),
191fd9ee8b5Sjoyce mcintosh offsetof(smb_spooldoc_t, sd_lnd));
192fd9ee8b5Sjoyce mcintosh spoolss_splist.sp_initialized = 1;
193fd9ee8b5Sjoyce mcintosh }
194fd9ee8b5Sjoyce mcintosh
195fd9ee8b5Sjoyce mcintosh spoolss_copyfile_callback = NULL;
196fd9ee8b5Sjoyce mcintosh
1978d7e4166Sjose borrego (void) ndr_svc_register(&spoolss_service);
1988d7e4166Sjose borrego }
1998d7e4166Sjose borrego
200cb174861Sjoyce mcintosh void
spoolss_finalize(void)201cb174861Sjoyce mcintosh spoolss_finalize(void)
202cb174861Sjoyce mcintosh {
203fd9ee8b5Sjoyce mcintosh spoolss_copyfile_callback = NULL;
204fd9ee8b5Sjoyce mcintosh }
205fd9ee8b5Sjoyce mcintosh
206fd9ee8b5Sjoyce mcintosh /*
207fd9ee8b5Sjoyce mcintosh * Register a copyfile callback that the spoolss service can use to
208fd9ee8b5Sjoyce mcintosh * copy files to the spool directory.
209fd9ee8b5Sjoyce mcintosh *
210fd9ee8b5Sjoyce mcintosh * Set a null pointer to disable the copying of files to the spool
211fd9ee8b5Sjoyce mcintosh * directory.
212fd9ee8b5Sjoyce mcintosh */
213fd9ee8b5Sjoyce mcintosh void
spoolss_register_copyfile(spoolss_copyfile_t copyfile)214fd9ee8b5Sjoyce mcintosh spoolss_register_copyfile(spoolss_copyfile_t copyfile)
215fd9ee8b5Sjoyce mcintosh {
216fd9ee8b5Sjoyce mcintosh spoolss_copyfile_callback = copyfile;
217fd9ee8b5Sjoyce mcintosh }
218fd9ee8b5Sjoyce mcintosh
219fd9ee8b5Sjoyce mcintosh static void
spoolss_copyfile(smb_inaddr_t * ipaddr,char * username,char * path,char * docname)220fd9ee8b5Sjoyce mcintosh spoolss_copyfile(smb_inaddr_t *ipaddr, char *username, char *path,
221fd9ee8b5Sjoyce mcintosh char *docname)
222fd9ee8b5Sjoyce mcintosh {
223fd9ee8b5Sjoyce mcintosh if (spoolss_copyfile_callback != NULL)
224fd9ee8b5Sjoyce mcintosh (*spoolss_copyfile_callback)(ipaddr, username, path, docname);
225cb174861Sjoyce mcintosh }
226cb174861Sjoyce mcintosh
227cb174861Sjoyce mcintosh static int
spoolss_s_OpenPrinter(void * arg,ndr_xa_t * mxa)2288d7e4166Sjose borrego spoolss_s_OpenPrinter(void *arg, ndr_xa_t *mxa)
2298d7e4166Sjose borrego {
2308d7e4166Sjose borrego struct spoolss_OpenPrinter *param = arg;
231fd9ee8b5Sjoyce mcintosh char *name = (char *)param->printer_name;
232fd9ee8b5Sjoyce mcintosh ndr_hdid_t *id;
233fd9ee8b5Sjoyce mcintosh
234fd9ee8b5Sjoyce mcintosh if (name != NULL && *name != '\0') {
235fd9ee8b5Sjoyce mcintosh if (strspn(name, "\\") > 2) {
236fd9ee8b5Sjoyce mcintosh bzero(¶m->handle, sizeof (spoolss_handle_t));
237fd9ee8b5Sjoyce mcintosh param->status = ERROR_INVALID_PRINTER_NAME;
238fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
239fd9ee8b5Sjoyce mcintosh }
240fd9ee8b5Sjoyce mcintosh
241fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_OpenPrinter: %s", name);
242fd9ee8b5Sjoyce mcintosh }
243cb174861Sjoyce mcintosh
244fd9ee8b5Sjoyce mcintosh if ((id = ndr_hdalloc(mxa, NULL)) == NULL) {
245cb174861Sjoyce mcintosh bzero(¶m->handle, sizeof (spoolss_handle_t));
246cb174861Sjoyce mcintosh param->status = ERROR_NOT_ENOUGH_MEMORY;
247cb174861Sjoyce mcintosh return (NDR_DRC_OK);
248cb174861Sjoyce mcintosh }
249cb174861Sjoyce mcintosh
250cb174861Sjoyce mcintosh bcopy(id, ¶m->handle, sizeof (spoolss_handle_t));
251cb174861Sjoyce mcintosh param->status = 0;
252cb174861Sjoyce mcintosh return (NDR_DRC_OK);
253cb174861Sjoyce mcintosh }
254cb174861Sjoyce mcintosh
255cb174861Sjoyce mcintosh /*ARGSUSED*/
256cb174861Sjoyce mcintosh static int
spoolss_s_StartPagePrinter(void * arg,ndr_xa_t * mxa)257cb174861Sjoyce mcintosh spoolss_s_StartPagePrinter(void *arg, ndr_xa_t *mxa)
258cb174861Sjoyce mcintosh {
259cb174861Sjoyce mcintosh struct spoolss_StartPagePrinter *param = arg;
260cb174861Sjoyce mcintosh
261cb174861Sjoyce mcintosh param->status = ERROR_SUCCESS;
262cb174861Sjoyce mcintosh
263cb174861Sjoyce mcintosh return (NDR_DRC_OK);
264cb174861Sjoyce mcintosh }
265cb174861Sjoyce mcintosh
266cb174861Sjoyce mcintosh /*ARGSUSED*/
267cb174861Sjoyce mcintosh static int
spoolss_s_EndPagePrinter(void * arg,ndr_xa_t * mxa)268cb174861Sjoyce mcintosh spoolss_s_EndPagePrinter(void *arg, ndr_xa_t *mxa)
269cb174861Sjoyce mcintosh {
270cb174861Sjoyce mcintosh struct spoolss_EndPagePrinter *param = arg;
271cb174861Sjoyce mcintosh
272cb174861Sjoyce mcintosh param->status = ERROR_SUCCESS;
273cb174861Sjoyce mcintosh
274cb174861Sjoyce mcintosh return (NDR_DRC_OK);
275cb174861Sjoyce mcintosh }
276cb174861Sjoyce mcintosh
277cb174861Sjoyce mcintosh /*
278cb174861Sjoyce mcintosh * Windows XP and 2000 use this mechanism to write spool files.
279fd9ee8b5Sjoyce mcintosh * Create a spool file fd to be used by spoolss_s_WritePrinter
280fd9ee8b5Sjoyce mcintosh * and add it to the tail of the spool list.
281cb174861Sjoyce mcintosh */
282cb174861Sjoyce mcintosh static int
spoolss_s_StartDocPrinter(void * arg,ndr_xa_t * mxa)283cb174861Sjoyce mcintosh spoolss_s_StartDocPrinter(void *arg, ndr_xa_t *mxa)
284cb174861Sjoyce mcintosh {
285cb174861Sjoyce mcintosh struct spoolss_StartDocPrinter *param = arg;
286cb174861Sjoyce mcintosh ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
287cb174861Sjoyce mcintosh smb_spooldoc_t *spfile;
288cb174861Sjoyce mcintosh spoolss_DocInfo_t *docinfo;
289cb174861Sjoyce mcintosh char g_path[MAXPATHLEN];
290cb174861Sjoyce mcintosh smb_share_t si;
291cb174861Sjoyce mcintosh int rc;
292cb174861Sjoyce mcintosh int fd;
293cb174861Sjoyce mcintosh
294cb174861Sjoyce mcintosh if (ndr_hdlookup(mxa, id) == NULL) {
295fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_StartDocPrinter: invalid handle");
296cb174861Sjoyce mcintosh param->status = ERROR_INVALID_HANDLE;
297cb174861Sjoyce mcintosh return (NDR_DRC_OK);
298cb174861Sjoyce mcintosh }
299cb174861Sjoyce mcintosh
300cb174861Sjoyce mcintosh if ((docinfo = param->dinfo.DocInfoContainer) == NULL) {
301cb174861Sjoyce mcintosh param->status = ERROR_INVALID_PARAMETER;
302cb174861Sjoyce mcintosh return (NDR_DRC_OK);
303cb174861Sjoyce mcintosh }
304cb174861Sjoyce mcintosh
305cb174861Sjoyce mcintosh if ((rc = smb_shr_get(SMB_SHARE_PRINT, &si)) != NERR_Success) {
306fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_StartDocPrinter: %s error=%d",
307cb174861Sjoyce mcintosh SMB_SHARE_PRINT, rc);
308cb174861Sjoyce mcintosh param->status = rc;
309cb174861Sjoyce mcintosh return (NDR_DRC_OK);
310cb174861Sjoyce mcintosh }
3118d7e4166Sjose borrego
312cb174861Sjoyce mcintosh if ((spfile = calloc(1, sizeof (smb_spooldoc_t))) == NULL) {
313cb174861Sjoyce mcintosh param->status = ERROR_NOT_ENOUGH_MEMORY;
314cb174861Sjoyce mcintosh return (NDR_DRC_OK);
315cb174861Sjoyce mcintosh }
3168d7e4166Sjose borrego
317cb174861Sjoyce mcintosh if (docinfo->doc_name != NULL)
318cb174861Sjoyce mcintosh (void) strlcpy(spfile->sd_doc_name,
319cb174861Sjoyce mcintosh (char *)docinfo->doc_name, MAXNAMELEN);
3208d7e4166Sjose borrego else
321cb174861Sjoyce mcintosh (void) strlcpy(spfile->sd_doc_name, "document", MAXNAMELEN);
322cb174861Sjoyce mcintosh
323cb174861Sjoyce mcintosh if (docinfo->printer_name != NULL)
324cb174861Sjoyce mcintosh (void) strlcpy(spfile->sd_printer_name,
325cb174861Sjoyce mcintosh (char *)docinfo->printer_name, MAXPATHLEN);
326cb174861Sjoyce mcintosh else
327cb174861Sjoyce mcintosh (void) strlcpy(spfile->sd_printer_name, "printer", MAXPATHLEN);
328cb174861Sjoyce mcintosh
32968b2bbf2SGordon Ross spfile->sd_ipaddr = mxa->pipe->np_user->ui_ipaddr;
330cb174861Sjoyce mcintosh (void) strlcpy((char *)spfile->sd_username,
33168b2bbf2SGordon Ross mxa->pipe->np_user->ui_account, MAXNAMELEN);
332fd9ee8b5Sjoyce mcintosh (void) memcpy(&spfile->sd_handle, ¶m->handle, sizeof (ndr_hdid_t));
333fd9ee8b5Sjoyce mcintosh
334cb174861Sjoyce mcintosh /*
335cb174861Sjoyce mcintosh * write temporary spool file to print$
336cb174861Sjoyce mcintosh */
337cb174861Sjoyce mcintosh (void) snprintf(g_path, MAXPATHLEN, "%s/%s%d", si.shr_path,
338cb174861Sjoyce mcintosh spfile->sd_username, spoolss_cnt);
339cb174861Sjoyce mcintosh atomic_inc_32(&spoolss_cnt);
340cb174861Sjoyce mcintosh
341cb174861Sjoyce mcintosh fd = open(g_path, O_CREAT | O_RDWR, 0600);
342cb174861Sjoyce mcintosh if (fd == -1) {
343fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_StartDocPrinter: %s: %s",
344cb174861Sjoyce mcintosh g_path, strerror(errno));
345cb174861Sjoyce mcintosh param->status = ERROR_OPEN_FAILED;
346cb174861Sjoyce mcintosh free(spfile);
347cb174861Sjoyce mcintosh } else {
348cb174861Sjoyce mcintosh (void) strlcpy((char *)spfile->sd_path, g_path, MAXPATHLEN);
349cb174861Sjoyce mcintosh spfile->sd_fd = (uint16_t)fd;
350fd9ee8b5Sjoyce mcintosh
351fd9ee8b5Sjoyce mcintosh /*
352fd9ee8b5Sjoyce mcintosh * Add the document to the spool list.
353fd9ee8b5Sjoyce mcintosh */
354fd9ee8b5Sjoyce mcintosh (void) rw_wrlock(&spoolss_splist.sp_rwl);
355fd9ee8b5Sjoyce mcintosh list_insert_tail(&spoolss_splist.sp_list, spfile);
356fd9ee8b5Sjoyce mcintosh spoolss_splist.sp_cnt++;
357fd9ee8b5Sjoyce mcintosh (void) rw_unlock(&spoolss_splist.sp_rwl);
358fd9ee8b5Sjoyce mcintosh
359cb174861Sjoyce mcintosh /*
360cb174861Sjoyce mcintosh * JobId isn't used now, but if printQ management is added
361cb174861Sjoyce mcintosh * this will have to be incremented per job submitted.
362cb174861Sjoyce mcintosh */
363cb174861Sjoyce mcintosh param->JobId = 46;
364cb174861Sjoyce mcintosh param->status = ERROR_SUCCESS;
365cb174861Sjoyce mcintosh }
366cb174861Sjoyce mcintosh return (NDR_DRC_OK);
367cb174861Sjoyce mcintosh }
368cb174861Sjoyce mcintosh
369cb174861Sjoyce mcintosh /*
370cb174861Sjoyce mcintosh * Windows XP and 2000 use this mechanism to write spool files
371fd9ee8b5Sjoyce mcintosh * Search the spooldoc list for a matching RPC handle and pass
372fd9ee8b5Sjoyce mcintosh * the spool the file for printing.
373cb174861Sjoyce mcintosh */
374cb174861Sjoyce mcintosh static int
spoolss_s_EndDocPrinter(void * arg,ndr_xa_t * mxa)375cb174861Sjoyce mcintosh spoolss_s_EndDocPrinter(void *arg, ndr_xa_t *mxa)
376cb174861Sjoyce mcintosh {
377cb174861Sjoyce mcintosh struct spoolss_EndDocPrinter *param = arg;
378fd9ee8b5Sjoyce mcintosh ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
379fd9ee8b5Sjoyce mcintosh smb_spooldoc_t *sp;
380cb174861Sjoyce mcintosh
381fd9ee8b5Sjoyce mcintosh if (ndr_hdlookup(mxa, id) == NULL) {
382fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_EndDocPrinter: invalid handle");
383fd9ee8b5Sjoyce mcintosh param->status = ERROR_INVALID_HANDLE;
384fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
385fd9ee8b5Sjoyce mcintosh }
386fd9ee8b5Sjoyce mcintosh
387fd9ee8b5Sjoyce mcintosh param->status = ERROR_INVALID_HANDLE;
388fd9ee8b5Sjoyce mcintosh (void) rw_wrlock(&spoolss_splist.sp_rwl);
389fd9ee8b5Sjoyce mcintosh
390fd9ee8b5Sjoyce mcintosh sp = list_head(&spoolss_splist.sp_list);
391fd9ee8b5Sjoyce mcintosh while (sp != NULL) {
392fd9ee8b5Sjoyce mcintosh if (!memcmp(id, &(sp->sd_handle), sizeof (ndr_hdid_t))) {
393fd9ee8b5Sjoyce mcintosh spoolss_copyfile(&sp->sd_ipaddr,
394fd9ee8b5Sjoyce mcintosh sp->sd_username, sp->sd_path, sp->sd_doc_name);
395fd9ee8b5Sjoyce mcintosh (void) close(sp->sd_fd);
396fd9ee8b5Sjoyce mcintosh list_remove(&spoolss_splist.sp_list, sp);
397fd9ee8b5Sjoyce mcintosh free(sp);
398fd9ee8b5Sjoyce mcintosh param->status = ERROR_SUCCESS;
399fd9ee8b5Sjoyce mcintosh break;
400fd9ee8b5Sjoyce mcintosh }
401fd9ee8b5Sjoyce mcintosh
402fd9ee8b5Sjoyce mcintosh sp = list_next(&spoolss_splist.sp_list, sp);
403fd9ee8b5Sjoyce mcintosh }
404fd9ee8b5Sjoyce mcintosh
405fd9ee8b5Sjoyce mcintosh (void) rw_unlock(&spoolss_splist.sp_rwl);
406fd9ee8b5Sjoyce mcintosh
407fd9ee8b5Sjoyce mcintosh if (param->status != ERROR_SUCCESS)
408fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_EndDocPrinter: document not found");
409cb174861Sjoyce mcintosh return (NDR_DRC_OK);
410cb174861Sjoyce mcintosh }
411cb174861Sjoyce mcintosh
412cb174861Sjoyce mcintosh /*ARGSUSED*/
413cb174861Sjoyce mcintosh static int
spoolss_s_AbortPrinter(void * arg,ndr_xa_t * mxa)414cb174861Sjoyce mcintosh spoolss_s_AbortPrinter(void *arg, ndr_xa_t *mxa)
415cb174861Sjoyce mcintosh {
416cb174861Sjoyce mcintosh struct spoolss_AbortPrinter *param = arg;
417cb174861Sjoyce mcintosh
418cb174861Sjoyce mcintosh param->status = ERROR_SUCCESS;
419cb174861Sjoyce mcintosh return (NDR_DRC_OK);
420cb174861Sjoyce mcintosh }
421cb174861Sjoyce mcintosh
422cb174861Sjoyce mcintosh /*ARGSUSED*/
423cb174861Sjoyce mcintosh static int
spoolss_s_ResetPrinter(void * arg,ndr_xa_t * mxa)424cb174861Sjoyce mcintosh spoolss_s_ResetPrinter(void *arg, ndr_xa_t *mxa)
425cb174861Sjoyce mcintosh {
426cb174861Sjoyce mcintosh struct spoolss_AbortPrinter *param = arg;
427cb174861Sjoyce mcintosh
428cb174861Sjoyce mcintosh param->status = ERROR_SUCCESS;
429cb174861Sjoyce mcintosh return (NDR_DRC_OK);
430cb174861Sjoyce mcintosh }
431cb174861Sjoyce mcintosh
432cb174861Sjoyce mcintosh static int
spoolss_s_ClosePrinter(void * arg,ndr_xa_t * mxa)433cb174861Sjoyce mcintosh spoolss_s_ClosePrinter(void *arg, ndr_xa_t *mxa)
434cb174861Sjoyce mcintosh {
435cb174861Sjoyce mcintosh struct spoolss_ClosePrinter *param = arg;
436fd9ee8b5Sjoyce mcintosh ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
437fd9ee8b5Sjoyce mcintosh ndr_handle_t *hd;
438cb174861Sjoyce mcintosh
439cb174861Sjoyce mcintosh if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
440cb174861Sjoyce mcintosh free(hd->nh_data);
441cb174861Sjoyce mcintosh hd->nh_data = NULL;
442cb174861Sjoyce mcintosh }
443cb174861Sjoyce mcintosh
444cb174861Sjoyce mcintosh ndr_hdfree(mxa, id);
445cb174861Sjoyce mcintosh bzero(¶m->result_handle, sizeof (spoolss_handle_t));
446cb174861Sjoyce mcintosh param->status = ERROR_SUCCESS;
447cb174861Sjoyce mcintosh return (NDR_DRC_OK);
448cb174861Sjoyce mcintosh }
449cb174861Sjoyce mcintosh
450fd9ee8b5Sjoyce mcintosh static int
spoolss_s_AddForm(void * arg,ndr_xa_t * mxa)451fd9ee8b5Sjoyce mcintosh spoolss_s_AddForm(void *arg, ndr_xa_t *mxa)
452fd9ee8b5Sjoyce mcintosh {
453fd9ee8b5Sjoyce mcintosh struct spoolss_AddForm *param = arg;
454fd9ee8b5Sjoyce mcintosh ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
455fd9ee8b5Sjoyce mcintosh
456fd9ee8b5Sjoyce mcintosh if (ndr_hdlookup(mxa, id) == NULL) {
457fd9ee8b5Sjoyce mcintosh bzero(param, sizeof (struct spoolss_AddForm));
458fd9ee8b5Sjoyce mcintosh param->status = ERROR_INVALID_HANDLE;
459fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
460fd9ee8b5Sjoyce mcintosh }
461fd9ee8b5Sjoyce mcintosh
462fd9ee8b5Sjoyce mcintosh bzero(param, sizeof (struct spoolss_AddForm));
463fd9ee8b5Sjoyce mcintosh param->status = ERROR_SUCCESS;
464fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
465fd9ee8b5Sjoyce mcintosh }
466fd9ee8b5Sjoyce mcintosh
467fd9ee8b5Sjoyce mcintosh static int
spoolss_s_DeleteForm(void * arg,ndr_xa_t * mxa)468fd9ee8b5Sjoyce mcintosh spoolss_s_DeleteForm(void *arg, ndr_xa_t *mxa)
469fd9ee8b5Sjoyce mcintosh {
470fd9ee8b5Sjoyce mcintosh struct spoolss_DeleteForm *param = arg;
471fd9ee8b5Sjoyce mcintosh ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
472fd9ee8b5Sjoyce mcintosh
473fd9ee8b5Sjoyce mcintosh if (ndr_hdlookup(mxa, id) == NULL) {
474fd9ee8b5Sjoyce mcintosh bzero(param, sizeof (struct spoolss_DeleteForm));
475fd9ee8b5Sjoyce mcintosh param->status = ERROR_INVALID_HANDLE;
476fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
477fd9ee8b5Sjoyce mcintosh }
478fd9ee8b5Sjoyce mcintosh
479fd9ee8b5Sjoyce mcintosh bzero(param, sizeof (struct spoolss_DeleteForm));
480fd9ee8b5Sjoyce mcintosh param->status = ERROR_SUCCESS;
481fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
482fd9ee8b5Sjoyce mcintosh }
483fd9ee8b5Sjoyce mcintosh
484fd9ee8b5Sjoyce mcintosh static int
spoolss_s_EnumForms(void * arg,ndr_xa_t * mxa)485cb174861Sjoyce mcintosh spoolss_s_EnumForms(void *arg, ndr_xa_t *mxa)
486cb174861Sjoyce mcintosh {
487cb174861Sjoyce mcintosh struct spoolss_EnumForms *param = arg;
488fd9ee8b5Sjoyce mcintosh ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
489cb174861Sjoyce mcintosh
490fd9ee8b5Sjoyce mcintosh if (ndr_hdlookup(mxa, id) == NULL) {
491fd9ee8b5Sjoyce mcintosh bzero(param, sizeof (struct spoolss_EnumForms));
492fd9ee8b5Sjoyce mcintosh param->status = ERROR_INVALID_HANDLE;
493fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
494fd9ee8b5Sjoyce mcintosh }
495fd9ee8b5Sjoyce mcintosh
496fd9ee8b5Sjoyce mcintosh bzero(param, sizeof (struct spoolss_EnumForms));
497fd9ee8b5Sjoyce mcintosh param->status = ERROR_SUCCESS;
498cb174861Sjoyce mcintosh param->needed = 0;
499cb174861Sjoyce mcintosh return (NDR_DRC_OK);
500cb174861Sjoyce mcintosh }
501cb174861Sjoyce mcintosh
502cb174861Sjoyce mcintosh /*ARGSUSED*/
503fd9ee8b5Sjoyce mcintosh static int
spoolss_s_AddMonitor(void * arg,ndr_xa_t * mxa)504fd9ee8b5Sjoyce mcintosh spoolss_s_AddMonitor(void *arg, ndr_xa_t *mxa)
505fd9ee8b5Sjoyce mcintosh {
506fd9ee8b5Sjoyce mcintosh struct spoolss_AddMonitor *param = arg;
507fd9ee8b5Sjoyce mcintosh
508fd9ee8b5Sjoyce mcintosh param->status = ERROR_SUCCESS;
509fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
510fd9ee8b5Sjoyce mcintosh }
511fd9ee8b5Sjoyce mcintosh
512fd9ee8b5Sjoyce mcintosh /*ARGSUSED*/
513fd9ee8b5Sjoyce mcintosh static int
spoolss_s_DeleteMonitor(void * arg,ndr_xa_t * mxa)514fd9ee8b5Sjoyce mcintosh spoolss_s_DeleteMonitor(void *arg, ndr_xa_t *mxa)
515fd9ee8b5Sjoyce mcintosh {
516fd9ee8b5Sjoyce mcintosh struct spoolss_DeleteMonitor *param = arg;
517fd9ee8b5Sjoyce mcintosh
518fd9ee8b5Sjoyce mcintosh param->status = ERROR_SUCCESS;
519fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
520fd9ee8b5Sjoyce mcintosh }
521fd9ee8b5Sjoyce mcintosh
522fd9ee8b5Sjoyce mcintosh /*ARGSUSED*/
523fd9ee8b5Sjoyce mcintosh static int
spoolss_s_DeletePort(void * arg,ndr_xa_t * mxa)524fd9ee8b5Sjoyce mcintosh spoolss_s_DeletePort(void *arg, ndr_xa_t *mxa)
525fd9ee8b5Sjoyce mcintosh {
526fd9ee8b5Sjoyce mcintosh struct spoolss_DeletePort *param = arg;
527fd9ee8b5Sjoyce mcintosh
528fd9ee8b5Sjoyce mcintosh param->status = ERROR_SUCCESS;
529fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
530fd9ee8b5Sjoyce mcintosh }
531fd9ee8b5Sjoyce mcintosh
532fd9ee8b5Sjoyce mcintosh /*ARGSUSED*/
533fd9ee8b5Sjoyce mcintosh static int
spoolss_s_AddPortEx(void * arg,ndr_xa_t * mxa)534fd9ee8b5Sjoyce mcintosh spoolss_s_AddPortEx(void *arg, ndr_xa_t *mxa)
535fd9ee8b5Sjoyce mcintosh {
536fd9ee8b5Sjoyce mcintosh struct spoolss_AddPortEx *param = arg;
537fd9ee8b5Sjoyce mcintosh
538fd9ee8b5Sjoyce mcintosh param->status = ERROR_SUCCESS;
539fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
540fd9ee8b5Sjoyce mcintosh }
541fd9ee8b5Sjoyce mcintosh
542fd9ee8b5Sjoyce mcintosh /*ARGSUSED*/
543fd9ee8b5Sjoyce mcintosh static int
spoolss_s_SetPort(void * arg,ndr_xa_t * mxa)544fd9ee8b5Sjoyce mcintosh spoolss_s_SetPort(void *arg, ndr_xa_t *mxa)
545fd9ee8b5Sjoyce mcintosh {
546fd9ee8b5Sjoyce mcintosh struct spoolss_SetPort *param = arg;
547fd9ee8b5Sjoyce mcintosh
548fd9ee8b5Sjoyce mcintosh param->status = ERROR_SUCCESS;
549fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
550fd9ee8b5Sjoyce mcintosh }
551fd9ee8b5Sjoyce mcintosh
552fd9ee8b5Sjoyce mcintosh /*ARGSUSED*/
553fd9ee8b5Sjoyce mcintosh static int
spoolss_s_EnumJobs(void * arg,ndr_xa_t * mxa)554cb174861Sjoyce mcintosh spoolss_s_EnumJobs(void *arg, ndr_xa_t *mxa)
555cb174861Sjoyce mcintosh {
556cb174861Sjoyce mcintosh struct spoolss_EnumJobs *param = arg;
557cb174861Sjoyce mcintosh DWORD status = ERROR_SUCCESS;
558cb174861Sjoyce mcintosh
559cb174861Sjoyce mcintosh switch (param->level) {
560cb174861Sjoyce mcintosh case 1:
561cb174861Sjoyce mcintosh case 2:
562cb174861Sjoyce mcintosh case 3:
563cb174861Sjoyce mcintosh case 4:
564cb174861Sjoyce mcintosh default:
565cb174861Sjoyce mcintosh break;
566cb174861Sjoyce mcintosh }
567cb174861Sjoyce mcintosh
568cb174861Sjoyce mcintosh param->status = status;
569cb174861Sjoyce mcintosh param->needed = 0;
570cb174861Sjoyce mcintosh param->needed2 = 0;
571cb174861Sjoyce mcintosh return (NDR_DRC_OK);
572cb174861Sjoyce mcintosh }
573cb174861Sjoyce mcintosh
574cb174861Sjoyce mcintosh
575cb174861Sjoyce mcintosh /*ARGSUSED*/
576cb174861Sjoyce mcintosh static int
spoolss_s_GetJob(void * arg,ndr_xa_t * mxa)577cb174861Sjoyce mcintosh spoolss_s_GetJob(void *arg, ndr_xa_t *mxa)
578cb174861Sjoyce mcintosh {
579cb174861Sjoyce mcintosh struct spoolss_GetJob *param = arg;
580cb174861Sjoyce mcintosh DWORD status = ERROR_SUCCESS;
581cb174861Sjoyce mcintosh
582cb174861Sjoyce mcintosh if (param->BufCount == 0)
583cb174861Sjoyce mcintosh param->status = ERROR_INSUFFICIENT_BUFFER;
584cb174861Sjoyce mcintosh else
585cb174861Sjoyce mcintosh param->status = status;
586cb174861Sjoyce mcintosh param->needed = 0;
587cb174861Sjoyce mcintosh return (NDR_DRC_OK);
588cb174861Sjoyce mcintosh }
589cb174861Sjoyce mcintosh
590cb174861Sjoyce mcintosh
591cb174861Sjoyce mcintosh /*ARGSUSED*/
592cb174861Sjoyce mcintosh static int
spoolss_s_ScheduleJob(void * arg,ndr_xa_t * mxa)593cb174861Sjoyce mcintosh spoolss_s_ScheduleJob(void *arg, ndr_xa_t *mxa)
594cb174861Sjoyce mcintosh {
595cb174861Sjoyce mcintosh struct spoolss_ScheduleJob *param = arg;
596fd9ee8b5Sjoyce mcintosh DWORD status = ERROR_SPL_NO_ADDJOB;
5978d7e4166Sjose borrego
598cb174861Sjoyce mcintosh param->status = status;
5998d7e4166Sjose borrego return (NDR_DRC_OK);
6008d7e4166Sjose borrego }
6018d7e4166Sjose borrego
6028d7e4166Sjose borrego /*ARGSUSED*/
603cb174861Sjoyce mcintosh static int
spoolss_s_AddJob(void * arg,ndr_xa_t * mxa)604cb174861Sjoyce mcintosh spoolss_s_AddJob(void *arg, ndr_xa_t *mxa)
605cb174861Sjoyce mcintosh {
606cb174861Sjoyce mcintosh struct spoolss_AddJob *param = arg;
607cb174861Sjoyce mcintosh
608cb174861Sjoyce mcintosh param->status = ERROR_SUCCESS;
609cb174861Sjoyce mcintosh param->needed = 0;
610cb174861Sjoyce mcintosh return (NDR_DRC_OK);
611cb174861Sjoyce mcintosh }
612cb174861Sjoyce mcintosh
613cb174861Sjoyce mcintosh /*ARGSUSED*/
614cb174861Sjoyce mcintosh static int
spoolss_s_rfnpcnex(void * arg,ndr_xa_t * mxa)615cb174861Sjoyce mcintosh spoolss_s_rfnpcnex(void *arg, ndr_xa_t *mxa)
616cb174861Sjoyce mcintosh {
617cb174861Sjoyce mcintosh struct spoolss_RFNPCNEX *param = arg;
618cb174861Sjoyce mcintosh
619cb174861Sjoyce mcintosh param->ppinfo = 0;
620cb174861Sjoyce mcintosh param->status = ERROR_SUCCESS;
621cb174861Sjoyce mcintosh return (NDR_DRC_OK);
622cb174861Sjoyce mcintosh }
623cb174861Sjoyce mcintosh
624cb174861Sjoyce mcintosh /*
625cb174861Sjoyce mcintosh * Use the RPC context handle to find the fd and write the document content.
626cb174861Sjoyce mcintosh */
627cb174861Sjoyce mcintosh static int
spoolss_s_WritePrinter(void * arg,ndr_xa_t * mxa)628cb174861Sjoyce mcintosh spoolss_s_WritePrinter(void *arg, ndr_xa_t *mxa)
629cb174861Sjoyce mcintosh {
630cb174861Sjoyce mcintosh struct spoolss_WritePrinter *param = arg;
631cb174861Sjoyce mcintosh int written = 0;
632cb174861Sjoyce mcintosh ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
633cb174861Sjoyce mcintosh int spfd;
634cb174861Sjoyce mcintosh
635cb174861Sjoyce mcintosh if (ndr_hdlookup(mxa, id) == NULL) {
636cb174861Sjoyce mcintosh param->written = 0;
637cb174861Sjoyce mcintosh param->status = ERROR_INVALID_HANDLE;
638fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_WritePrinter: invalid handle");
639cb174861Sjoyce mcintosh return (NDR_DRC_OK);
640cb174861Sjoyce mcintosh }
641cb174861Sjoyce mcintosh
642fd9ee8b5Sjoyce mcintosh if ((spfd = spoolss_find_document(id)) < 0) {
643cb174861Sjoyce mcintosh param->written = 0;
644cb174861Sjoyce mcintosh param->status = ERROR_INVALID_HANDLE;
645fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_WritePrinter: document not found");
646cb174861Sjoyce mcintosh return (NDR_DRC_OK);
647cb174861Sjoyce mcintosh }
648cb174861Sjoyce mcintosh
649cb174861Sjoyce mcintosh written = write(spfd, param->pBuf, param->BufCount);
650cb174861Sjoyce mcintosh if (written < param->BufCount) {
651fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_WritePrinter: write failed");
652cb174861Sjoyce mcintosh param->written = 0;
653cb174861Sjoyce mcintosh param->status = ERROR_CANTWRITE;
654cb174861Sjoyce mcintosh return (NDR_DRC_OK);
655cb174861Sjoyce mcintosh }
656cb174861Sjoyce mcintosh
657cb174861Sjoyce mcintosh param->written = written;
658cb174861Sjoyce mcintosh param->status = ERROR_SUCCESS;
659cb174861Sjoyce mcintosh return (NDR_DRC_OK);
660cb174861Sjoyce mcintosh }
661cb174861Sjoyce mcintosh
662cb174861Sjoyce mcintosh /*
663fd9ee8b5Sjoyce mcintosh * Find a document by RPC handle in the spool list and return the fd.
664cb174861Sjoyce mcintosh */
665fd9ee8b5Sjoyce mcintosh static int
spoolss_find_document(ndr_hdid_t * handle)666fd9ee8b5Sjoyce mcintosh spoolss_find_document(ndr_hdid_t *handle)
667cb174861Sjoyce mcintosh {
668fd9ee8b5Sjoyce mcintosh smb_spooldoc_t *sp;
669cb174861Sjoyce mcintosh
670fd9ee8b5Sjoyce mcintosh (void) rw_rdlock(&spoolss_splist.sp_rwl);
671cb174861Sjoyce mcintosh
672fd9ee8b5Sjoyce mcintosh sp = list_head(&spoolss_splist.sp_list);
673fd9ee8b5Sjoyce mcintosh while (sp != NULL) {
674fd9ee8b5Sjoyce mcintosh if (!memcmp(handle, &(sp->sd_handle), sizeof (ndr_hdid_t))) {
675fd9ee8b5Sjoyce mcintosh (void) rw_unlock(&spoolss_splist.sp_rwl);
676fd9ee8b5Sjoyce mcintosh return (sp->sd_fd);
677cb174861Sjoyce mcintosh }
678fd9ee8b5Sjoyce mcintosh sp = list_next(&spoolss_splist.sp_list, sp);
679cb174861Sjoyce mcintosh }
680cb174861Sjoyce mcintosh
681fd9ee8b5Sjoyce mcintosh (void) rw_unlock(&spoolss_splist.sp_rwl);
682fd9ee8b5Sjoyce mcintosh return (-1);
683cb174861Sjoyce mcintosh }
684cb174861Sjoyce mcintosh
685fd9ee8b5Sjoyce mcintosh /*
686fd9ee8b5Sjoyce mcintosh * GetPrinterData is used t obtain values from the registry for a
687fd9ee8b5Sjoyce mcintosh * printer or a print server. See [MS-RPRN] for value descriptions.
688fd9ee8b5Sjoyce mcintosh * The registry returns ERROR_FILE_NOT_FOUND for unknown keys.
689fd9ee8b5Sjoyce mcintosh */
690cb174861Sjoyce mcintosh static int
spoolss_s_GetPrinterData(void * arg,ndr_xa_t * mxa)691cb174861Sjoyce mcintosh spoolss_s_GetPrinterData(void *arg, ndr_xa_t *mxa)
692cb174861Sjoyce mcintosh {
693fd9ee8b5Sjoyce mcintosh static spoolss_winreg_t reg[] = {
694fd9ee8b5Sjoyce mcintosh { "ChangeId", 0x0050acf2 },
695fd9ee8b5Sjoyce mcintosh { "W3SvcInstalled", 0x00000000 },
696fd9ee8b5Sjoyce mcintosh { "BeepEnabled", 0x00000000 },
697fd9ee8b5Sjoyce mcintosh { "EventLog", 0x0000001f },
698fd9ee8b5Sjoyce mcintosh { "NetPopup", 0x00000000 },
699fd9ee8b5Sjoyce mcintosh { "NetPopupToComputer", 0x00000000 },
700fd9ee8b5Sjoyce mcintosh { "MajorVersion", 0x00000003 },
701fd9ee8b5Sjoyce mcintosh { "MinorVersion", 0x00000000 },
702fd9ee8b5Sjoyce mcintosh { "DsPresent", 0x00000000 }
703fd9ee8b5Sjoyce mcintosh };
704cb174861Sjoyce mcintosh
705fd9ee8b5Sjoyce mcintosh struct spoolss_GetPrinterData *param = arg;
706fd9ee8b5Sjoyce mcintosh char *name = (char *)param->pValueName;
707fd9ee8b5Sjoyce mcintosh char buf[MAXPATHLEN];
708fd9ee8b5Sjoyce mcintosh static uint8_t reserved_buf[4];
709fd9ee8b5Sjoyce mcintosh spoolss_winreg_t *rp;
710fd9ee8b5Sjoyce mcintosh smb_share_t si;
711fd9ee8b5Sjoyce mcintosh smb_version_t *osversion;
712fd9ee8b5Sjoyce mcintosh struct utsname sysname;
713fd9ee8b5Sjoyce mcintosh smb_wchar_t *wcs;
714fd9ee8b5Sjoyce mcintosh uint32_t value;
715fd9ee8b5Sjoyce mcintosh uint32_t status;
716fd9ee8b5Sjoyce mcintosh int wcslen;
717fd9ee8b5Sjoyce mcintosh int i;
718fd9ee8b5Sjoyce mcintosh
719fd9ee8b5Sjoyce mcintosh if (name == NULL || *name == '\0') {
720fd9ee8b5Sjoyce mcintosh status = ERROR_FILE_NOT_FOUND;
721fd9ee8b5Sjoyce mcintosh goto report_error;
722cb174861Sjoyce mcintosh }
723cb174861Sjoyce mcintosh
724fd9ee8b5Sjoyce mcintosh for (i = 0; i < sizeof (reg) / sizeof (reg[0]); ++i) {
725fd9ee8b5Sjoyce mcintosh param->pType = WINREG_DWORD;
726fd9ee8b5Sjoyce mcintosh param->Needed = sizeof (uint32_t);
727fd9ee8b5Sjoyce mcintosh rp = ®[i];
728fd9ee8b5Sjoyce mcintosh
729fd9ee8b5Sjoyce mcintosh if (strcasecmp(name, rp->name) != 0)
730fd9ee8b5Sjoyce mcintosh continue;
731fd9ee8b5Sjoyce mcintosh
732fd9ee8b5Sjoyce mcintosh if (param->Size < sizeof (uint32_t)) {
733fd9ee8b5Sjoyce mcintosh param->Size = 0;
734fd9ee8b5Sjoyce mcintosh goto need_more_data;
735fd9ee8b5Sjoyce mcintosh }
736fd9ee8b5Sjoyce mcintosh
737fd9ee8b5Sjoyce mcintosh if ((param->Buf = NDR_NEW(mxa, uint32_t)) == NULL) {
738fd9ee8b5Sjoyce mcintosh status = ERROR_NOT_ENOUGH_MEMORY;
739fd9ee8b5Sjoyce mcintosh goto report_error;
740fd9ee8b5Sjoyce mcintosh }
741fd9ee8b5Sjoyce mcintosh
742fd9ee8b5Sjoyce mcintosh value = rp->value;
743fd9ee8b5Sjoyce mcintosh
744fd9ee8b5Sjoyce mcintosh if ((strcasecmp(name, "DsPresent") == 0) &&
745fd9ee8b5Sjoyce mcintosh (smb_config_get_secmode() == SMB_SECMODE_DOMAIN))
746fd9ee8b5Sjoyce mcintosh value = 0x00000001;
747fd9ee8b5Sjoyce mcintosh
748fd9ee8b5Sjoyce mcintosh bcopy(&value, param->Buf, sizeof (uint32_t));
749fd9ee8b5Sjoyce mcintosh param->Size = sizeof (uint32_t);
750fd9ee8b5Sjoyce mcintosh param->status = ERROR_SUCCESS;
751fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
752cb174861Sjoyce mcintosh }
753cb174861Sjoyce mcintosh
754fd9ee8b5Sjoyce mcintosh if (strcasecmp(name, "OSVersion") == 0) {
755fd9ee8b5Sjoyce mcintosh param->pType = WINREG_BINARY;
756fd9ee8b5Sjoyce mcintosh param->Needed = sizeof (smb_version_t);
757cb174861Sjoyce mcintosh
758fd9ee8b5Sjoyce mcintosh if (param->Size < sizeof (smb_version_t)) {
759fd9ee8b5Sjoyce mcintosh param->Size = sizeof (smb_version_t);
760fd9ee8b5Sjoyce mcintosh goto need_more_data;
761fd9ee8b5Sjoyce mcintosh }
762cb174861Sjoyce mcintosh
763fd9ee8b5Sjoyce mcintosh if ((osversion = NDR_NEW(mxa, smb_version_t)) == NULL) {
764fd9ee8b5Sjoyce mcintosh status = ERROR_NOT_ENOUGH_MEMORY;
765fd9ee8b5Sjoyce mcintosh goto report_error;
766fd9ee8b5Sjoyce mcintosh }
767fd9ee8b5Sjoyce mcintosh
768fd9ee8b5Sjoyce mcintosh smb_config_get_version(osversion);
769fd9ee8b5Sjoyce mcintosh param->Buf = (uint8_t *)osversion;
770fd9ee8b5Sjoyce mcintosh param->status = ERROR_SUCCESS;
771fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
772fd9ee8b5Sjoyce mcintosh }
773cb174861Sjoyce mcintosh
774fd9ee8b5Sjoyce mcintosh if (strcasecmp(name, "DNSMachineName") == 0) {
775fd9ee8b5Sjoyce mcintosh param->pType = WINREG_SZ;
776fd9ee8b5Sjoyce mcintosh buf[0] = '\0';
777fd9ee8b5Sjoyce mcintosh (void) smb_getfqhostname(buf, MAXHOSTNAMELEN);
778fd9ee8b5Sjoyce mcintosh goto encode_string;
779cb174861Sjoyce mcintosh }
780cb174861Sjoyce mcintosh
781fd9ee8b5Sjoyce mcintosh if (strcasecmp(name, "DefaultSpoolDirectory") == 0) {
782fd9ee8b5Sjoyce mcintosh param->pType = WINREG_SZ;
783fd9ee8b5Sjoyce mcintosh buf[0] = '\0';
784fd9ee8b5Sjoyce mcintosh
785fd9ee8b5Sjoyce mcintosh if (smb_shr_get(SMB_SHARE_PRINT, &si) != NERR_Success) {
786fd9ee8b5Sjoyce mcintosh status = ERROR_FILE_NOT_FOUND;
787fd9ee8b5Sjoyce mcintosh goto report_error;
788fd9ee8b5Sjoyce mcintosh }
789fd9ee8b5Sjoyce mcintosh
790fd9ee8b5Sjoyce mcintosh (void) snprintf(buf, MAXPATHLEN, "C:/%s", si.shr_path);
791fd9ee8b5Sjoyce mcintosh (void) strcanon(buf, "/\\");
792fd9ee8b5Sjoyce mcintosh (void) strsubst(buf, '/', '\\');
793fd9ee8b5Sjoyce mcintosh goto encode_string;
794cb174861Sjoyce mcintosh }
795cb174861Sjoyce mcintosh
796fd9ee8b5Sjoyce mcintosh if (strcasecmp(name, "Architecture") == 0) {
797fd9ee8b5Sjoyce mcintosh param->pType = WINREG_SZ;
798fd9ee8b5Sjoyce mcintosh
799fd9ee8b5Sjoyce mcintosh if (uname(&sysname) < 0)
800fd9ee8b5Sjoyce mcintosh (void) strlcpy(buf, "Solaris", MAXPATHLEN);
801fd9ee8b5Sjoyce mcintosh else
802fd9ee8b5Sjoyce mcintosh (void) snprintf(buf, MAXPATHLEN, "%s %s",
803fd9ee8b5Sjoyce mcintosh sysname.sysname, sysname.machine);
804fd9ee8b5Sjoyce mcintosh
805fd9ee8b5Sjoyce mcintosh goto encode_string;
806cb174861Sjoyce mcintosh }
807cb174861Sjoyce mcintosh
808fd9ee8b5Sjoyce mcintosh status = ERROR_FILE_NOT_FOUND;
809cb174861Sjoyce mcintosh
810fd9ee8b5Sjoyce mcintosh report_error:
811fd9ee8b5Sjoyce mcintosh bzero(param, sizeof (struct spoolss_GetPrinterData));
812fd9ee8b5Sjoyce mcintosh param->Buf = reserved_buf;
813fd9ee8b5Sjoyce mcintosh param->status = status;
814fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
815fd9ee8b5Sjoyce mcintosh
816fd9ee8b5Sjoyce mcintosh encode_string:
817fd9ee8b5Sjoyce mcintosh wcslen = smb_wcequiv_strlen(buf) + sizeof (smb_wchar_t);
818fd9ee8b5Sjoyce mcintosh if (param->Size < wcslen) {
819fd9ee8b5Sjoyce mcintosh param->Needed = wcslen;
820fd9ee8b5Sjoyce mcintosh goto need_more_data;
821fd9ee8b5Sjoyce mcintosh }
822cb174861Sjoyce mcintosh
823fd9ee8b5Sjoyce mcintosh if ((wcs = NDR_MALLOC(mxa, wcslen)) == NULL) {
824fd9ee8b5Sjoyce mcintosh status = ERROR_NOT_ENOUGH_MEMORY;
825fd9ee8b5Sjoyce mcintosh goto report_error;
826cb174861Sjoyce mcintosh }
827cb174861Sjoyce mcintosh
828fd9ee8b5Sjoyce mcintosh (void) ndr_mbstowcs(NULL, wcs, buf, wcslen);
829fd9ee8b5Sjoyce mcintosh param->Buf = (uint8_t *)wcs;
830fd9ee8b5Sjoyce mcintosh param->Needed = wcslen;
831fd9ee8b5Sjoyce mcintosh param->status = ERROR_SUCCESS;
832fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
833fd9ee8b5Sjoyce mcintosh
834fd9ee8b5Sjoyce mcintosh need_more_data:
835fd9ee8b5Sjoyce mcintosh param->Size = 0;
836fd9ee8b5Sjoyce mcintosh param->Buf = reserved_buf;
837fd9ee8b5Sjoyce mcintosh param->status = ERROR_MORE_DATA;
838fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
839cb174861Sjoyce mcintosh }
840cb174861Sjoyce mcintosh
841cb174861Sjoyce mcintosh void
smb_rpc_off(char * dst,char * src,uint32_t * offset,uint32_t * outoffset)842cb174861Sjoyce mcintosh smb_rpc_off(char *dst, char *src, uint32_t *offset, uint32_t *outoffset)
843cb174861Sjoyce mcintosh {
844cb174861Sjoyce mcintosh int nwchars;
845cb174861Sjoyce mcintosh int bytes;
846cb174861Sjoyce mcintosh
847cb174861Sjoyce mcintosh bytes = smb_wcequiv_strlen(src) + 2;
848cb174861Sjoyce mcintosh nwchars = strlen(src) + 1;
849cb174861Sjoyce mcintosh *offset -= bytes;
850cb174861Sjoyce mcintosh *outoffset = *offset;
851cb174861Sjoyce mcintosh /*LINTED E_BAD_PTR_CAST_ALIGN*/
852cb174861Sjoyce mcintosh (void) smb_mbstowcs(((smb_wchar_t *)(dst + *offset)), src, nwchars);
853cb174861Sjoyce mcintosh }
854cb174861Sjoyce mcintosh
8558d7e4166Sjose borrego int
spoolss_s_GetPrinter(void * arg,ndr_xa_t * mxa)856cb174861Sjoyce mcintosh spoolss_s_GetPrinter(void *arg, ndr_xa_t *mxa)
857cb174861Sjoyce mcintosh {
858fd9ee8b5Sjoyce mcintosh struct spoolss_GetPrinter *param = arg;
859fd9ee8b5Sjoyce mcintosh struct spoolss_GetPrinter0 *pinfo0;
860fd9ee8b5Sjoyce mcintosh struct spoolss_GetPrinter1 *pinfo1;
861fd9ee8b5Sjoyce mcintosh struct spoolss_GetPrinter2 *pinfo2;
862fd9ee8b5Sjoyce mcintosh struct spoolss_DeviceMode *devmode2;
863fd9ee8b5Sjoyce mcintosh ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
864fd9ee8b5Sjoyce mcintosh spoolss_sd_t secdesc;
865fd9ee8b5Sjoyce mcintosh char server[MAXNAMELEN];
866fd9ee8b5Sjoyce mcintosh char printer[MAXNAMELEN];
867fd9ee8b5Sjoyce mcintosh DWORD status = ERROR_SUCCESS;
868fd9ee8b5Sjoyce mcintosh char *wname;
869fd9ee8b5Sjoyce mcintosh uint32_t offset;
870fd9ee8b5Sjoyce mcintosh uint8_t *tmpbuf;
871fd9ee8b5Sjoyce mcintosh
872fd9ee8b5Sjoyce mcintosh if (ndr_hdlookup(mxa, id) == NULL) {
873fd9ee8b5Sjoyce mcintosh status = ERROR_INVALID_HANDLE;
874cb174861Sjoyce mcintosh goto error_out;
875cb174861Sjoyce mcintosh }
876fd9ee8b5Sjoyce mcintosh
877fd9ee8b5Sjoyce mcintosh if (spoolss_getservername(server, MAXNAMELEN) != 0) {
878fd9ee8b5Sjoyce mcintosh status = ERROR_INTERNAL_ERROR;
879fd9ee8b5Sjoyce mcintosh goto error_out;
880fd9ee8b5Sjoyce mcintosh }
881fd9ee8b5Sjoyce mcintosh
882fd9ee8b5Sjoyce mcintosh (void) snprintf(printer, MAXNAMELEN, "%s\\%s", server, SPOOLSS_PRINTER);
883fd9ee8b5Sjoyce mcintosh
884cb174861Sjoyce mcintosh switch (param->switch_value) {
885cb174861Sjoyce mcintosh case 0:
886cb174861Sjoyce mcintosh case 1:
887fd9ee8b5Sjoyce mcintosh param->needed = 460;
888cb174861Sjoyce mcintosh break;
889cb174861Sjoyce mcintosh case 2:
890fd9ee8b5Sjoyce mcintosh param->needed = 712;
891cb174861Sjoyce mcintosh break;
892fd9ee8b5Sjoyce mcintosh default:
893fd9ee8b5Sjoyce mcintosh status = ERROR_INVALID_LEVEL;
894cb174861Sjoyce mcintosh goto error_out;
895cb174861Sjoyce mcintosh }
896fd9ee8b5Sjoyce mcintosh
897fd9ee8b5Sjoyce mcintosh if (param->BufCount < param->needed) {
898fd9ee8b5Sjoyce mcintosh param->BufCount = 0;
899fd9ee8b5Sjoyce mcintosh param->Buf = NULL;
900fd9ee8b5Sjoyce mcintosh param->status = ERROR_INSUFFICIENT_BUFFER;
901fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
902cb174861Sjoyce mcintosh }
903fd9ee8b5Sjoyce mcintosh
904fd9ee8b5Sjoyce mcintosh if ((param->Buf = NDR_MALLOC(mxa, param->BufCount)) == NULL) {
905fd9ee8b5Sjoyce mcintosh status = ERROR_NOT_ENOUGH_MEMORY;
906cb174861Sjoyce mcintosh goto error_out;
907cb174861Sjoyce mcintosh }
908fd9ee8b5Sjoyce mcintosh
909fd9ee8b5Sjoyce mcintosh bzero(param->Buf, param->BufCount);
910fd9ee8b5Sjoyce mcintosh wname = (char *)param->Buf;
911fd9ee8b5Sjoyce mcintosh offset = param->needed;
912fd9ee8b5Sjoyce mcintosh
913cb174861Sjoyce mcintosh switch (param->switch_value) {
914cb174861Sjoyce mcintosh case 0:
915fd9ee8b5Sjoyce mcintosh /*LINTED E_BAD_PTR_CAST_ALIGN*/
916fd9ee8b5Sjoyce mcintosh pinfo0 = (struct spoolss_GetPrinter0 *)param->Buf;
917fd9ee8b5Sjoyce mcintosh
918fd9ee8b5Sjoyce mcintosh smb_rpc_off(wname, server, &offset, &pinfo0->servername);
919fd9ee8b5Sjoyce mcintosh smb_rpc_off(wname, printer, &offset, &pinfo0->printername);
920cb174861Sjoyce mcintosh pinfo0->cjobs = 0;
921cb174861Sjoyce mcintosh pinfo0->total_jobs = 6;
922cb174861Sjoyce mcintosh pinfo0->total_bytes = 1040771;
923cb174861Sjoyce mcintosh pinfo0->time0 = 0;
924cb174861Sjoyce mcintosh pinfo0->time1 = 0;
925cb174861Sjoyce mcintosh pinfo0->time2 = 3;
926cb174861Sjoyce mcintosh pinfo0->time3 = 0;
927cb174861Sjoyce mcintosh pinfo0->global_counter = 2162710;
928cb174861Sjoyce mcintosh pinfo0->total_pages = 21495865;
929cb174861Sjoyce mcintosh pinfo0->version = 10;
930cb174861Sjoyce mcintosh pinfo0->session_counter = 1;
931cb174861Sjoyce mcintosh pinfo0->job_error = 0x6;
932cb174861Sjoyce mcintosh pinfo0->change_id = 0x1;
933cb174861Sjoyce mcintosh pinfo0->status = 0;
934cb174861Sjoyce mcintosh pinfo0->c_setprinter = 0;
935cb174861Sjoyce mcintosh break;
936cb174861Sjoyce mcintosh case 1:
937fd9ee8b5Sjoyce mcintosh /*LINTED E_BAD_PTR_CAST_ALIGN*/
938fd9ee8b5Sjoyce mcintosh pinfo1 = (struct spoolss_GetPrinter1 *)param->Buf;
939fd9ee8b5Sjoyce mcintosh
940cb174861Sjoyce mcintosh pinfo1->flags = PRINTER_ENUM_ICON8;
941fd9ee8b5Sjoyce mcintosh smb_rpc_off(wname, printer, &offset, &pinfo1->flags);
942fd9ee8b5Sjoyce mcintosh smb_rpc_off(wname, printer, &offset, &pinfo1->description);
943fd9ee8b5Sjoyce mcintosh smb_rpc_off(wname, printer, &offset, &pinfo1->comment);
944cb174861Sjoyce mcintosh break;
945cb174861Sjoyce mcintosh case 2:
946fd9ee8b5Sjoyce mcintosh /*LINTED E_BAD_PTR_CAST_ALIGN*/
947fd9ee8b5Sjoyce mcintosh pinfo2 = (struct spoolss_GetPrinter2 *)param->Buf;
948fd9ee8b5Sjoyce mcintosh
949fd9ee8b5Sjoyce mcintosh smb_rpc_off(wname, server, &offset, &pinfo2->servername);
950fd9ee8b5Sjoyce mcintosh smb_rpc_off(wname, printer, &offset, &pinfo2->printername);
951cb174861Sjoyce mcintosh smb_rpc_off(wname, SPOOLSS_PRINTER, &offset,
952cb174861Sjoyce mcintosh &pinfo2->sharename);
953cb174861Sjoyce mcintosh smb_rpc_off(wname, "CIFS Printer Port", &offset,
954cb174861Sjoyce mcintosh &pinfo2->portname);
955cb174861Sjoyce mcintosh smb_rpc_off(wname, "", &offset, &pinfo2->drivername);
956cb174861Sjoyce mcintosh smb_rpc_off(wname, SPOOLSS_PRINTER, &offset,
957cb174861Sjoyce mcintosh &pinfo2->comment);
958cb174861Sjoyce mcintosh smb_rpc_off(wname, "farside", &offset, &pinfo2->location);
959fd9ee8b5Sjoyce mcintosh
960fd9ee8b5Sjoyce mcintosh offset -= sizeof (struct spoolss_DeviceMode);
961fd9ee8b5Sjoyce mcintosh pinfo2->devmode = offset;
962fd9ee8b5Sjoyce mcintosh /*LINTED E_BAD_PTR_CAST_ALIGN*/
963fd9ee8b5Sjoyce mcintosh devmode2 = (struct spoolss_DeviceMode *)(param->Buf + offset);
964fd9ee8b5Sjoyce mcintosh
965cb174861Sjoyce mcintosh smb_rpc_off(wname, "farside", &offset, &pinfo2->sepfile);
966cb174861Sjoyce mcintosh smb_rpc_off(wname, "winprint", &offset,
967cb174861Sjoyce mcintosh &pinfo2->printprocessor);
968cb174861Sjoyce mcintosh smb_rpc_off(wname, "RAW", &offset, &pinfo2->datatype);
969fd9ee8b5Sjoyce mcintosh smb_rpc_off(wname, "", &offset, &pinfo2->parameters);
970fd9ee8b5Sjoyce mcintosh
971fd9ee8b5Sjoyce mcintosh status = spoolss_make_sd(mxa, &secdesc);
972fd9ee8b5Sjoyce mcintosh if (status == ERROR_SUCCESS) {
973fd9ee8b5Sjoyce mcintosh offset -= secdesc.sd_size;
974fd9ee8b5Sjoyce mcintosh pinfo2->secdesc = offset;
975fd9ee8b5Sjoyce mcintosh tmpbuf = (uint8_t *)(param->Buf + offset);
976fd9ee8b5Sjoyce mcintosh bcopy(secdesc.sd_buf, tmpbuf, secdesc.sd_size);
977fd9ee8b5Sjoyce mcintosh }
978fd9ee8b5Sjoyce mcintosh
979cb174861Sjoyce mcintosh pinfo2->attributes = 0x00001048;
980cb174861Sjoyce mcintosh pinfo2->status = 0x00000000;
981cb174861Sjoyce mcintosh pinfo2->starttime = 0;
982cb174861Sjoyce mcintosh pinfo2->untiltime = 0;
983cb174861Sjoyce mcintosh pinfo2->cjobs = 0;
984cb174861Sjoyce mcintosh pinfo2->averageppm = 0;
985cb174861Sjoyce mcintosh pinfo2->defaultpriority = 0;
986fd9ee8b5Sjoyce mcintosh
987cb174861Sjoyce mcintosh /*LINTED E_BAD_PTR_CAST_ALIGN*/
988fd9ee8b5Sjoyce mcintosh (void) smb_mbstowcs((smb_wchar_t *)devmode2->devicename,
989fd9ee8b5Sjoyce mcintosh printer, 32);
990cb174861Sjoyce mcintosh devmode2->specversion = 0x0401;
991cb174861Sjoyce mcintosh devmode2->driverversion = 1024;
992cb174861Sjoyce mcintosh devmode2->size = 220;
993cb174861Sjoyce mcintosh devmode2->driverextra_length = 0;
994cb174861Sjoyce mcintosh devmode2->fields = 0x00014713;
995cb174861Sjoyce mcintosh devmode2->orientation = 1;
996cb174861Sjoyce mcintosh devmode2->papersize = 1;
997cb174861Sjoyce mcintosh devmode2->paperlength = 0;
998cb174861Sjoyce mcintosh devmode2->paperwidth = 0;
999cb174861Sjoyce mcintosh devmode2->scale = 100;
1000cb174861Sjoyce mcintosh devmode2->copies = 1;
1001cb174861Sjoyce mcintosh devmode2->defaultsource = 15;
1002cb174861Sjoyce mcintosh devmode2->printquality = 65532;
1003cb174861Sjoyce mcintosh devmode2->color = 1;
1004cb174861Sjoyce mcintosh devmode2->duplex = 1;
1005cb174861Sjoyce mcintosh devmode2->yresolution = 1;
1006cb174861Sjoyce mcintosh devmode2->ttoption = 1;
1007cb174861Sjoyce mcintosh devmode2->collate = 0;
1008cb174861Sjoyce mcintosh /*LINTED E_BAD_PTR_CAST_ALIGN*/
1009fd9ee8b5Sjoyce mcintosh (void) smb_mbstowcs((smb_wchar_t *)devmode2->formname,
1010fd9ee8b5Sjoyce mcintosh "Letter", 32);
1011cb174861Sjoyce mcintosh devmode2->logpixels = 0;
1012cb174861Sjoyce mcintosh devmode2->bitsperpel = 0;
1013cb174861Sjoyce mcintosh devmode2->pelswidth = 0;
1014cb174861Sjoyce mcintosh devmode2->pelsheight = 0;
1015cb174861Sjoyce mcintosh devmode2->displayflags = 0;
1016cb174861Sjoyce mcintosh devmode2->displayfrequency = 0;
1017cb174861Sjoyce mcintosh devmode2->icmmethod = 0;
1018cb174861Sjoyce mcintosh devmode2->icmintent = 0;
1019cb174861Sjoyce mcintosh devmode2->mediatype = 0;
1020cb174861Sjoyce mcintosh devmode2->dithertype = 0;
1021cb174861Sjoyce mcintosh devmode2->reserved1 = 0;
1022cb174861Sjoyce mcintosh devmode2->reserved2 = 0;
1023cb174861Sjoyce mcintosh devmode2->panningwidth = 0;
1024cb174861Sjoyce mcintosh devmode2->panningheight = 0;
1025cb174861Sjoyce mcintosh break;
1026cb174861Sjoyce mcintosh
1027cb174861Sjoyce mcintosh default:
1028cb174861Sjoyce mcintosh break;
1029cb174861Sjoyce mcintosh }
1030fd9ee8b5Sjoyce mcintosh
1031fd9ee8b5Sjoyce mcintosh param->status = status;
1032fd9ee8b5Sjoyce mcintosh return (NDR_DRC_OK);
1033fd9ee8b5Sjoyce mcintosh
1034cb174861Sjoyce mcintosh error_out:
1035fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_GetPrinter: error %u", status);
1036fd9ee8b5Sjoyce mcintosh bzero(param, sizeof (struct spoolss_GetPrinter));
1037cb174861Sjoyce mcintosh param->status = status;
1038cb174861Sjoyce mcintosh return (NDR_DRC_OK);
1039cb174861Sjoyce mcintosh }
1040cb174861Sjoyce mcintosh
1041fd9ee8b5Sjoyce mcintosh static int
spoolss_getservername(char * name,size_t namelen)1042fd9ee8b5Sjoyce mcintosh spoolss_getservername(char *name, size_t namelen)
1043cb174861Sjoyce mcintosh {
1044fd9ee8b5Sjoyce mcintosh char hostname[MAXHOSTNAMELEN];
1045fd9ee8b5Sjoyce mcintosh char ipstr[INET6_ADDRSTRLEN];
1046fd9ee8b5Sjoyce mcintosh smb_inaddr_t ipaddr;
1047fd9ee8b5Sjoyce mcintosh struct hostent *h;
1048fd9ee8b5Sjoyce mcintosh const char *p;
1049fd9ee8b5Sjoyce mcintosh int error;
1050fd9ee8b5Sjoyce mcintosh
1051fd9ee8b5Sjoyce mcintosh if (smb_gethostname(hostname, MAXHOSTNAMELEN, 0) != 0) {
1052fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_GetPrinter: gethostname failed");
1053fd9ee8b5Sjoyce mcintosh return (-1);
1054fd9ee8b5Sjoyce mcintosh }
1055cb174861Sjoyce mcintosh
1056fd9ee8b5Sjoyce mcintosh if ((h = smb_gethostbyname(hostname, &error)) == NULL) {
1057fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_GetPrinter: gethostbyname failed: %d",
1058fd9ee8b5Sjoyce mcintosh error);
1059fd9ee8b5Sjoyce mcintosh return (-1);
1060fd9ee8b5Sjoyce mcintosh }
1061cb174861Sjoyce mcintosh
1062fd9ee8b5Sjoyce mcintosh bcopy(h->h_addr, &ipaddr, h->h_length);
1063fd9ee8b5Sjoyce mcintosh ipaddr.a_family = h->h_addrtype;
1064fd9ee8b5Sjoyce mcintosh freehostent(h);
1065fd9ee8b5Sjoyce mcintosh
1066fd9ee8b5Sjoyce mcintosh p = smb_inet_ntop(&ipaddr, ipstr, SMB_IPSTRLEN(ipaddr.a_family));
1067fd9ee8b5Sjoyce mcintosh if (p == NULL) {
1068fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_s_GetPrinter: inet_ntop failed");
1069fd9ee8b5Sjoyce mcintosh return (-1);
1070cb174861Sjoyce mcintosh }
1071fd9ee8b5Sjoyce mcintosh
1072fd9ee8b5Sjoyce mcintosh (void) snprintf(name, namelen, "\\\\%s", ipstr);
1073fd9ee8b5Sjoyce mcintosh return (0);
1074fd9ee8b5Sjoyce mcintosh }
1075fd9ee8b5Sjoyce mcintosh
1076fd9ee8b5Sjoyce mcintosh static uint32_t
spoolss_make_sd(ndr_xa_t * mxa,spoolss_sd_t * secdesc)1077fd9ee8b5Sjoyce mcintosh spoolss_make_sd(ndr_xa_t *mxa, spoolss_sd_t *secdesc)
1078fd9ee8b5Sjoyce mcintosh {
1079fd9ee8b5Sjoyce mcintosh smb_sd_t sd;
1080fd9ee8b5Sjoyce mcintosh uint8_t *sd_buf;
1081fd9ee8b5Sjoyce mcintosh uint32_t sd_len;
1082fd9ee8b5Sjoyce mcintosh uint32_t status;
1083fd9ee8b5Sjoyce mcintosh
1084fd9ee8b5Sjoyce mcintosh bzero(&sd, sizeof (smb_sd_t));
1085fd9ee8b5Sjoyce mcintosh
1086fd9ee8b5Sjoyce mcintosh if ((status = spoolss_format_sd(&sd)) != ERROR_SUCCESS)
1087fd9ee8b5Sjoyce mcintosh return (status);
1088fd9ee8b5Sjoyce mcintosh
1089fd9ee8b5Sjoyce mcintosh sd_len = smb_sd_len(&sd, SMB_ALL_SECINFO);
1090fd9ee8b5Sjoyce mcintosh
1091fd9ee8b5Sjoyce mcintosh if ((sd_buf = NDR_MALLOC(mxa, sd_len)) == NULL)
1092fd9ee8b5Sjoyce mcintosh return (ERROR_NOT_ENOUGH_MEMORY);
1093fd9ee8b5Sjoyce mcintosh
1094fd9ee8b5Sjoyce mcintosh secdesc->sd_buf = sd_buf;
1095fd9ee8b5Sjoyce mcintosh secdesc->sd_size = sd_len;
1096fd9ee8b5Sjoyce mcintosh
1097fd9ee8b5Sjoyce mcintosh status = srvsvc_sd_set_relative(&sd, sd_buf);
1098cb174861Sjoyce mcintosh smb_sd_term(&sd);
1099fd9ee8b5Sjoyce mcintosh return (status);
1100cb174861Sjoyce mcintosh }
1101cb174861Sjoyce mcintosh
1102cb174861Sjoyce mcintosh static uint32_t
spoolss_format_sd(smb_sd_t * sd)1103fd9ee8b5Sjoyce mcintosh spoolss_format_sd(smb_sd_t *sd)
1104cb174861Sjoyce mcintosh {
1105cb174861Sjoyce mcintosh smb_fssd_t fs_sd;
1106cb174861Sjoyce mcintosh acl_t *acl;
1107cb174861Sjoyce mcintosh uint32_t status = ERROR_SUCCESS;
1108cb174861Sjoyce mcintosh
1109cb174861Sjoyce mcintosh if (acl_fromtext("everyone@:full_set::allow", &acl) != 0) {
1110fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_format_sd: NOT_ENOUGH_MEMORY");
1111cb174861Sjoyce mcintosh return (ERROR_NOT_ENOUGH_MEMORY);
1112cb174861Sjoyce mcintosh }
1113cb174861Sjoyce mcintosh smb_fssd_init(&fs_sd, SMB_ALL_SECINFO, SMB_FSSD_FLAGS_DIR);
1114cb174861Sjoyce mcintosh fs_sd.sd_uid = 0;
1115cb174861Sjoyce mcintosh fs_sd.sd_gid = 0;
1116cb174861Sjoyce mcintosh fs_sd.sd_zdacl = acl;
1117cb174861Sjoyce mcintosh fs_sd.sd_zsacl = NULL;
1118cb174861Sjoyce mcintosh
1119fd9ee8b5Sjoyce mcintosh status = smb_sd_fromfs(&fs_sd, sd);
1120fd9ee8b5Sjoyce mcintosh if (status != NT_STATUS_SUCCESS) {
1121fd9ee8b5Sjoyce mcintosh smb_tracef("spoolss_format_sd: %u", status);
1122cb174861Sjoyce mcintosh status = ERROR_ACCESS_DENIED;
1123cb174861Sjoyce mcintosh }
1124cb174861Sjoyce mcintosh smb_fssd_term(&fs_sd);
1125cb174861Sjoyce mcintosh return (status);
1126cb174861Sjoyce mcintosh }
1127cb174861Sjoyce mcintosh
1128cb174861Sjoyce mcintosh /*ARGSUSED*/
1129cb174861Sjoyce mcintosh static int
spoolss_s_stub(void * arg,ndr_xa_t * mxa)11308d7e4166Sjose borrego spoolss_s_stub(void *arg, ndr_xa_t *mxa)
11318d7e4166Sjose borrego {
11328d7e4166Sjose borrego return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED);
11338d7e4166Sjose borrego }
1134cb174861Sjoyce mcintosh
1135cb174861Sjoyce mcintosh void
fixup_spoolss_RFNPCNEX(struct spoolss_RFNPCNEX * val)1136cb174861Sjoyce mcintosh fixup_spoolss_RFNPCNEX(struct spoolss_RFNPCNEX *val)
1137cb174861Sjoyce mcintosh {
1138cb174861Sjoyce mcintosh unsigned short size1 = 0;
1139cb174861Sjoyce mcintosh unsigned short size2 = 0;
1140cb174861Sjoyce mcintosh unsigned short size3 = 0;
1141cb174861Sjoyce mcintosh struct spoolss_RPC_V2_NOTIFY_INFO *pinfo;
1142cb174861Sjoyce mcintosh
1143cb174861Sjoyce mcintosh pinfo = val->ppinfo->pinfo;
1144cb174861Sjoyce mcintosh switch (pinfo->aData->Reserved) {
1145cb174861Sjoyce mcintosh case TABLE_STRING:
1146cb174861Sjoyce mcintosh size1 = sizeof (struct STRING_CONTAINER);
1147cb174861Sjoyce mcintosh break;
1148cb174861Sjoyce mcintosh case TABLE_DWORD:
1149cb174861Sjoyce mcintosh size1 = sizeof (DWORD) * 2;
1150cb174861Sjoyce mcintosh break;
1151cb174861Sjoyce mcintosh case TABLE_TIME:
1152cb174861Sjoyce mcintosh size1 = sizeof (struct SYSTEMTIME_CONTAINER);
1153cb174861Sjoyce mcintosh break;
1154cb174861Sjoyce mcintosh case TABLE_DEVMODE:
1155cb174861Sjoyce mcintosh size1 = sizeof (struct spoolssDevmodeContainer);
1156cb174861Sjoyce mcintosh break;
1157cb174861Sjoyce mcintosh case TABLE_SECURITY_DESCRIPTOR:
1158cb174861Sjoyce mcintosh size1 = sizeof (struct SECURITY_CONTAINER);
1159cb174861Sjoyce mcintosh break;
1160cb174861Sjoyce mcintosh default:
1161cb174861Sjoyce mcintosh return;
1162cb174861Sjoyce mcintosh }
1163cb174861Sjoyce mcintosh size2 = size1 + (2 * sizeof (DWORD));
1164cb174861Sjoyce mcintosh size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
1165cb174861Sjoyce mcintosh
1166cb174861Sjoyce mcintosh FIXUP_PDU_SIZE(spoolss_RPC_V2_NOTIFY_INFO_DATA_DATA, size1);
1167cb174861Sjoyce mcintosh FIXUP_PDU_SIZE(spoolss_RPC_V2_NOTIFY_INFO_DATA, size2);
1168cb174861Sjoyce mcintosh FIXUP_PDU_SIZE(spoolss_RPC_V2_NOTIFY_INFO, size3);
1169cb174861Sjoyce mcintosh FIXUP_PDU_SIZE(spoolss_RFNPCNEX, size3);
1170cb174861Sjoyce mcintosh }
1171cb174861Sjoyce mcintosh
1172cb174861Sjoyce mcintosh void
fixup_spoolss_GetPrinter(struct spoolss_GetPrinter * val)1173cb174861Sjoyce mcintosh fixup_spoolss_GetPrinter(struct spoolss_GetPrinter *val)
1174cb174861Sjoyce mcintosh {
1175cb174861Sjoyce mcintosh unsigned short size1 = 0;
1176cb174861Sjoyce mcintosh unsigned short size2 = 0;
1177cb174861Sjoyce mcintosh unsigned short size3 = 0;
1178cb174861Sjoyce mcintosh
1179cb174861Sjoyce mcintosh switch (val->switch_value) {
1180cb174861Sjoyce mcintosh CASE_INFO_ENT(spoolss_GetPrinter, 0);
1181cb174861Sjoyce mcintosh CASE_INFO_ENT(spoolss_GetPrinter, 1);
1182cb174861Sjoyce mcintosh CASE_INFO_ENT(spoolss_GetPrinter, 2);
1183cb174861Sjoyce mcintosh CASE_INFO_ENT(spoolss_GetPrinter, 3);
1184cb174861Sjoyce mcintosh CASE_INFO_ENT(spoolss_GetPrinter, 4);
1185cb174861Sjoyce mcintosh CASE_INFO_ENT(spoolss_GetPrinter, 5);
1186cb174861Sjoyce mcintosh CASE_INFO_ENT(spoolss_GetPrinter, 6);
1187cb174861Sjoyce mcintosh CASE_INFO_ENT(spoolss_GetPrinter, 7);
1188cb174861Sjoyce mcintosh CASE_INFO_ENT(spoolss_GetPrinter, 8);
1189cb174861Sjoyce mcintosh
1190cb174861Sjoyce mcintosh default:
1191cb174861Sjoyce mcintosh return;
1192cb174861Sjoyce mcintosh };
1193cb174861Sjoyce mcintosh
1194cb174861Sjoyce mcintosh size2 = size1 + (2 * sizeof (DWORD));
1195cb174861Sjoyce mcintosh size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
1196cb174861Sjoyce mcintosh
1197cb174861Sjoyce mcintosh FIXUP_PDU_SIZE(spoolss_GetPrinter_result_u, size1);
1198cb174861Sjoyce mcintosh FIXUP_PDU_SIZE(spoolss_GetPrinter_result, size2);
1199cb174861Sjoyce mcintosh FIXUP_PDU_SIZE(spoolss_GetPrinter, size3);
1200cb174861Sjoyce mcintosh }
120186d7016bSGordon Ross
120286d7016bSGordon Ross #else /* HAVE_CUPS */
120386d7016bSGordon Ross
120486d7016bSGordon Ross /*
120586d7016bSGordon Ross * If not HAVE_CUPS, just provide a few "stubs".
120686d7016bSGordon Ross */
120786d7016bSGordon Ross
120886d7016bSGordon Ross void
spoolss_initialize(void)120986d7016bSGordon Ross spoolss_initialize(void)
121086d7016bSGordon Ross {
121186d7016bSGordon Ross }
121286d7016bSGordon Ross
121386d7016bSGordon Ross void
spoolss_finalize(void)121486d7016bSGordon Ross spoolss_finalize(void)
121586d7016bSGordon Ross {
121686d7016bSGordon Ross }
121786d7016bSGordon Ross
121886d7016bSGordon Ross /*ARGSUSED*/
121986d7016bSGordon Ross void
spoolss_register_copyfile(spoolss_copyfile_t copyfile)122086d7016bSGordon Ross spoolss_register_copyfile(spoolss_copyfile_t copyfile)
122186d7016bSGordon Ross {
122286d7016bSGordon Ross }
122386d7016bSGordon Ross
122486d7016bSGordon Ross #endif /* HAVE_CUPS */
1225