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