xref: /onnv-gate/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c (revision 12890:16985853e3aa)
18334SJose.Borrego@Sun.COM /*
28334SJose.Borrego@Sun.COM  * CDDL HEADER START
38334SJose.Borrego@Sun.COM  *
48334SJose.Borrego@Sun.COM  * The contents of this file are subject to the terms of the
58334SJose.Borrego@Sun.COM  * Common Development and Distribution License (the "License").
68334SJose.Borrego@Sun.COM  * You may not use this file except in compliance with the License.
78334SJose.Borrego@Sun.COM  *
88334SJose.Borrego@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98334SJose.Borrego@Sun.COM  * or http://www.opensolaris.org/os/licensing.
108334SJose.Borrego@Sun.COM  * See the License for the specific language governing permissions
118334SJose.Borrego@Sun.COM  * and limitations under the License.
128334SJose.Borrego@Sun.COM  *
138334SJose.Borrego@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
148334SJose.Borrego@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158334SJose.Borrego@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
168334SJose.Borrego@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
178334SJose.Borrego@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
188334SJose.Borrego@Sun.COM  *
198334SJose.Borrego@Sun.COM  * CDDL HEADER END
208334SJose.Borrego@Sun.COM  */
218334SJose.Borrego@Sun.COM /*
22*12890SJoyce.McIntosh@Sun.COM  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
238334SJose.Borrego@Sun.COM  */
248334SJose.Borrego@Sun.COM 
258334SJose.Borrego@Sun.COM /*
268334SJose.Borrego@Sun.COM  * Printing and Spooling RPC service.
278334SJose.Borrego@Sun.COM  */
28*12890SJoyce.McIntosh@Sun.COM #include <unistd.h>
298334SJose.Borrego@Sun.COM #include <stdlib.h>
308334SJose.Borrego@Sun.COM #include <strings.h>
31*12890SJoyce.McIntosh@Sun.COM #include <pthread.h>
32*12890SJoyce.McIntosh@Sun.COM #include <synch.h>
338334SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h>
348334SJose.Borrego@Sun.COM #include <smbsrv/libmlrpc.h>
358334SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h>
36*12890SJoyce.McIntosh@Sun.COM #include <smbsrv/ndl/ndrtypes.ndl>
378334SJose.Borrego@Sun.COM #include <smbsrv/ndl/spoolss.ndl>
38*12890SJoyce.McIntosh@Sun.COM #include <smb/nterror.h>
398334SJose.Borrego@Sun.COM #include <smbsrv/smbinfo.h>
408334SJose.Borrego@Sun.COM #include <smbsrv/nmpipes.h>
41*12890SJoyce.McIntosh@Sun.COM #include <wchar.h>
42*12890SJoyce.McIntosh@Sun.COM #include <cups/cups.h>
43*12890SJoyce.McIntosh@Sun.COM #include <fcntl.h>
44*12890SJoyce.McIntosh@Sun.COM #include <sys/types.h>
45*12890SJoyce.McIntosh@Sun.COM #include <sys/stat.h>
46*12890SJoyce.McIntosh@Sun.COM #include <errno.h>
47*12890SJoyce.McIntosh@Sun.COM #include <dlfcn.h>
48*12890SJoyce.McIntosh@Sun.COM #include <mlsvc.h>
498334SJose.Borrego@Sun.COM 
50*12890SJoyce.McIntosh@Sun.COM typedef struct smb_spool {
51*12890SJoyce.McIntosh@Sun.COM 	list_t sp_list;
52*12890SJoyce.McIntosh@Sun.COM 	int sp_cnt;
53*12890SJoyce.McIntosh@Sun.COM 	rwlock_t sp_rwl;
54*12890SJoyce.McIntosh@Sun.COM 	int sp_initialized;
55*12890SJoyce.McIntosh@Sun.COM } smb_spool_t;
56*12890SJoyce.McIntosh@Sun.COM 
57*12890SJoyce.McIntosh@Sun.COM static uint32_t spoolss_cnt;
58*12890SJoyce.McIntosh@Sun.COM static uint32_t spoolss_jobnum = 1;
59*12890SJoyce.McIntosh@Sun.COM static smb_spool_t spoolss_splist;
60*12890SJoyce.McIntosh@Sun.COM static smb_cups_ops_t smb_cups;
61*12890SJoyce.McIntosh@Sun.COM static mutex_t spoolss_cups_mutex;
62*12890SJoyce.McIntosh@Sun.COM 
63*12890SJoyce.McIntosh@Sun.COM #define	SPOOLSS_PJOBLEN		256
64*12890SJoyce.McIntosh@Sun.COM #define	SPOOLSS_JOB_NOT_ISSUED	3004
65*12890SJoyce.McIntosh@Sun.COM #define	SPOOLSS_PRINTER		"Postscript"
66*12890SJoyce.McIntosh@Sun.COM #define	SPOOLSS_FN_PREFIX	"cifsprintjob-"
67*12890SJoyce.McIntosh@Sun.COM #define	SPOOLSS_CUPS_SPOOL_DIR	"//var//spool//cups"
68*12890SJoyce.McIntosh@Sun.COM 
69*12890SJoyce.McIntosh@Sun.COM struct spoolss_printjob {
70*12890SJoyce.McIntosh@Sun.COM 	pid_t pj_pid;
71*12890SJoyce.McIntosh@Sun.COM 	int pj_sysjob;
72*12890SJoyce.McIntosh@Sun.COM 	int pj_fd;
73*12890SJoyce.McIntosh@Sun.COM 	time_t pj_start_time;
74*12890SJoyce.McIntosh@Sun.COM 	int pj_status;
75*12890SJoyce.McIntosh@Sun.COM 	size_t pj_size;
76*12890SJoyce.McIntosh@Sun.COM 	int pj_page_count;
77*12890SJoyce.McIntosh@Sun.COM 	boolean_t pj_isspooled;
78*12890SJoyce.McIntosh@Sun.COM 	boolean_t pj_jobnum;
79*12890SJoyce.McIntosh@Sun.COM 	char pj_filename[SPOOLSS_PJOBLEN];
80*12890SJoyce.McIntosh@Sun.COM 	char pj_jobname[SPOOLSS_PJOBLEN];
81*12890SJoyce.McIntosh@Sun.COM 	char pj_username[SPOOLSS_PJOBLEN];
82*12890SJoyce.McIntosh@Sun.COM 	char pj_queuename[SPOOLSS_PJOBLEN];
83*12890SJoyce.McIntosh@Sun.COM };
84*12890SJoyce.McIntosh@Sun.COM 
85*12890SJoyce.McIntosh@Sun.COM DECL_FIXUP_STRUCT(spoolss_GetPrinter_result_u);
86*12890SJoyce.McIntosh@Sun.COM DECL_FIXUP_STRUCT(spoolss_GetPrinter_result);
87*12890SJoyce.McIntosh@Sun.COM DECL_FIXUP_STRUCT(spoolss_GetPrinter);
88*12890SJoyce.McIntosh@Sun.COM 
89*12890SJoyce.McIntosh@Sun.COM DECL_FIXUP_STRUCT(spoolss_RPC_V2_NOTIFY_INFO_DATA_DATA);
90*12890SJoyce.McIntosh@Sun.COM DECL_FIXUP_STRUCT(spoolss_RPC_V2_NOTIFY_INFO_DATA);
91*12890SJoyce.McIntosh@Sun.COM DECL_FIXUP_STRUCT(spoolss_RPC_V2_NOTIFY_INFO);
92*12890SJoyce.McIntosh@Sun.COM DECL_FIXUP_STRUCT(spoolss_RFNPCNEX);
93*12890SJoyce.McIntosh@Sun.COM 
94*12890SJoyce.McIntosh@Sun.COM uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *);
95*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_make_sd(uint8_t *);
96*12890SJoyce.McIntosh@Sun.COM static uint32_t spoolss_sd_format(smb_sd_t *);
97*12890SJoyce.McIntosh@Sun.COM static int spoolss_find_fd(ndr_hdid_t *);
98*12890SJoyce.McIntosh@Sun.COM static void spoolss_find_doc_and_print(ndr_hdid_t *);
99*12890SJoyce.McIntosh@Sun.COM static void spoolss_add_spool_doc(smb_spooldoc_t *);
100*12890SJoyce.McIntosh@Sun.COM static int spoolss_cups_init(void);
101*12890SJoyce.McIntosh@Sun.COM static void spoolss_cups_fini(void);
102*12890SJoyce.McIntosh@Sun.COM 
103*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_OpenPrinter(void *, ndr_xa_t *);
104*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_ClosePrinter(void *, ndr_xa_t *);
105*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_AbortPrinter(void *, ndr_xa_t *);
106*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_ResetPrinter(void *, ndr_xa_t *);
107*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_GetPrinter(void *, ndr_xa_t *);
108*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_GetPrinterData(void *, ndr_xa_t *);
109*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_AddJob(void *, ndr_xa_t *);
110*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_GetJob(void *, ndr_xa_t *);
111*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_EnumJobs(void *, ndr_xa_t *);
112*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_ScheduleJob(void *, ndr_xa_t *);
113*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_StartDocPrinter(void *, ndr_xa_t *);
114*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_EndDocPrinter(void *, ndr_xa_t *);
115*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_StartPagePrinter(void *, ndr_xa_t *);
116*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_EndPagePrinter(void *, ndr_xa_t *);
117*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_rfnpcnex(void *, ndr_xa_t *);
118*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_WritePrinter(void *, ndr_xa_t *);
119*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_EnumForms(void *, ndr_xa_t *);
120*12890SJoyce.McIntosh@Sun.COM static int spoolss_s_stub(void *, ndr_xa_t *);
1218334SJose.Borrego@Sun.COM 
1228334SJose.Borrego@Sun.COM static ndr_stub_table_t spoolss_stub_table[] = {
123*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_GetJob,		SPOOLSS_OPNUM_GetJob },
124*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_EnumJobs,		SPOOLSS_OPNUM_EnumJobs },
125*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_stub, SPOOLSS_OPNUM_DeletePrinter },
126*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_GetPrinter,		SPOOLSS_OPNUM_GetPrinter },
127*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_stub,		SPOOLSS_OPNUM_GetPrinterDriver },
128*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_stub,		SPOOLSS_OPNUM_DeletePrinterDriver },
1298334SJose.Borrego@Sun.COM 	{ spoolss_s_OpenPrinter,	SPOOLSS_OPNUM_OpenPrinter },
130*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_StartDocPrinter,	SPOOLSS_OPNUM_StartDocPrinter },
131*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_WritePrinter,	SPOOLSS_OPNUM_WritePrinter },
132*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_EndDocPrinter,	SPOOLSS_OPNUM_EndDocPrinter },
133*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_StartPagePrinter,	SPOOLSS_OPNUM_StartPagePrinter },
134*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_EndPagePrinter,	SPOOLSS_OPNUM_EndPagePrinter },
135*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_AbortPrinter,	SPOOLSS_OPNUM_AbortPrinter },
136*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_ResetPrinter,	SPOOLSS_OPNUM_ResetPrinter },
137*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_AddJob,		SPOOLSS_OPNUM_AddJob },
138*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_ScheduleJob,    	SPOOLSS_OPNUM_ScheduleJob },
139*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_GetPrinterData,	SPOOLSS_OPNUM_GetPrinterData },
140*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_ClosePrinter,	SPOOLSS_OPNUM_ClosePrinter },
141*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_EnumForms,		SPOOLSS_OPNUM_EnumForms },
142*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_stub,		SPOOLSS_OPNUM_GetPrinterDriver2 },
143*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_stub,		SPOOLSS_OPNUM_FCPN },
144*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_stub,		SPOOLSS_OPNUM_ReplyOpenPrinter },
145*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_stub,		SPOOLSS_OPNUM_ReplyClosePrinter },
146*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_stub,		SPOOLSS_OPNUM_RFFPCNEX },
147*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_rfnpcnex,		SPOOLSS_OPNUM_RFNPCNEX },
148*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_stub,		SPOOLSS_OPNUM_RRPCN },
149*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_OpenPrinter,	SPOOLSS_OPNUM_OpenPrinterEx },
150*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_stub,		SPOOLSS_OPNUM_EnumPrinterData },
151*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_stub,		SPOOLSS_OPNUM_EnumPrinterDataEx },
152*12890SJoyce.McIntosh@Sun.COM 	{ spoolss_s_stub,		SPOOLSS_OPNUM_EnumPrinterKey },
1538334SJose.Borrego@Sun.COM 	{0}
1548334SJose.Borrego@Sun.COM };
1558334SJose.Borrego@Sun.COM 
1568334SJose.Borrego@Sun.COM static ndr_service_t spoolss_service = {
1578334SJose.Borrego@Sun.COM 	"SPOOLSS",			/* name */
1588334SJose.Borrego@Sun.COM 	"Print Spool Service",		/* desc */
1598334SJose.Borrego@Sun.COM 	"\\spoolss",			/* endpoint */
1608334SJose.Borrego@Sun.COM 	PIPE_SPOOLSS,			/* sec_addr_port */
161*12890SJoyce.McIntosh@Sun.COM 	"12345678-1234-abcd-ef00-0123456789ab",	1,	/* abstract */
1628334SJose.Borrego@Sun.COM 	NDR_TRANSFER_SYNTAX_UUID,		2,	/* transfer */
1638334SJose.Borrego@Sun.COM 	0,				/* no bind_instance_size */
1648334SJose.Borrego@Sun.COM 	0,				/* no bind_req() */
1658334SJose.Borrego@Sun.COM 	0,				/* no unbind_and_close() */
1668334SJose.Borrego@Sun.COM 	0,				/* use generic_call_stub() */
1678334SJose.Borrego@Sun.COM 	&TYPEINFO(spoolss_interface),	/* interface ti */
1688334SJose.Borrego@Sun.COM 	spoolss_stub_table		/* stub_table */
1698334SJose.Borrego@Sun.COM };
1708334SJose.Borrego@Sun.COM 
1718334SJose.Borrego@Sun.COM void
1728334SJose.Borrego@Sun.COM spoolss_initialize(void)
1738334SJose.Borrego@Sun.COM {
1748334SJose.Borrego@Sun.COM 	(void) ndr_svc_register(&spoolss_service);
175*12890SJoyce.McIntosh@Sun.COM 	(void) spoolss_cups_init();
1768334SJose.Borrego@Sun.COM }
1778334SJose.Borrego@Sun.COM 
178*12890SJoyce.McIntosh@Sun.COM void
179*12890SJoyce.McIntosh@Sun.COM spoolss_finalize(void)
180*12890SJoyce.McIntosh@Sun.COM {
181*12890SJoyce.McIntosh@Sun.COM 	spoolss_cups_fini();
182*12890SJoyce.McIntosh@Sun.COM }
183*12890SJoyce.McIntosh@Sun.COM 
184*12890SJoyce.McIntosh@Sun.COM static int
1858334SJose.Borrego@Sun.COM spoolss_s_OpenPrinter(void *arg, ndr_xa_t *mxa)
1868334SJose.Borrego@Sun.COM {
1878334SJose.Borrego@Sun.COM 	struct spoolss_OpenPrinter *param = arg;
188*12890SJoyce.McIntosh@Sun.COM 	ndr_hdid_t *id;
1898334SJose.Borrego@Sun.COM 
190*12890SJoyce.McIntosh@Sun.COM 	if ((id = ndr_hdalloc(mxa, 0)) == NULL) {
191*12890SJoyce.McIntosh@Sun.COM 		bzero(&param->handle, sizeof (spoolss_handle_t));
192*12890SJoyce.McIntosh@Sun.COM 		param->status = ERROR_NOT_ENOUGH_MEMORY;
193*12890SJoyce.McIntosh@Sun.COM 		return (NDR_DRC_OK);
194*12890SJoyce.McIntosh@Sun.COM 	}
195*12890SJoyce.McIntosh@Sun.COM 
196*12890SJoyce.McIntosh@Sun.COM 	bcopy(id, &param->handle, sizeof (spoolss_handle_t));
197*12890SJoyce.McIntosh@Sun.COM 	param->status = 0;
1988334SJose.Borrego@Sun.COM 
199*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
200*12890SJoyce.McIntosh@Sun.COM }
201*12890SJoyce.McIntosh@Sun.COM 
202*12890SJoyce.McIntosh@Sun.COM /*ARGSUSED*/
203*12890SJoyce.McIntosh@Sun.COM static int
204*12890SJoyce.McIntosh@Sun.COM spoolss_s_StartPagePrinter(void *arg, ndr_xa_t *mxa)
205*12890SJoyce.McIntosh@Sun.COM {
206*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_StartPagePrinter *param = arg;
207*12890SJoyce.McIntosh@Sun.COM 
208*12890SJoyce.McIntosh@Sun.COM 	param->status = ERROR_SUCCESS;
2098334SJose.Borrego@Sun.COM 
2108334SJose.Borrego@Sun.COM 	return (NDR_DRC_OK);
2118334SJose.Borrego@Sun.COM }
2128334SJose.Borrego@Sun.COM 
2138334SJose.Borrego@Sun.COM /*ARGSUSED*/
214*12890SJoyce.McIntosh@Sun.COM static int
215*12890SJoyce.McIntosh@Sun.COM spoolss_s_EndPagePrinter(void *arg, ndr_xa_t *mxa)
216*12890SJoyce.McIntosh@Sun.COM {
217*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_EndPagePrinter *param = arg;
218*12890SJoyce.McIntosh@Sun.COM 
219*12890SJoyce.McIntosh@Sun.COM 	param->status = ERROR_SUCCESS;
220*12890SJoyce.McIntosh@Sun.COM 
221*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
222*12890SJoyce.McIntosh@Sun.COM }
223*12890SJoyce.McIntosh@Sun.COM 
224*12890SJoyce.McIntosh@Sun.COM /*
225*12890SJoyce.McIntosh@Sun.COM  *
226*12890SJoyce.McIntosh@Sun.COM  * adds new spool doc to the tail.  used by windows
227*12890SJoyce.McIntosh@Sun.COM  * XP and 2000 only
228*12890SJoyce.McIntosh@Sun.COM  *
229*12890SJoyce.McIntosh@Sun.COM  * Return values
230*12890SJoyce.McIntosh@Sun.COM  *      smb_spooldoc_t - NULL if not found
231*12890SJoyce.McIntosh@Sun.COM  */
232*12890SJoyce.McIntosh@Sun.COM 
233*12890SJoyce.McIntosh@Sun.COM static void
234*12890SJoyce.McIntosh@Sun.COM spoolss_add_spool_doc(smb_spooldoc_t *sp)
235*12890SJoyce.McIntosh@Sun.COM {
236*12890SJoyce.McIntosh@Sun.COM 	(void) rw_wrlock(&spoolss_splist.sp_rwl);
237*12890SJoyce.McIntosh@Sun.COM 	if (!spoolss_splist.sp_initialized) {
238*12890SJoyce.McIntosh@Sun.COM 		list_create(&spoolss_splist.sp_list,
239*12890SJoyce.McIntosh@Sun.COM 		    sizeof (smb_spooldoc_t),
240*12890SJoyce.McIntosh@Sun.COM 		    offsetof(smb_spooldoc_t, sd_lnd));
241*12890SJoyce.McIntosh@Sun.COM 		spoolss_splist.sp_initialized = 1;
242*12890SJoyce.McIntosh@Sun.COM 	}
243*12890SJoyce.McIntosh@Sun.COM 	list_insert_tail(&spoolss_splist.sp_list, sp);
244*12890SJoyce.McIntosh@Sun.COM 	spoolss_splist.sp_cnt++;
245*12890SJoyce.McIntosh@Sun.COM 	(void) rw_unlock(&spoolss_splist.sp_rwl);
246*12890SJoyce.McIntosh@Sun.COM }
247*12890SJoyce.McIntosh@Sun.COM 
248*12890SJoyce.McIntosh@Sun.COM /*
249*12890SJoyce.McIntosh@Sun.COM  *
250*12890SJoyce.McIntosh@Sun.COM  * finds a completed spool doc using the RPC handle
251*12890SJoyce.McIntosh@Sun.COM  * as the key, then prints the doc
252*12890SJoyce.McIntosh@Sun.COM  *
253*12890SJoyce.McIntosh@Sun.COM  * XP and 2000 only
254*12890SJoyce.McIntosh@Sun.COM  *
255*12890SJoyce.McIntosh@Sun.COM  */
256*12890SJoyce.McIntosh@Sun.COM 
257*12890SJoyce.McIntosh@Sun.COM static void
258*12890SJoyce.McIntosh@Sun.COM spoolss_find_doc_and_print(ndr_hdid_t *handle)
259*12890SJoyce.McIntosh@Sun.COM {
260*12890SJoyce.McIntosh@Sun.COM 	smb_spooldoc_t *sp;
261*12890SJoyce.McIntosh@Sun.COM 
262*12890SJoyce.McIntosh@Sun.COM 	if (!spoolss_splist.sp_initialized) {
263*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_ERR, "spoolss_find_doc_and_print: not initialized");
264*12890SJoyce.McIntosh@Sun.COM 		return;
265*12890SJoyce.McIntosh@Sun.COM 	}
266*12890SJoyce.McIntosh@Sun.COM 	(void) rw_wrlock(&spoolss_splist.sp_rwl);
267*12890SJoyce.McIntosh@Sun.COM 	sp = list_head(&spoolss_splist.sp_list);
268*12890SJoyce.McIntosh@Sun.COM 	while (sp != NULL) {
269*12890SJoyce.McIntosh@Sun.COM 		/*
270*12890SJoyce.McIntosh@Sun.COM 		 * search the spooldoc list for a matching RPC handle
271*12890SJoyce.McIntosh@Sun.COM 		 * and use the info to pass to cups for printing
272*12890SJoyce.McIntosh@Sun.COM 		 */
273*12890SJoyce.McIntosh@Sun.COM 		if (!memcmp(handle, &(sp->sd_handle), sizeof (ndr_hdid_t))) {
274*12890SJoyce.McIntosh@Sun.COM 			spoolss_copy_spool_file(&sp->sd_ipaddr,
275*12890SJoyce.McIntosh@Sun.COM 			    sp->sd_username, sp->sd_path, sp->sd_doc_name);
276*12890SJoyce.McIntosh@Sun.COM 			(void) close(sp->sd_fd);
277*12890SJoyce.McIntosh@Sun.COM 			list_remove(&spoolss_splist.sp_list, sp);
278*12890SJoyce.McIntosh@Sun.COM 			free(sp);
279*12890SJoyce.McIntosh@Sun.COM 			(void) rw_unlock(&spoolss_splist.sp_rwl);
280*12890SJoyce.McIntosh@Sun.COM 			return;
281*12890SJoyce.McIntosh@Sun.COM 		}
282*12890SJoyce.McIntosh@Sun.COM 		sp = list_next(&spoolss_splist.sp_list, sp);
283*12890SJoyce.McIntosh@Sun.COM 	}
284*12890SJoyce.McIntosh@Sun.COM 	syslog(LOG_ERR, "spoolss_find_doc_and_print: handle not found");
285*12890SJoyce.McIntosh@Sun.COM 	(void) rw_unlock(&spoolss_splist.sp_rwl);
286*12890SJoyce.McIntosh@Sun.COM }
287*12890SJoyce.McIntosh@Sun.COM 
288*12890SJoyce.McIntosh@Sun.COM static int
289*12890SJoyce.McIntosh@Sun.COM spoolss_find_fd(ndr_hdid_t *handle)
290*12890SJoyce.McIntosh@Sun.COM {
291*12890SJoyce.McIntosh@Sun.COM 	smb_spooldoc_t *sp;
292*12890SJoyce.McIntosh@Sun.COM 
293*12890SJoyce.McIntosh@Sun.COM 	if (!spoolss_splist.sp_initialized) {
294*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_ERR, "spoolss_find_fd: not initialized");
295*12890SJoyce.McIntosh@Sun.COM 		return (-1);
296*12890SJoyce.McIntosh@Sun.COM 	}
297*12890SJoyce.McIntosh@Sun.COM 	(void) rw_rdlock(&spoolss_splist.sp_rwl);
298*12890SJoyce.McIntosh@Sun.COM 	sp = list_head(&spoolss_splist.sp_list);
299*12890SJoyce.McIntosh@Sun.COM 	while (sp != NULL) {
300*12890SJoyce.McIntosh@Sun.COM 		/*
301*12890SJoyce.McIntosh@Sun.COM 		 * check for a matching rpc handle in the
302*12890SJoyce.McIntosh@Sun.COM 		 * spooldoc list
303*12890SJoyce.McIntosh@Sun.COM 		 */
304*12890SJoyce.McIntosh@Sun.COM 		if (!memcmp(handle, &(sp->sd_handle), sizeof (ndr_hdid_t))) {
305*12890SJoyce.McIntosh@Sun.COM 			(void) rw_unlock(&spoolss_splist.sp_rwl);
306*12890SJoyce.McIntosh@Sun.COM 			return (sp->sd_fd);
307*12890SJoyce.McIntosh@Sun.COM 		}
308*12890SJoyce.McIntosh@Sun.COM 		sp = list_next(&spoolss_splist.sp_list, sp);
309*12890SJoyce.McIntosh@Sun.COM 	}
310*12890SJoyce.McIntosh@Sun.COM 	syslog(LOG_ERR, "spoolss_find_fd: handle not found");
311*12890SJoyce.McIntosh@Sun.COM 	(void) rw_unlock(&spoolss_splist.sp_rwl);
312*12890SJoyce.McIntosh@Sun.COM 	return (-1);
313*12890SJoyce.McIntosh@Sun.COM }
314*12890SJoyce.McIntosh@Sun.COM 
315*12890SJoyce.McIntosh@Sun.COM /*
316*12890SJoyce.McIntosh@Sun.COM  * Windows XP and 2000 use this mechanism to write spool files.
317*12890SJoyce.McIntosh@Sun.COM  * Creates a spool file fd to be used by spoolss_s_WritePrinter.
318*12890SJoyce.McIntosh@Sun.COM  */
319*12890SJoyce.McIntosh@Sun.COM static int
320*12890SJoyce.McIntosh@Sun.COM spoolss_s_StartDocPrinter(void *arg, ndr_xa_t *mxa)
321*12890SJoyce.McIntosh@Sun.COM {
322*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_StartDocPrinter *param = arg;
323*12890SJoyce.McIntosh@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
324*12890SJoyce.McIntosh@Sun.COM 	smb_spooldoc_t *spfile;
325*12890SJoyce.McIntosh@Sun.COM 	spoolss_DocInfo_t *docinfo;
326*12890SJoyce.McIntosh@Sun.COM 	char g_path[MAXPATHLEN];
327*12890SJoyce.McIntosh@Sun.COM 	smb_share_t si;
328*12890SJoyce.McIntosh@Sun.COM 	int rc;
329*12890SJoyce.McIntosh@Sun.COM 	int fd;
330*12890SJoyce.McIntosh@Sun.COM 
331*12890SJoyce.McIntosh@Sun.COM 	if (ndr_hdlookup(mxa, id) == NULL) {
332*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_ERR, "spoolss_s_StartDocPrinter: invalid handle");
333*12890SJoyce.McIntosh@Sun.COM 		param->status = ERROR_INVALID_HANDLE;
334*12890SJoyce.McIntosh@Sun.COM 		return (NDR_DRC_OK);
335*12890SJoyce.McIntosh@Sun.COM 	}
336*12890SJoyce.McIntosh@Sun.COM 
337*12890SJoyce.McIntosh@Sun.COM 	if ((docinfo = param->dinfo.DocInfoContainer) == NULL) {
338*12890SJoyce.McIntosh@Sun.COM 		param->status = ERROR_INVALID_PARAMETER;
339*12890SJoyce.McIntosh@Sun.COM 		return (NDR_DRC_OK);
340*12890SJoyce.McIntosh@Sun.COM 	}
341*12890SJoyce.McIntosh@Sun.COM 
342*12890SJoyce.McIntosh@Sun.COM 	if ((rc = smb_shr_get(SMB_SHARE_PRINT, &si)) != NERR_Success) {
343*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_INFO, "spoolss_s_StartDocPrinter: %s error=%d",
344*12890SJoyce.McIntosh@Sun.COM 		    SMB_SHARE_PRINT, rc);
345*12890SJoyce.McIntosh@Sun.COM 		param->status = rc;
346*12890SJoyce.McIntosh@Sun.COM 		return (NDR_DRC_OK);
347*12890SJoyce.McIntosh@Sun.COM 	}
348*12890SJoyce.McIntosh@Sun.COM 
349*12890SJoyce.McIntosh@Sun.COM 	if ((spfile = calloc(1, sizeof (smb_spooldoc_t))) == NULL) {
350*12890SJoyce.McIntosh@Sun.COM 		param->status = ERROR_NOT_ENOUGH_MEMORY;
351*12890SJoyce.McIntosh@Sun.COM 		return (NDR_DRC_OK);
352*12890SJoyce.McIntosh@Sun.COM 	}
353*12890SJoyce.McIntosh@Sun.COM 
354*12890SJoyce.McIntosh@Sun.COM 	if (docinfo->doc_name != NULL)
355*12890SJoyce.McIntosh@Sun.COM 		(void) strlcpy(spfile->sd_doc_name,
356*12890SJoyce.McIntosh@Sun.COM 		    (char *)docinfo->doc_name, MAXNAMELEN);
357*12890SJoyce.McIntosh@Sun.COM 	else
358*12890SJoyce.McIntosh@Sun.COM 		(void) strlcpy(spfile->sd_doc_name, "document", MAXNAMELEN);
359*12890SJoyce.McIntosh@Sun.COM 
360*12890SJoyce.McIntosh@Sun.COM 	if (docinfo->printer_name != NULL)
361*12890SJoyce.McIntosh@Sun.COM 		(void) strlcpy(spfile->sd_printer_name,
362*12890SJoyce.McIntosh@Sun.COM 		    (char *)docinfo->printer_name, MAXPATHLEN);
363*12890SJoyce.McIntosh@Sun.COM 	else
364*12890SJoyce.McIntosh@Sun.COM 		(void) strlcpy(spfile->sd_printer_name, "printer", MAXPATHLEN);
365*12890SJoyce.McIntosh@Sun.COM 
366*12890SJoyce.McIntosh@Sun.COM 	spfile->sd_ipaddr = mxa->pipe->np_user.ui_ipaddr;
367*12890SJoyce.McIntosh@Sun.COM 	(void) strlcpy((char *)spfile->sd_username,
368*12890SJoyce.McIntosh@Sun.COM 	    mxa->pipe->np_user.ui_account, MAXNAMELEN);
369*12890SJoyce.McIntosh@Sun.COM 	(void) memcpy(&spfile->sd_handle, &param->handle,
370*12890SJoyce.McIntosh@Sun.COM 	    sizeof (rpc_handle_t));
371*12890SJoyce.McIntosh@Sun.COM 	/*
372*12890SJoyce.McIntosh@Sun.COM 	 *	write temporary spool file to print$
373*12890SJoyce.McIntosh@Sun.COM 	 */
374*12890SJoyce.McIntosh@Sun.COM 	(void) snprintf(g_path, MAXPATHLEN, "%s/%s%d", si.shr_path,
375*12890SJoyce.McIntosh@Sun.COM 	    spfile->sd_username, spoolss_cnt);
376*12890SJoyce.McIntosh@Sun.COM 	atomic_inc_32(&spoolss_cnt);
377*12890SJoyce.McIntosh@Sun.COM 
378*12890SJoyce.McIntosh@Sun.COM 	fd = open(g_path, O_CREAT | O_RDWR, 0600);
379*12890SJoyce.McIntosh@Sun.COM 	if (fd == -1) {
380*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_INFO, "spoolss_s_StartDocPrinter: %s: %s",
381*12890SJoyce.McIntosh@Sun.COM 		    g_path, strerror(errno));
382*12890SJoyce.McIntosh@Sun.COM 		param->status = ERROR_OPEN_FAILED;
383*12890SJoyce.McIntosh@Sun.COM 		free(spfile);
384*12890SJoyce.McIntosh@Sun.COM 	} else {
385*12890SJoyce.McIntosh@Sun.COM 		(void) strlcpy((char *)spfile->sd_path, g_path, MAXPATHLEN);
386*12890SJoyce.McIntosh@Sun.COM 		spfile->sd_fd = (uint16_t)fd;
387*12890SJoyce.McIntosh@Sun.COM 		spoolss_add_spool_doc(spfile);
388*12890SJoyce.McIntosh@Sun.COM 		/*
389*12890SJoyce.McIntosh@Sun.COM 		 * JobId isn't used now, but if printQ management is added
390*12890SJoyce.McIntosh@Sun.COM 		 * this will have to be incremented per job submitted.
391*12890SJoyce.McIntosh@Sun.COM 		 */
392*12890SJoyce.McIntosh@Sun.COM 		param->JobId = 46;
393*12890SJoyce.McIntosh@Sun.COM 		param->status = ERROR_SUCCESS;
394*12890SJoyce.McIntosh@Sun.COM 	}
395*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
396*12890SJoyce.McIntosh@Sun.COM }
397*12890SJoyce.McIntosh@Sun.COM 
398*12890SJoyce.McIntosh@Sun.COM /*
399*12890SJoyce.McIntosh@Sun.COM  * Windows XP and 2000 use this mechanism to write spool files
400*12890SJoyce.McIntosh@Sun.COM  */
401*12890SJoyce.McIntosh@Sun.COM 
402*12890SJoyce.McIntosh@Sun.COM /*ARGSUSED*/
403*12890SJoyce.McIntosh@Sun.COM static int
404*12890SJoyce.McIntosh@Sun.COM spoolss_s_EndDocPrinter(void *arg, ndr_xa_t *mxa)
405*12890SJoyce.McIntosh@Sun.COM {
406*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_EndDocPrinter *param = arg;
407*12890SJoyce.McIntosh@Sun.COM 
408*12890SJoyce.McIntosh@Sun.COM 	spoolss_find_doc_and_print((ndr_hdid_t *)&param->handle);
409*12890SJoyce.McIntosh@Sun.COM 	param->status = ERROR_SUCCESS;
410*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
411*12890SJoyce.McIntosh@Sun.COM }
412*12890SJoyce.McIntosh@Sun.COM 
413*12890SJoyce.McIntosh@Sun.COM /*ARGSUSED*/
414*12890SJoyce.McIntosh@Sun.COM static int
415*12890SJoyce.McIntosh@Sun.COM spoolss_s_AbortPrinter(void *arg, ndr_xa_t *mxa)
416*12890SJoyce.McIntosh@Sun.COM {
417*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_AbortPrinter *param = arg;
418*12890SJoyce.McIntosh@Sun.COM 
419*12890SJoyce.McIntosh@Sun.COM 	param->status = ERROR_SUCCESS;
420*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
421*12890SJoyce.McIntosh@Sun.COM }
422*12890SJoyce.McIntosh@Sun.COM 
423*12890SJoyce.McIntosh@Sun.COM /*ARGSUSED*/
424*12890SJoyce.McIntosh@Sun.COM static int
425*12890SJoyce.McIntosh@Sun.COM spoolss_s_ResetPrinter(void *arg, ndr_xa_t *mxa)
426*12890SJoyce.McIntosh@Sun.COM {
427*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_AbortPrinter *param = arg;
428*12890SJoyce.McIntosh@Sun.COM 
429*12890SJoyce.McIntosh@Sun.COM 	param->status = ERROR_SUCCESS;
430*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
431*12890SJoyce.McIntosh@Sun.COM }
432*12890SJoyce.McIntosh@Sun.COM 
433*12890SJoyce.McIntosh@Sun.COM static int
434*12890SJoyce.McIntosh@Sun.COM spoolss_s_ClosePrinter(void *arg, ndr_xa_t *mxa)
435*12890SJoyce.McIntosh@Sun.COM {
436*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_ClosePrinter *param = arg;
437*12890SJoyce.McIntosh@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
438*12890SJoyce.McIntosh@Sun.COM 	ndr_handle_t *hd;
439*12890SJoyce.McIntosh@Sun.COM 
440*12890SJoyce.McIntosh@Sun.COM 	if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
441*12890SJoyce.McIntosh@Sun.COM 		free(hd->nh_data);
442*12890SJoyce.McIntosh@Sun.COM 		hd->nh_data = NULL;
443*12890SJoyce.McIntosh@Sun.COM 	}
444*12890SJoyce.McIntosh@Sun.COM 
445*12890SJoyce.McIntosh@Sun.COM 	ndr_hdfree(mxa, id);
446*12890SJoyce.McIntosh@Sun.COM 	bzero(&param->result_handle, sizeof (spoolss_handle_t));
447*12890SJoyce.McIntosh@Sun.COM 	param->status = ERROR_SUCCESS;
448*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
449*12890SJoyce.McIntosh@Sun.COM }
450*12890SJoyce.McIntosh@Sun.COM 
451*12890SJoyce.McIntosh@Sun.COM /*ARGSUSED*/
4528334SJose.Borrego@Sun.COM int
453*12890SJoyce.McIntosh@Sun.COM spoolss_s_EnumForms(void *arg, ndr_xa_t *mxa)
454*12890SJoyce.McIntosh@Sun.COM {
455*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_EnumForms *param = arg;
456*12890SJoyce.McIntosh@Sun.COM 	DWORD status = ERROR_SUCCESS;
457*12890SJoyce.McIntosh@Sun.COM 
458*12890SJoyce.McIntosh@Sun.COM 	param->status = status;
459*12890SJoyce.McIntosh@Sun.COM 	param->needed = 0;
460*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
461*12890SJoyce.McIntosh@Sun.COM }
462*12890SJoyce.McIntosh@Sun.COM 
463*12890SJoyce.McIntosh@Sun.COM /*ARGSUSED*/
464*12890SJoyce.McIntosh@Sun.COM int
465*12890SJoyce.McIntosh@Sun.COM spoolss_s_EnumJobs(void *arg, ndr_xa_t *mxa)
466*12890SJoyce.McIntosh@Sun.COM {
467*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_EnumJobs *param = arg;
468*12890SJoyce.McIntosh@Sun.COM 	DWORD status = ERROR_SUCCESS;
469*12890SJoyce.McIntosh@Sun.COM 
470*12890SJoyce.McIntosh@Sun.COM 	switch (param->level) {
471*12890SJoyce.McIntosh@Sun.COM 	case 1:
472*12890SJoyce.McIntosh@Sun.COM 	case 2:
473*12890SJoyce.McIntosh@Sun.COM 	case 3:
474*12890SJoyce.McIntosh@Sun.COM 	case 4:
475*12890SJoyce.McIntosh@Sun.COM 	default:
476*12890SJoyce.McIntosh@Sun.COM 		break;
477*12890SJoyce.McIntosh@Sun.COM 	}
478*12890SJoyce.McIntosh@Sun.COM 
479*12890SJoyce.McIntosh@Sun.COM 	param->status = status;
480*12890SJoyce.McIntosh@Sun.COM 	param->needed = 0;
481*12890SJoyce.McIntosh@Sun.COM 	param->needed2 = 0;
482*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
483*12890SJoyce.McIntosh@Sun.COM }
484*12890SJoyce.McIntosh@Sun.COM 
485*12890SJoyce.McIntosh@Sun.COM 
486*12890SJoyce.McIntosh@Sun.COM /*ARGSUSED*/
487*12890SJoyce.McIntosh@Sun.COM static int
488*12890SJoyce.McIntosh@Sun.COM spoolss_s_GetJob(void *arg, ndr_xa_t *mxa)
489*12890SJoyce.McIntosh@Sun.COM {
490*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_GetJob *param = arg;
491*12890SJoyce.McIntosh@Sun.COM 	DWORD status = ERROR_SUCCESS;
492*12890SJoyce.McIntosh@Sun.COM 
493*12890SJoyce.McIntosh@Sun.COM 	if (param->BufCount == 0)
494*12890SJoyce.McIntosh@Sun.COM 		param->status = ERROR_INSUFFICIENT_BUFFER;
495*12890SJoyce.McIntosh@Sun.COM 	else
496*12890SJoyce.McIntosh@Sun.COM 		param->status = status;
497*12890SJoyce.McIntosh@Sun.COM 	param->needed = 0;
498*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
499*12890SJoyce.McIntosh@Sun.COM }
500*12890SJoyce.McIntosh@Sun.COM 
501*12890SJoyce.McIntosh@Sun.COM 
502*12890SJoyce.McIntosh@Sun.COM /*ARGSUSED*/
503*12890SJoyce.McIntosh@Sun.COM static int
504*12890SJoyce.McIntosh@Sun.COM spoolss_s_ScheduleJob(void *arg, ndr_xa_t *mxa)
505*12890SJoyce.McIntosh@Sun.COM {
506*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_ScheduleJob *param = arg;
507*12890SJoyce.McIntosh@Sun.COM 	DWORD status = SPOOLSS_JOB_NOT_ISSUED;
508*12890SJoyce.McIntosh@Sun.COM 
509*12890SJoyce.McIntosh@Sun.COM 	param->status = status;
510*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
511*12890SJoyce.McIntosh@Sun.COM }
512*12890SJoyce.McIntosh@Sun.COM 
513*12890SJoyce.McIntosh@Sun.COM /*ARGSUSED*/
514*12890SJoyce.McIntosh@Sun.COM static int
515*12890SJoyce.McIntosh@Sun.COM spoolss_s_AddJob(void *arg, ndr_xa_t *mxa)
516*12890SJoyce.McIntosh@Sun.COM {
517*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_AddJob *param = arg;
518*12890SJoyce.McIntosh@Sun.COM 
519*12890SJoyce.McIntosh@Sun.COM 	param->status = ERROR_SUCCESS;
520*12890SJoyce.McIntosh@Sun.COM 	param->needed = 0;
521*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
522*12890SJoyce.McIntosh@Sun.COM }
523*12890SJoyce.McIntosh@Sun.COM 
524*12890SJoyce.McIntosh@Sun.COM /*ARGSUSED*/
525*12890SJoyce.McIntosh@Sun.COM static int
526*12890SJoyce.McIntosh@Sun.COM spoolss_s_rfnpcnex(void *arg, ndr_xa_t *mxa)
527*12890SJoyce.McIntosh@Sun.COM {
528*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_RFNPCNEX *param = arg;
529*12890SJoyce.McIntosh@Sun.COM 
530*12890SJoyce.McIntosh@Sun.COM 	param->ppinfo = 0;
531*12890SJoyce.McIntosh@Sun.COM 	param->status = ERROR_SUCCESS;
532*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
533*12890SJoyce.McIntosh@Sun.COM }
534*12890SJoyce.McIntosh@Sun.COM 
535*12890SJoyce.McIntosh@Sun.COM /*
536*12890SJoyce.McIntosh@Sun.COM  * Use the RPC context handle to find the fd and write the document content.
537*12890SJoyce.McIntosh@Sun.COM  */
538*12890SJoyce.McIntosh@Sun.COM static int
539*12890SJoyce.McIntosh@Sun.COM spoolss_s_WritePrinter(void *arg, ndr_xa_t *mxa)
540*12890SJoyce.McIntosh@Sun.COM {
541*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_WritePrinter *param = arg;
542*12890SJoyce.McIntosh@Sun.COM 	int written = 0;
543*12890SJoyce.McIntosh@Sun.COM 	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
544*12890SJoyce.McIntosh@Sun.COM 	int spfd;
545*12890SJoyce.McIntosh@Sun.COM 
546*12890SJoyce.McIntosh@Sun.COM 	if (ndr_hdlookup(mxa, id) == NULL) {
547*12890SJoyce.McIntosh@Sun.COM 		param->written = 0;
548*12890SJoyce.McIntosh@Sun.COM 		param->status = ERROR_INVALID_HANDLE;
549*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_ERR, "spoolss_s_WritePrinter: invalid handle");
550*12890SJoyce.McIntosh@Sun.COM 		return (NDR_DRC_OK);
551*12890SJoyce.McIntosh@Sun.COM 	}
552*12890SJoyce.McIntosh@Sun.COM 
553*12890SJoyce.McIntosh@Sun.COM 	if ((spfd = spoolss_find_fd(id)) < 0) {
554*12890SJoyce.McIntosh@Sun.COM 		param->written = 0;
555*12890SJoyce.McIntosh@Sun.COM 		param->status = ERROR_INVALID_HANDLE;
556*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_ERR, "spoolss_s_WritePrinter: cannot find fd");
557*12890SJoyce.McIntosh@Sun.COM 		return (NDR_DRC_OK);
558*12890SJoyce.McIntosh@Sun.COM 	}
559*12890SJoyce.McIntosh@Sun.COM 
560*12890SJoyce.McIntosh@Sun.COM 	written = write(spfd, param->pBuf, param->BufCount);
561*12890SJoyce.McIntosh@Sun.COM 	if (written < param->BufCount) {
562*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_ERR, "spoolss_s_WritePrinter: write failed");
563*12890SJoyce.McIntosh@Sun.COM 		param->written = 0;
564*12890SJoyce.McIntosh@Sun.COM 		param->status = ERROR_CANTWRITE;
565*12890SJoyce.McIntosh@Sun.COM 		return (NDR_DRC_OK);
566*12890SJoyce.McIntosh@Sun.COM 	}
567*12890SJoyce.McIntosh@Sun.COM 
568*12890SJoyce.McIntosh@Sun.COM 	param->written = written;
569*12890SJoyce.McIntosh@Sun.COM 	param->status = ERROR_SUCCESS;
570*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
571*12890SJoyce.McIntosh@Sun.COM }
572*12890SJoyce.McIntosh@Sun.COM 
573*12890SJoyce.McIntosh@Sun.COM /*
574*12890SJoyce.McIntosh@Sun.COM  * All versions of windows use this function to print
575*12890SJoyce.McIntosh@Sun.COM  * spool files via the cups interface
576*12890SJoyce.McIntosh@Sun.COM  */
577*12890SJoyce.McIntosh@Sun.COM 
578*12890SJoyce.McIntosh@Sun.COM void
579*12890SJoyce.McIntosh@Sun.COM spoolss_copy_spool_file(smb_inaddr_t *ipaddr, char *username,
580*12890SJoyce.McIntosh@Sun.COM     char *path, char *doc_name)
581*12890SJoyce.McIntosh@Sun.COM {
582*12890SJoyce.McIntosh@Sun.COM 	smb_cups_ops_t	*cups;
583*12890SJoyce.McIntosh@Sun.COM 	int		ret = 1;		/* Return value */
584*12890SJoyce.McIntosh@Sun.COM 	http_t		*http = NULL;		/* HTTP connection to server */
585*12890SJoyce.McIntosh@Sun.COM 	ipp_t		*request = NULL;	/* IPP Request */
586*12890SJoyce.McIntosh@Sun.COM 	ipp_t		*response = NULL;	/* IPP Response */
587*12890SJoyce.McIntosh@Sun.COM 	cups_lang_t	*language = NULL;	/* Default language */
588*12890SJoyce.McIntosh@Sun.COM 	char		uri[HTTP_MAX_URI];	/* printer-uri attribute */
589*12890SJoyce.McIntosh@Sun.COM 	char		new_jobname[SPOOLSS_PJOBLEN];
590*12890SJoyce.McIntosh@Sun.COM 	struct		spoolss_printjob pjob;
591*12890SJoyce.McIntosh@Sun.COM 	char 		clientname[INET6_ADDRSTRLEN];
592*12890SJoyce.McIntosh@Sun.COM 	struct stat 	sbuf;
593*12890SJoyce.McIntosh@Sun.COM 
594*12890SJoyce.McIntosh@Sun.COM 	if (stat(path, &sbuf)) {
595*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_INFO, "spoolss_copy_spool_file: %s: %s",
596*12890SJoyce.McIntosh@Sun.COM 		    path, strerror(errno));
597*12890SJoyce.McIntosh@Sun.COM 		return;
598*12890SJoyce.McIntosh@Sun.COM 	}
599*12890SJoyce.McIntosh@Sun.COM 
600*12890SJoyce.McIntosh@Sun.COM 	/*
601*12890SJoyce.McIntosh@Sun.COM 	 * Remove zero size files and return; these were inadvertantly
602*12890SJoyce.McIntosh@Sun.COM 	 * created by XP or 2000.
603*12890SJoyce.McIntosh@Sun.COM 	 */
604*12890SJoyce.McIntosh@Sun.COM 	if (sbuf.st_blocks == 0) {
605*12890SJoyce.McIntosh@Sun.COM 		if (remove(path))
606*12890SJoyce.McIntosh@Sun.COM 			syslog(LOG_INFO,
607*12890SJoyce.McIntosh@Sun.COM 			    "spoolss_copy_spool_file: cannot remove %s", path);
608*12890SJoyce.McIntosh@Sun.COM 		return;
609*12890SJoyce.McIntosh@Sun.COM 	}
610*12890SJoyce.McIntosh@Sun.COM 
611*12890SJoyce.McIntosh@Sun.COM 	if ((cups = spoolss_cups_ops()) == NULL)
612*12890SJoyce.McIntosh@Sun.COM 		return;
613*12890SJoyce.McIntosh@Sun.COM 
614*12890SJoyce.McIntosh@Sun.COM 	if ((http = cups->httpConnect("localhost", 631)) == NULL) {
615*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_INFO, "spoolss_copy_spool_file: cupsd not running");
616*12890SJoyce.McIntosh@Sun.COM 		return;
617*12890SJoyce.McIntosh@Sun.COM 	}
618*12890SJoyce.McIntosh@Sun.COM 
619*12890SJoyce.McIntosh@Sun.COM 	if ((request = cups->ippNew()) == NULL) {
620*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_INFO, "spoolss_copy_spool_file: ipp not running");
621*12890SJoyce.McIntosh@Sun.COM 		return;
622*12890SJoyce.McIntosh@Sun.COM 	}
623*12890SJoyce.McIntosh@Sun.COM 	request->request.op.operation_id = IPP_PRINT_JOB;
624*12890SJoyce.McIntosh@Sun.COM 	request->request.op.request_id = 1;
625*12890SJoyce.McIntosh@Sun.COM 	language = cups->cupsLangDefault();
626*12890SJoyce.McIntosh@Sun.COM 
627*12890SJoyce.McIntosh@Sun.COM 	cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
628*12890SJoyce.McIntosh@Sun.COM 	    "attributes-charset", NULL, cups->cupsLangEncoding(language));
629*12890SJoyce.McIntosh@Sun.COM 
630*12890SJoyce.McIntosh@Sun.COM 	cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
631*12890SJoyce.McIntosh@Sun.COM 	    "attributes-natural-language", NULL, language->language);
632*12890SJoyce.McIntosh@Sun.COM 
633*12890SJoyce.McIntosh@Sun.COM 	(void) snprintf(uri, sizeof (uri), "ipp://localhost/printers/%s",
634*12890SJoyce.McIntosh@Sun.COM 	    SPOOLSS_PRINTER);
635*12890SJoyce.McIntosh@Sun.COM 	pjob.pj_pid = pthread_self();
636*12890SJoyce.McIntosh@Sun.COM 	pjob.pj_sysjob = 10;
637*12890SJoyce.McIntosh@Sun.COM 	(void) strlcpy(pjob.pj_filename, path, SPOOLSS_PJOBLEN);
638*12890SJoyce.McIntosh@Sun.COM 	pjob.pj_start_time = time(NULL);
639*12890SJoyce.McIntosh@Sun.COM 	pjob.pj_status = 2;
640*12890SJoyce.McIntosh@Sun.COM 	pjob.pj_size = sbuf.st_blocks * 512;
641*12890SJoyce.McIntosh@Sun.COM 	pjob.pj_page_count = 1;
642*12890SJoyce.McIntosh@Sun.COM 	pjob.pj_isspooled = B_TRUE;
643*12890SJoyce.McIntosh@Sun.COM 	pjob.pj_jobnum = spoolss_jobnum;
644*12890SJoyce.McIntosh@Sun.COM 
645*12890SJoyce.McIntosh@Sun.COM 	(void) strlcpy(pjob.pj_jobname, doc_name, SPOOLSS_PJOBLEN);
646*12890SJoyce.McIntosh@Sun.COM 	(void) strlcpy(pjob.pj_username, username, SPOOLSS_PJOBLEN);
647*12890SJoyce.McIntosh@Sun.COM 	(void) strlcpy(pjob.pj_queuename, SPOOLSS_CUPS_SPOOL_DIR,
648*12890SJoyce.McIntosh@Sun.COM 	    SPOOLSS_PJOBLEN);
649*12890SJoyce.McIntosh@Sun.COM 	cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
650*12890SJoyce.McIntosh@Sun.COM 	    "printer-uri", NULL, uri);
651*12890SJoyce.McIntosh@Sun.COM 
652*12890SJoyce.McIntosh@Sun.COM 	cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
653*12890SJoyce.McIntosh@Sun.COM 	    "requesting-user-name", NULL, pjob.pj_username);
654*12890SJoyce.McIntosh@Sun.COM 
655*12890SJoyce.McIntosh@Sun.COM 	if (smb_inet_ntop(ipaddr, clientname,
656*12890SJoyce.McIntosh@Sun.COM 	    SMB_IPSTRLEN(ipaddr->a_family)) == NULL) {
657*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_INFO, "spoolss_copy_spool_file: %s: unknown client",
658*12890SJoyce.McIntosh@Sun.COM 		    clientname);
659*12890SJoyce.McIntosh@Sun.COM 		goto out;
660*12890SJoyce.McIntosh@Sun.COM 	}
661*12890SJoyce.McIntosh@Sun.COM 	cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
662*12890SJoyce.McIntosh@Sun.COM 	    "job-originating-host-name", NULL, clientname);
663*12890SJoyce.McIntosh@Sun.COM 
664*12890SJoyce.McIntosh@Sun.COM 	(void) snprintf(new_jobname, SPOOLSS_PJOBLEN, "%s%d",
665*12890SJoyce.McIntosh@Sun.COM 	    SPOOLSS_FN_PREFIX, pjob.pj_jobnum);
666*12890SJoyce.McIntosh@Sun.COM 	cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
667*12890SJoyce.McIntosh@Sun.COM 	    "job-name", NULL, new_jobname);
668*12890SJoyce.McIntosh@Sun.COM 
669*12890SJoyce.McIntosh@Sun.COM 	(void) snprintf(uri, sizeof (uri) - 1, "/printers/%s", SPOOLSS_PRINTER);
670*12890SJoyce.McIntosh@Sun.COM 
671*12890SJoyce.McIntosh@Sun.COM 	response = cups->cupsDoFileRequest(http, request, uri,
672*12890SJoyce.McIntosh@Sun.COM 	    pjob.pj_filename);
673*12890SJoyce.McIntosh@Sun.COM 	if (response != NULL) {
674*12890SJoyce.McIntosh@Sun.COM 		if (response->request.status.status_code >= IPP_OK_CONFLICT) {
675*12890SJoyce.McIntosh@Sun.COM 			syslog(LOG_ERR,
676*12890SJoyce.McIntosh@Sun.COM 			    "spoolss_copy_spool_file: file print %s: %s",
677*12890SJoyce.McIntosh@Sun.COM 			    SPOOLSS_PRINTER,
678*12890SJoyce.McIntosh@Sun.COM 			    cups->ippErrorString(cups->cupsLastError()));
679*12890SJoyce.McIntosh@Sun.COM 		} else {
680*12890SJoyce.McIntosh@Sun.COM 			atomic_inc_32(&spoolss_jobnum);
681*12890SJoyce.McIntosh@Sun.COM 			ret = 0;
682*12890SJoyce.McIntosh@Sun.COM 		}
683*12890SJoyce.McIntosh@Sun.COM 	} else {
684*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_ERR,
685*12890SJoyce.McIntosh@Sun.COM 		    "spoolss_copy_spool_file: unable to print file to %s",
686*12890SJoyce.McIntosh@Sun.COM 		    cups->ippErrorString(cups->cupsLastError()));
687*12890SJoyce.McIntosh@Sun.COM 	}
688*12890SJoyce.McIntosh@Sun.COM 
689*12890SJoyce.McIntosh@Sun.COM 	if (ret == 0)
690*12890SJoyce.McIntosh@Sun.COM 		(void) unlink(pjob.pj_filename);
691*12890SJoyce.McIntosh@Sun.COM 
692*12890SJoyce.McIntosh@Sun.COM out:
693*12890SJoyce.McIntosh@Sun.COM 	if (response)
694*12890SJoyce.McIntosh@Sun.COM 		cups->ippDelete(response);
695*12890SJoyce.McIntosh@Sun.COM 
696*12890SJoyce.McIntosh@Sun.COM 	if (language)
697*12890SJoyce.McIntosh@Sun.COM 		cups->cupsLangFree(language);
698*12890SJoyce.McIntosh@Sun.COM 
699*12890SJoyce.McIntosh@Sun.COM 	if (http)
700*12890SJoyce.McIntosh@Sun.COM 		cups->httpClose(http);
701*12890SJoyce.McIntosh@Sun.COM }
702*12890SJoyce.McIntosh@Sun.COM 
703*12890SJoyce.McIntosh@Sun.COM static int
704*12890SJoyce.McIntosh@Sun.COM spoolss_s_GetPrinterData(void *arg, ndr_xa_t *mxa)
705*12890SJoyce.McIntosh@Sun.COM {
706*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_GetPrinterData *param = arg;
707*12890SJoyce.McIntosh@Sun.COM 	DWORD status = ERROR_SUCCESS;
708*12890SJoyce.McIntosh@Sun.COM 
709*12890SJoyce.McIntosh@Sun.COM 	if (param->Size > 0) {
710*12890SJoyce.McIntosh@Sun.COM 		param->Buf = NDR_NEWN(mxa, char, param->Size);
711*12890SJoyce.McIntosh@Sun.COM 		bzero(param->Buf, param->Size);
712*12890SJoyce.McIntosh@Sun.COM 	} else {
713*12890SJoyce.McIntosh@Sun.COM 		param->Buf = NDR_NEWN(mxa, uint32_t, 1);
714*12890SJoyce.McIntosh@Sun.COM 		param->Buf[0] = 1;
715*12890SJoyce.McIntosh@Sun.COM 		param->Buf[1] = 1;
716*12890SJoyce.McIntosh@Sun.COM 		param->Buf[2] = 2;
717*12890SJoyce.McIntosh@Sun.COM 		param->Buf[3] = 2;
718*12890SJoyce.McIntosh@Sun.COM 	}
719*12890SJoyce.McIntosh@Sun.COM 
720*12890SJoyce.McIntosh@Sun.COM 	/*
721*12890SJoyce.McIntosh@Sun.COM 	 * Increment pType if the Printer Data changes
722*12890SJoyce.McIntosh@Sun.COM 	 * as specified by Microsoft documentation
723*12890SJoyce.McIntosh@Sun.COM 	 */
724*12890SJoyce.McIntosh@Sun.COM 	param->pType = 1;
725*12890SJoyce.McIntosh@Sun.COM 	if (strcasecmp((char *)param->pValueName, "ChangeId") == 0) {
726*12890SJoyce.McIntosh@Sun.COM 		param->pType = 4;
727*12890SJoyce.McIntosh@Sun.COM 		param->Buf[3] = 0x00;
728*12890SJoyce.McIntosh@Sun.COM 		param->Buf[2] = 0x50;
729*12890SJoyce.McIntosh@Sun.COM 		param->Buf[1] = 0xac;
730*12890SJoyce.McIntosh@Sun.COM 		param->Buf[0] = 0xf2;
731*12890SJoyce.McIntosh@Sun.COM 	} else if (strcasecmp((char *)param->pValueName,
732*12890SJoyce.McIntosh@Sun.COM 	    "UISingleJobStatusString") == 0) {
733*12890SJoyce.McIntosh@Sun.COM 		status = ERROR_FILE_NOT_FOUND;
734*12890SJoyce.McIntosh@Sun.COM 	} else if (strcasecmp((char *)param->pValueName,
735*12890SJoyce.McIntosh@Sun.COM 	    "W3SvcInstalled") == 0) {
736*12890SJoyce.McIntosh@Sun.COM 		status = ERROR_FILE_NOT_FOUND;
737*12890SJoyce.McIntosh@Sun.COM 	} else if (strcasecmp((char *)param->pValueName,
738*12890SJoyce.McIntosh@Sun.COM 	    "PrintProcCaps_NT EMF 1.008") == 0) {
739*12890SJoyce.McIntosh@Sun.COM 		status = ERROR_FILE_NOT_FOUND;
740*12890SJoyce.McIntosh@Sun.COM 	} else if (strcasecmp((char *)param->pValueName, "OSVersion") == 0) {
741*12890SJoyce.McIntosh@Sun.COM 		param->Buf = NDR_NEWN(mxa, char, param->Size);
742*12890SJoyce.McIntosh@Sun.COM 		bzero(param->Buf, param->Size);
743*12890SJoyce.McIntosh@Sun.COM 		param->Buf[0] = 0x14;
744*12890SJoyce.McIntosh@Sun.COM 		param->Buf[1] = 0x01;
745*12890SJoyce.McIntosh@Sun.COM 		param->Buf[4] = 0x05;
746*12890SJoyce.McIntosh@Sun.COM 		param->Buf[12] = 0x93;
747*12890SJoyce.McIntosh@Sun.COM 		param->Buf[13] = 0x08;
748*12890SJoyce.McIntosh@Sun.COM 	}
749*12890SJoyce.McIntosh@Sun.COM 	param->status = status;
750*12890SJoyce.McIntosh@Sun.COM 	param->Needed = param->Size;
751*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
752*12890SJoyce.McIntosh@Sun.COM }
753*12890SJoyce.McIntosh@Sun.COM 
754*12890SJoyce.McIntosh@Sun.COM smb_cups_ops_t *
755*12890SJoyce.McIntosh@Sun.COM spoolss_cups_ops(void)
756*12890SJoyce.McIntosh@Sun.COM {
757*12890SJoyce.McIntosh@Sun.COM 	if (spoolss_cups_init() != 0)
758*12890SJoyce.McIntosh@Sun.COM 		return (NULL);
759*12890SJoyce.McIntosh@Sun.COM 
760*12890SJoyce.McIntosh@Sun.COM 	return (&smb_cups);
761*12890SJoyce.McIntosh@Sun.COM }
762*12890SJoyce.McIntosh@Sun.COM 
763*12890SJoyce.McIntosh@Sun.COM static int
764*12890SJoyce.McIntosh@Sun.COM spoolss_cups_init(void)
765*12890SJoyce.McIntosh@Sun.COM {
766*12890SJoyce.McIntosh@Sun.COM 	(void) mutex_lock(&spoolss_cups_mutex);
767*12890SJoyce.McIntosh@Sun.COM 
768*12890SJoyce.McIntosh@Sun.COM 	if (smb_cups.cups_hdl != NULL) {
769*12890SJoyce.McIntosh@Sun.COM 		(void) mutex_unlock(&spoolss_cups_mutex);
770*12890SJoyce.McIntosh@Sun.COM 		return (0);
771*12890SJoyce.McIntosh@Sun.COM 	}
772*12890SJoyce.McIntosh@Sun.COM 
773*12890SJoyce.McIntosh@Sun.COM 	if ((smb_cups.cups_hdl = dlopen("libcups.so.2", RTLD_NOW)) == NULL) {
774*12890SJoyce.McIntosh@Sun.COM 		(void) mutex_unlock(&spoolss_cups_mutex);
775*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_DEBUG, "spoolss_cups_init: cannot open libcups");
776*12890SJoyce.McIntosh@Sun.COM 		return (ENOENT);
777*12890SJoyce.McIntosh@Sun.COM 	}
778*12890SJoyce.McIntosh@Sun.COM 
779*12890SJoyce.McIntosh@Sun.COM 	smb_cups.cupsLangDefault =
780*12890SJoyce.McIntosh@Sun.COM 	    (cups_lang_t *(*)())dlsym(smb_cups.cups_hdl, "cupsLangDefault");
781*12890SJoyce.McIntosh@Sun.COM 	smb_cups.cupsLangEncoding = (const char *(*)(cups_lang_t *))
782*12890SJoyce.McIntosh@Sun.COM 	    dlsym(smb_cups.cups_hdl, "cupsLangEncoding");
783*12890SJoyce.McIntosh@Sun.COM 	smb_cups.cupsDoFileRequest =
784*12890SJoyce.McIntosh@Sun.COM 	    (ipp_t *(*)(http_t *, ipp_t *, const char *, const char *))
785*12890SJoyce.McIntosh@Sun.COM 	    dlsym(smb_cups.cups_hdl, "cupsDoFileRequest");
786*12890SJoyce.McIntosh@Sun.COM 	smb_cups.cupsLastError = (ipp_status_t (*)())
787*12890SJoyce.McIntosh@Sun.COM 	    dlsym(smb_cups.cups_hdl, "cupsLastError");
788*12890SJoyce.McIntosh@Sun.COM 	smb_cups.cupsLangFree = (void (*)(cups_lang_t *))
789*12890SJoyce.McIntosh@Sun.COM 	    dlsym(smb_cups.cups_hdl, "cupsLangFree");
790*12890SJoyce.McIntosh@Sun.COM 	smb_cups.cupsGetDests = (int (*)(cups_dest_t **))
791*12890SJoyce.McIntosh@Sun.COM 	    dlsym(smb_cups.cups_hdl, "cupsGetDests");
792*12890SJoyce.McIntosh@Sun.COM 	smb_cups.cupsFreeDests = (void (*)(int, cups_dest_t *))
793*12890SJoyce.McIntosh@Sun.COM 	    dlsym(smb_cups.cups_hdl, "cupsFreeDests");
794*12890SJoyce.McIntosh@Sun.COM 
795*12890SJoyce.McIntosh@Sun.COM 	smb_cups.httpClose = (void (*)(http_t *))
796*12890SJoyce.McIntosh@Sun.COM 	    dlsym(smb_cups.cups_hdl, "httpClose");
797*12890SJoyce.McIntosh@Sun.COM 	smb_cups.httpConnect = (http_t *(*)(const char *, int))
798*12890SJoyce.McIntosh@Sun.COM 	    dlsym(smb_cups.cups_hdl, "httpConnect");
799*12890SJoyce.McIntosh@Sun.COM 
800*12890SJoyce.McIntosh@Sun.COM 	smb_cups.ippNew = (ipp_t *(*)())dlsym(smb_cups.cups_hdl, "ippNew");
801*12890SJoyce.McIntosh@Sun.COM 	smb_cups.ippDelete = (void (*)())dlsym(smb_cups.cups_hdl, "ippDelete");
802*12890SJoyce.McIntosh@Sun.COM 	smb_cups.ippErrorString = (char *(*)())
803*12890SJoyce.McIntosh@Sun.COM 	    dlsym(smb_cups.cups_hdl, "ippErrorString");
804*12890SJoyce.McIntosh@Sun.COM 	smb_cups.ippAddString = (ipp_attribute_t *(*)())
805*12890SJoyce.McIntosh@Sun.COM 	    dlsym(smb_cups.cups_hdl, "ippAddString");
806*12890SJoyce.McIntosh@Sun.COM 
807*12890SJoyce.McIntosh@Sun.COM 	if (smb_cups.cupsLangDefault == NULL ||
808*12890SJoyce.McIntosh@Sun.COM 	    smb_cups.cupsLangEncoding == NULL ||
809*12890SJoyce.McIntosh@Sun.COM 	    smb_cups.cupsDoFileRequest == NULL ||
810*12890SJoyce.McIntosh@Sun.COM 	    smb_cups.cupsLastError == NULL ||
811*12890SJoyce.McIntosh@Sun.COM 	    smb_cups.cupsLangFree == NULL ||
812*12890SJoyce.McIntosh@Sun.COM 	    smb_cups.cupsGetDests == NULL ||
813*12890SJoyce.McIntosh@Sun.COM 	    smb_cups.cupsFreeDests == NULL ||
814*12890SJoyce.McIntosh@Sun.COM 	    smb_cups.ippNew == NULL ||
815*12890SJoyce.McIntosh@Sun.COM 	    smb_cups.httpClose == NULL ||
816*12890SJoyce.McIntosh@Sun.COM 	    smb_cups.httpConnect == NULL ||
817*12890SJoyce.McIntosh@Sun.COM 	    smb_cups.ippDelete == NULL ||
818*12890SJoyce.McIntosh@Sun.COM 	    smb_cups.ippErrorString == NULL ||
819*12890SJoyce.McIntosh@Sun.COM 	    smb_cups.ippAddString == NULL) {
820*12890SJoyce.McIntosh@Sun.COM 		smb_dlclose(smb_cups.cups_hdl);
821*12890SJoyce.McIntosh@Sun.COM 		smb_cups.cups_hdl = NULL;
822*12890SJoyce.McIntosh@Sun.COM 		(void) mutex_unlock(&spoolss_cups_mutex);
823*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_DEBUG, "spoolss_cups_init: cannot load libcups");
824*12890SJoyce.McIntosh@Sun.COM 		return (ENOENT);
825*12890SJoyce.McIntosh@Sun.COM 	}
826*12890SJoyce.McIntosh@Sun.COM 
827*12890SJoyce.McIntosh@Sun.COM 	(void) mutex_unlock(&spoolss_cups_mutex);
828*12890SJoyce.McIntosh@Sun.COM 	return (0);
829*12890SJoyce.McIntosh@Sun.COM }
830*12890SJoyce.McIntosh@Sun.COM 
831*12890SJoyce.McIntosh@Sun.COM static void
832*12890SJoyce.McIntosh@Sun.COM spoolss_cups_fini(void)
833*12890SJoyce.McIntosh@Sun.COM {
834*12890SJoyce.McIntosh@Sun.COM 	(void) mutex_lock(&spoolss_cups_mutex);
835*12890SJoyce.McIntosh@Sun.COM 
836*12890SJoyce.McIntosh@Sun.COM 	if (smb_cups.cups_hdl != NULL) {
837*12890SJoyce.McIntosh@Sun.COM 		smb_dlclose(smb_cups.cups_hdl);
838*12890SJoyce.McIntosh@Sun.COM 		smb_cups.cups_hdl = NULL;
839*12890SJoyce.McIntosh@Sun.COM 	}
840*12890SJoyce.McIntosh@Sun.COM 
841*12890SJoyce.McIntosh@Sun.COM 	(void) mutex_unlock(&spoolss_cups_mutex);
842*12890SJoyce.McIntosh@Sun.COM }
843*12890SJoyce.McIntosh@Sun.COM 
844*12890SJoyce.McIntosh@Sun.COM void
845*12890SJoyce.McIntosh@Sun.COM smb_rpc_off(char *dst, char *src, uint32_t *offset, uint32_t *outoffset)
846*12890SJoyce.McIntosh@Sun.COM {
847*12890SJoyce.McIntosh@Sun.COM 	int nwchars;
848*12890SJoyce.McIntosh@Sun.COM 	int bytes;
849*12890SJoyce.McIntosh@Sun.COM 
850*12890SJoyce.McIntosh@Sun.COM 	bytes = smb_wcequiv_strlen(src) + 2;
851*12890SJoyce.McIntosh@Sun.COM 	nwchars = strlen(src) + 1;
852*12890SJoyce.McIntosh@Sun.COM 	*offset -= bytes;
853*12890SJoyce.McIntosh@Sun.COM 	*outoffset = *offset;
854*12890SJoyce.McIntosh@Sun.COM 	/*LINTED E_BAD_PTR_CAST_ALIGN*/
855*12890SJoyce.McIntosh@Sun.COM 	(void) smb_mbstowcs(((smb_wchar_t *)(dst + *offset)), src, nwchars);
856*12890SJoyce.McIntosh@Sun.COM }
857*12890SJoyce.McIntosh@Sun.COM 
858*12890SJoyce.McIntosh@Sun.COM int
859*12890SJoyce.McIntosh@Sun.COM spoolss_s_GetPrinter(void *arg, ndr_xa_t *mxa)
860*12890SJoyce.McIntosh@Sun.COM {
861*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_GetPrinter *param = arg;
862*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_GetPrinter0 *pinfo0;
863*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_GetPrinter1 *pinfo1;
864*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_GetPrinter2 *pinfo2;
865*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_DeviceMode *devmode2;
866*12890SJoyce.McIntosh@Sun.COM 	DWORD status = ERROR_SUCCESS;
867*12890SJoyce.McIntosh@Sun.COM 	char *wname;
868*12890SJoyce.McIntosh@Sun.COM 	uint32_t offset;
869*12890SJoyce.McIntosh@Sun.COM 	smb_inaddr_t ipaddr;
870*12890SJoyce.McIntosh@Sun.COM 	struct hostent *h;
871*12890SJoyce.McIntosh@Sun.COM 	char hname[MAXHOSTNAMELEN];
872*12890SJoyce.McIntosh@Sun.COM 	char soutbuf[MAXNAMELEN];
873*12890SJoyce.McIntosh@Sun.COM 	char poutbuf[MAXNAMELEN];
874*12890SJoyce.McIntosh@Sun.COM 	char ipstr[INET6_ADDRSTRLEN];
875*12890SJoyce.McIntosh@Sun.COM 	int error;
876*12890SJoyce.McIntosh@Sun.COM 	uint8_t *tmpbuf;
877*12890SJoyce.McIntosh@Sun.COM 
878*12890SJoyce.McIntosh@Sun.COM 	if (param->BufCount == 0) {
879*12890SJoyce.McIntosh@Sun.COM 		status = ERROR_INSUFFICIENT_BUFFER;
880*12890SJoyce.McIntosh@Sun.COM 		goto error_out;
881*12890SJoyce.McIntosh@Sun.COM 	}
882*12890SJoyce.McIntosh@Sun.COM 	param->Buf = NDR_NEWN(mxa, char, param->BufCount);
883*12890SJoyce.McIntosh@Sun.COM 	bzero(param->Buf, param->BufCount);
884*12890SJoyce.McIntosh@Sun.COM 	switch (param->switch_value) {
885*12890SJoyce.McIntosh@Sun.COM 	case 0:
886*12890SJoyce.McIntosh@Sun.COM 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
887*12890SJoyce.McIntosh@Sun.COM 		pinfo0 = (struct spoolss_GetPrinter0 *)param->Buf;
888*12890SJoyce.McIntosh@Sun.COM 		break;
889*12890SJoyce.McIntosh@Sun.COM 	case 1:
890*12890SJoyce.McIntosh@Sun.COM 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
891*12890SJoyce.McIntosh@Sun.COM 		pinfo1 = (struct spoolss_GetPrinter1 *)param->Buf;
892*12890SJoyce.McIntosh@Sun.COM 		break;
893*12890SJoyce.McIntosh@Sun.COM 	case 2:
894*12890SJoyce.McIntosh@Sun.COM 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
895*12890SJoyce.McIntosh@Sun.COM 		pinfo2 = (struct spoolss_GetPrinter2 *)param->Buf;
896*12890SJoyce.McIntosh@Sun.COM 		break;
897*12890SJoyce.McIntosh@Sun.COM 	}
898*12890SJoyce.McIntosh@Sun.COM 	wname = (char *)param->Buf;
899*12890SJoyce.McIntosh@Sun.COM 
900*12890SJoyce.McIntosh@Sun.COM 	status = ERROR_INVALID_PARAMETER;
901*12890SJoyce.McIntosh@Sun.COM 	if (smb_gethostname(hname, MAXHOSTNAMELEN, 0) != 0) {
902*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_NOTICE, "spoolss_s_GetPrinter: gethostname failed");
903*12890SJoyce.McIntosh@Sun.COM 		goto error_out;
904*12890SJoyce.McIntosh@Sun.COM 	}
905*12890SJoyce.McIntosh@Sun.COM 	if ((h = smb_gethostbyname(hname, &error)) == NULL) {
906*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_NOTICE,
907*12890SJoyce.McIntosh@Sun.COM 		    "spoolss_s_GetPrinter: gethostbyname failed");
908*12890SJoyce.McIntosh@Sun.COM 		goto error_out;
909*12890SJoyce.McIntosh@Sun.COM 	}
910*12890SJoyce.McIntosh@Sun.COM 	bcopy(h->h_addr, &ipaddr, h->h_length);
911*12890SJoyce.McIntosh@Sun.COM 	ipaddr.a_family = h->h_addrtype;
912*12890SJoyce.McIntosh@Sun.COM 	freehostent(h);
913*12890SJoyce.McIntosh@Sun.COM 	if (smb_inet_ntop(&ipaddr, ipstr, SMB_IPSTRLEN(ipaddr.a_family))
914*12890SJoyce.McIntosh@Sun.COM 	    == NULL) {
915*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_NOTICE, "spoolss_s_GetPrinter: inet_ntop failed");
916*12890SJoyce.McIntosh@Sun.COM 		goto error_out;
917*12890SJoyce.McIntosh@Sun.COM 	}
918*12890SJoyce.McIntosh@Sun.COM 	status = ERROR_SUCCESS;
919*12890SJoyce.McIntosh@Sun.COM 	(void) snprintf(poutbuf, MAXNAMELEN, "\\\\%s\\%s",
920*12890SJoyce.McIntosh@Sun.COM 	    ipstr, SPOOLSS_PRINTER);
921*12890SJoyce.McIntosh@Sun.COM 	(void) snprintf(soutbuf, MAXNAMELEN, "\\\\%s", ipstr);
922*12890SJoyce.McIntosh@Sun.COM 	param->needed = 0;
923*12890SJoyce.McIntosh@Sun.COM 	switch (param->switch_value) {
924*12890SJoyce.McIntosh@Sun.COM 	case 0:
925*12890SJoyce.McIntosh@Sun.COM 		offset = 460;
926*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, "", &offset, &pinfo0->servername);
927*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, poutbuf, &offset, &pinfo0->printername);
928*12890SJoyce.McIntosh@Sun.COM 		pinfo0->cjobs = 0;
929*12890SJoyce.McIntosh@Sun.COM 		pinfo0->total_jobs = 6;
930*12890SJoyce.McIntosh@Sun.COM 		pinfo0->total_bytes = 1040771;
931*12890SJoyce.McIntosh@Sun.COM 		pinfo0->time0 = 0;
932*12890SJoyce.McIntosh@Sun.COM 		pinfo0->time1 = 0;
933*12890SJoyce.McIntosh@Sun.COM 		pinfo0->time2 = 3;
934*12890SJoyce.McIntosh@Sun.COM 		pinfo0->time3 = 0;
935*12890SJoyce.McIntosh@Sun.COM 		pinfo0->global_counter = 2162710;
936*12890SJoyce.McIntosh@Sun.COM 		pinfo0->total_pages = 21495865;
937*12890SJoyce.McIntosh@Sun.COM 		pinfo0->version = 10;
938*12890SJoyce.McIntosh@Sun.COM 		pinfo0->session_counter = 1;
939*12890SJoyce.McIntosh@Sun.COM 		pinfo0->job_error = 0x6;
940*12890SJoyce.McIntosh@Sun.COM 		pinfo0->change_id  = 0x1;
941*12890SJoyce.McIntosh@Sun.COM 		pinfo0->status = 0;
942*12890SJoyce.McIntosh@Sun.COM 		pinfo0->c_setprinter = 0;
943*12890SJoyce.McIntosh@Sun.COM 		break;
944*12890SJoyce.McIntosh@Sun.COM 	case 1:
945*12890SJoyce.McIntosh@Sun.COM 		pinfo1->flags = PRINTER_ENUM_ICON8;
946*12890SJoyce.McIntosh@Sun.COM 		offset = 460;
947*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, poutbuf, &offset, &pinfo1->flags);
948*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, poutbuf, &offset, &pinfo1->description);
949*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, poutbuf, &offset, &pinfo1->comment);
950*12890SJoyce.McIntosh@Sun.COM 		break;
951*12890SJoyce.McIntosh@Sun.COM 	case 2:
952*12890SJoyce.McIntosh@Sun.COM 		offset = param->BufCount;
953*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, soutbuf, &offset, &pinfo2->servername);
954*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, poutbuf, &offset, &pinfo2->printername);
955*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, SPOOLSS_PRINTER, &offset,
956*12890SJoyce.McIntosh@Sun.COM 		    &pinfo2->sharename);
957*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, "CIFS Printer Port", &offset,
958*12890SJoyce.McIntosh@Sun.COM 		    &pinfo2->portname);
959*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, "", &offset, &pinfo2->drivername);
960*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, SPOOLSS_PRINTER, &offset,
961*12890SJoyce.McIntosh@Sun.COM 		    &pinfo2->comment);
962*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, "farside", &offset, &pinfo2->location);
963*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, "farside", &offset, &pinfo2->sepfile);
964*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, "winprint", &offset,
965*12890SJoyce.McIntosh@Sun.COM 		    &pinfo2->printprocessor);
966*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, "RAW", &offset, &pinfo2->datatype);
967*12890SJoyce.McIntosh@Sun.COM 		smb_rpc_off(wname, "", &offset, &pinfo2->datatype);
968*12890SJoyce.McIntosh@Sun.COM 		pinfo2->attributes = 0x00001048;
969*12890SJoyce.McIntosh@Sun.COM 		pinfo2->status = 0x00000000;
970*12890SJoyce.McIntosh@Sun.COM 		pinfo2->starttime = 0;
971*12890SJoyce.McIntosh@Sun.COM 		pinfo2->untiltime = 0;
972*12890SJoyce.McIntosh@Sun.COM 		pinfo2->cjobs = 0;
973*12890SJoyce.McIntosh@Sun.COM 		pinfo2->averageppm = 0;
974*12890SJoyce.McIntosh@Sun.COM 		pinfo2->defaultpriority = 0;
975*12890SJoyce.McIntosh@Sun.COM 		pinfo2->devmode = 568; // offset
976*12890SJoyce.McIntosh@Sun.COM 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
977*12890SJoyce.McIntosh@Sun.COM 		devmode2 = (struct spoolss_DeviceMode *)(param->Buf
978*12890SJoyce.McIntosh@Sun.COM 		    + pinfo2->devmode);
979*12890SJoyce.McIntosh@Sun.COM 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
980*12890SJoyce.McIntosh@Sun.COM 		(void) smb_mbstowcs(((smb_wchar_t *)
981*12890SJoyce.McIntosh@Sun.COM 		    (devmode2->devicename)), (const char *)poutbuf, 25);
982*12890SJoyce.McIntosh@Sun.COM 		devmode2->specversion = 0x0401;
983*12890SJoyce.McIntosh@Sun.COM 		devmode2->driverversion = 1024;
984*12890SJoyce.McIntosh@Sun.COM 		devmode2->size = 220;
985*12890SJoyce.McIntosh@Sun.COM 		devmode2->driverextra_length = 0;
986*12890SJoyce.McIntosh@Sun.COM 		devmode2->fields = 0x00014713;
987*12890SJoyce.McIntosh@Sun.COM 		devmode2->orientation = 1;
988*12890SJoyce.McIntosh@Sun.COM 		devmode2->papersize = 1;
989*12890SJoyce.McIntosh@Sun.COM 		devmode2->paperlength = 0;
990*12890SJoyce.McIntosh@Sun.COM 		devmode2->paperwidth = 0;
991*12890SJoyce.McIntosh@Sun.COM 		devmode2->scale = 100;
992*12890SJoyce.McIntosh@Sun.COM 		devmode2->copies = 1;
993*12890SJoyce.McIntosh@Sun.COM 		devmode2->defaultsource = 15;
994*12890SJoyce.McIntosh@Sun.COM 		devmode2->printquality = 65532;
995*12890SJoyce.McIntosh@Sun.COM 		devmode2->color = 1;
996*12890SJoyce.McIntosh@Sun.COM 		devmode2->duplex = 1;
997*12890SJoyce.McIntosh@Sun.COM 		devmode2->yresolution = 1;
998*12890SJoyce.McIntosh@Sun.COM 		devmode2->ttoption = 1;
999*12890SJoyce.McIntosh@Sun.COM 		devmode2->collate = 0;
1000*12890SJoyce.McIntosh@Sun.COM 		/*LINTED E_BAD_PTR_CAST_ALIGN*/
1001*12890SJoyce.McIntosh@Sun.COM 		(void) smb_mbstowcs(((smb_wchar_t *)
1002*12890SJoyce.McIntosh@Sun.COM 		    (devmode2->formname)), (const char *)"Letter", 6);
1003*12890SJoyce.McIntosh@Sun.COM 		devmode2->logpixels = 0;
1004*12890SJoyce.McIntosh@Sun.COM 		devmode2->bitsperpel = 0;
1005*12890SJoyce.McIntosh@Sun.COM 		devmode2->pelswidth = 0;
1006*12890SJoyce.McIntosh@Sun.COM 		devmode2->pelsheight = 0;
1007*12890SJoyce.McIntosh@Sun.COM 		devmode2->displayflags = 0;
1008*12890SJoyce.McIntosh@Sun.COM 		devmode2->displayfrequency = 0;
1009*12890SJoyce.McIntosh@Sun.COM 		devmode2->icmmethod = 0;
1010*12890SJoyce.McIntosh@Sun.COM 		devmode2->icmintent = 0;
1011*12890SJoyce.McIntosh@Sun.COM 		devmode2->mediatype = 0;
1012*12890SJoyce.McIntosh@Sun.COM 		devmode2->dithertype = 0;
1013*12890SJoyce.McIntosh@Sun.COM 		devmode2->reserved1 = 0;
1014*12890SJoyce.McIntosh@Sun.COM 		devmode2->reserved2 = 0;
1015*12890SJoyce.McIntosh@Sun.COM 		devmode2->panningwidth = 0;
1016*12890SJoyce.McIntosh@Sun.COM 		devmode2->panningheight = 0;
1017*12890SJoyce.McIntosh@Sun.COM 
1018*12890SJoyce.McIntosh@Sun.COM 		pinfo2->secdesc = 84;
1019*12890SJoyce.McIntosh@Sun.COM 		tmpbuf = (uint8_t *)(pinfo2->secdesc + (uint8_t *)param->Buf);
1020*12890SJoyce.McIntosh@Sun.COM 		error = spoolss_s_make_sd(tmpbuf);
1021*12890SJoyce.McIntosh@Sun.COM 		param->needed = 712;
1022*12890SJoyce.McIntosh@Sun.COM 		break;
1023*12890SJoyce.McIntosh@Sun.COM 
1024*12890SJoyce.McIntosh@Sun.COM 	default:
1025*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_NOTICE, "spoolss_s_GetPrinter: INVALID_LEVEL");
1026*12890SJoyce.McIntosh@Sun.COM 		status = ERROR_INVALID_LEVEL;
1027*12890SJoyce.McIntosh@Sun.COM 		break;
1028*12890SJoyce.McIntosh@Sun.COM 
1029*12890SJoyce.McIntosh@Sun.COM 	}
1030*12890SJoyce.McIntosh@Sun.COM error_out:
1031*12890SJoyce.McIntosh@Sun.COM 	param->status = status;
1032*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
1033*12890SJoyce.McIntosh@Sun.COM }
1034*12890SJoyce.McIntosh@Sun.COM 
1035*12890SJoyce.McIntosh@Sun.COM int
1036*12890SJoyce.McIntosh@Sun.COM spoolss_s_make_sd(uint8_t *sd_buf)
1037*12890SJoyce.McIntosh@Sun.COM {
1038*12890SJoyce.McIntosh@Sun.COM 	smb_sd_t			sd;
1039*12890SJoyce.McIntosh@Sun.COM 	uint32_t			status;
1040*12890SJoyce.McIntosh@Sun.COM 
1041*12890SJoyce.McIntosh@Sun.COM 	bzero(&sd, sizeof (smb_sd_t));
1042*12890SJoyce.McIntosh@Sun.COM 
1043*12890SJoyce.McIntosh@Sun.COM 	if ((status = spoolss_sd_format(&sd)) == ERROR_SUCCESS) {
1044*12890SJoyce.McIntosh@Sun.COM 		status = srvsvc_sd_set_relative(&sd, sd_buf);
1045*12890SJoyce.McIntosh@Sun.COM 		smb_sd_term(&sd);
1046*12890SJoyce.McIntosh@Sun.COM 		return (NDR_DRC_OK);
1047*12890SJoyce.McIntosh@Sun.COM 	}
1048*12890SJoyce.McIntosh@Sun.COM 	syslog(LOG_NOTICE, "spoolss_s_make_sd: error status=%d", status);
1049*12890SJoyce.McIntosh@Sun.COM 	smb_sd_term(&sd);
1050*12890SJoyce.McIntosh@Sun.COM 	return (NDR_DRC_OK);
1051*12890SJoyce.McIntosh@Sun.COM }
1052*12890SJoyce.McIntosh@Sun.COM 
1053*12890SJoyce.McIntosh@Sun.COM static uint32_t
1054*12890SJoyce.McIntosh@Sun.COM spoolss_sd_format(smb_sd_t *sd)
1055*12890SJoyce.McIntosh@Sun.COM {
1056*12890SJoyce.McIntosh@Sun.COM 	smb_fssd_t	fs_sd;
1057*12890SJoyce.McIntosh@Sun.COM 	acl_t		*acl;
1058*12890SJoyce.McIntosh@Sun.COM 	uint32_t	status = ERROR_SUCCESS;
1059*12890SJoyce.McIntosh@Sun.COM 
1060*12890SJoyce.McIntosh@Sun.COM 	if (acl_fromtext("everyone@:full_set::allow", &acl) != 0) {
1061*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_ERR, "spoolss_sd_format: NOT_ENOUGH_MEMORY");
1062*12890SJoyce.McIntosh@Sun.COM 		return (ERROR_NOT_ENOUGH_MEMORY);
1063*12890SJoyce.McIntosh@Sun.COM 	}
1064*12890SJoyce.McIntosh@Sun.COM 	smb_fssd_init(&fs_sd, SMB_ALL_SECINFO, SMB_FSSD_FLAGS_DIR);
1065*12890SJoyce.McIntosh@Sun.COM 	fs_sd.sd_uid = 0;
1066*12890SJoyce.McIntosh@Sun.COM 	fs_sd.sd_gid = 0;
1067*12890SJoyce.McIntosh@Sun.COM 	fs_sd.sd_zdacl = acl;
1068*12890SJoyce.McIntosh@Sun.COM 	fs_sd.sd_zsacl = NULL;
1069*12890SJoyce.McIntosh@Sun.COM 
1070*12890SJoyce.McIntosh@Sun.COM 	if (smb_sd_fromfs(&fs_sd, sd) != NT_STATUS_SUCCESS) {
1071*12890SJoyce.McIntosh@Sun.COM 		syslog(LOG_NOTICE, "spoolss_sd_format: ACCESS_DENIED");
1072*12890SJoyce.McIntosh@Sun.COM 		status = ERROR_ACCESS_DENIED;
1073*12890SJoyce.McIntosh@Sun.COM 	}
1074*12890SJoyce.McIntosh@Sun.COM 	smb_fssd_term(&fs_sd);
1075*12890SJoyce.McIntosh@Sun.COM 	return (status);
1076*12890SJoyce.McIntosh@Sun.COM }
1077*12890SJoyce.McIntosh@Sun.COM 
1078*12890SJoyce.McIntosh@Sun.COM /*ARGSUSED*/
1079*12890SJoyce.McIntosh@Sun.COM static int
10808334SJose.Borrego@Sun.COM spoolss_s_stub(void *arg, ndr_xa_t *mxa)
10818334SJose.Borrego@Sun.COM {
10828334SJose.Borrego@Sun.COM 	return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED);
10838334SJose.Borrego@Sun.COM }
1084*12890SJoyce.McIntosh@Sun.COM 
1085*12890SJoyce.McIntosh@Sun.COM /*ARGSUSED*/
1086*12890SJoyce.McIntosh@Sun.COM void
1087*12890SJoyce.McIntosh@Sun.COM fixup_spoolss_RFNPCNEX(struct spoolss_RFNPCNEX *val)
1088*12890SJoyce.McIntosh@Sun.COM {
1089*12890SJoyce.McIntosh@Sun.COM 	unsigned short size1 = 0;
1090*12890SJoyce.McIntosh@Sun.COM 	unsigned short size2 = 0;
1091*12890SJoyce.McIntosh@Sun.COM 	unsigned short size3 = 0;
1092*12890SJoyce.McIntosh@Sun.COM 	struct spoolss_RPC_V2_NOTIFY_INFO *pinfo;
1093*12890SJoyce.McIntosh@Sun.COM 
1094*12890SJoyce.McIntosh@Sun.COM 	pinfo = val->ppinfo->pinfo;
1095*12890SJoyce.McIntosh@Sun.COM 	switch (pinfo->aData->Reserved) {
1096*12890SJoyce.McIntosh@Sun.COM 	case TABLE_STRING:
1097*12890SJoyce.McIntosh@Sun.COM 		size1 = sizeof (struct STRING_CONTAINER);
1098*12890SJoyce.McIntosh@Sun.COM 		break;
1099*12890SJoyce.McIntosh@Sun.COM 	case TABLE_DWORD:
1100*12890SJoyce.McIntosh@Sun.COM 		size1 = sizeof (DWORD) * 2;
1101*12890SJoyce.McIntosh@Sun.COM 		break;
1102*12890SJoyce.McIntosh@Sun.COM 	case TABLE_TIME:
1103*12890SJoyce.McIntosh@Sun.COM 		size1 = sizeof (struct SYSTEMTIME_CONTAINER);
1104*12890SJoyce.McIntosh@Sun.COM 		break;
1105*12890SJoyce.McIntosh@Sun.COM 	case TABLE_DEVMODE:
1106*12890SJoyce.McIntosh@Sun.COM 		size1 = sizeof (struct spoolssDevmodeContainer);
1107*12890SJoyce.McIntosh@Sun.COM 		break;
1108*12890SJoyce.McIntosh@Sun.COM 	case TABLE_SECURITY_DESCRIPTOR:
1109*12890SJoyce.McIntosh@Sun.COM 		size1 = sizeof (struct SECURITY_CONTAINER);
1110*12890SJoyce.McIntosh@Sun.COM 		break;
1111*12890SJoyce.McIntosh@Sun.COM 	default:
1112*12890SJoyce.McIntosh@Sun.COM 		return;
1113*12890SJoyce.McIntosh@Sun.COM 	}
1114*12890SJoyce.McIntosh@Sun.COM 	size2 = size1 + (2 * sizeof (DWORD));
1115*12890SJoyce.McIntosh@Sun.COM 	size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
1116*12890SJoyce.McIntosh@Sun.COM 
1117*12890SJoyce.McIntosh@Sun.COM 	FIXUP_PDU_SIZE(spoolss_RPC_V2_NOTIFY_INFO_DATA_DATA, size1);
1118*12890SJoyce.McIntosh@Sun.COM 	FIXUP_PDU_SIZE(spoolss_RPC_V2_NOTIFY_INFO_DATA, size2);
1119*12890SJoyce.McIntosh@Sun.COM 	FIXUP_PDU_SIZE(spoolss_RPC_V2_NOTIFY_INFO, size3);
1120*12890SJoyce.McIntosh@Sun.COM 	FIXUP_PDU_SIZE(spoolss_RFNPCNEX, size3);
1121*12890SJoyce.McIntosh@Sun.COM }
1122*12890SJoyce.McIntosh@Sun.COM 
1123*12890SJoyce.McIntosh@Sun.COM void
1124*12890SJoyce.McIntosh@Sun.COM fixup_spoolss_GetPrinter(struct spoolss_GetPrinter *val)
1125*12890SJoyce.McIntosh@Sun.COM {
1126*12890SJoyce.McIntosh@Sun.COM 	unsigned short size1 = 0;
1127*12890SJoyce.McIntosh@Sun.COM 	unsigned short size2 = 0;
1128*12890SJoyce.McIntosh@Sun.COM 	unsigned short size3 = 0;
1129*12890SJoyce.McIntosh@Sun.COM 
1130*12890SJoyce.McIntosh@Sun.COM 	switch (val->switch_value) {
1131*12890SJoyce.McIntosh@Sun.COM 	CASE_INFO_ENT(spoolss_GetPrinter, 0);
1132*12890SJoyce.McIntosh@Sun.COM 	CASE_INFO_ENT(spoolss_GetPrinter, 1);
1133*12890SJoyce.McIntosh@Sun.COM 	CASE_INFO_ENT(spoolss_GetPrinter, 2);
1134*12890SJoyce.McIntosh@Sun.COM 	CASE_INFO_ENT(spoolss_GetPrinter, 3);
1135*12890SJoyce.McIntosh@Sun.COM 	CASE_INFO_ENT(spoolss_GetPrinter, 4);
1136*12890SJoyce.McIntosh@Sun.COM 	CASE_INFO_ENT(spoolss_GetPrinter, 5);
1137*12890SJoyce.McIntosh@Sun.COM 	CASE_INFO_ENT(spoolss_GetPrinter, 6);
1138*12890SJoyce.McIntosh@Sun.COM 	CASE_INFO_ENT(spoolss_GetPrinter, 7);
1139*12890SJoyce.McIntosh@Sun.COM 	CASE_INFO_ENT(spoolss_GetPrinter, 8);
1140*12890SJoyce.McIntosh@Sun.COM 
1141*12890SJoyce.McIntosh@Sun.COM 	default:
1142*12890SJoyce.McIntosh@Sun.COM 		return;
1143*12890SJoyce.McIntosh@Sun.COM 	};
1144*12890SJoyce.McIntosh@Sun.COM 
1145*12890SJoyce.McIntosh@Sun.COM 	size2 = size1 + (2 * sizeof (DWORD));
1146*12890SJoyce.McIntosh@Sun.COM 	size3 = size2 + sizeof (ndr_request_hdr_t) + sizeof (DWORD);
1147*12890SJoyce.McIntosh@Sun.COM 
1148*12890SJoyce.McIntosh@Sun.COM 	FIXUP_PDU_SIZE(spoolss_GetPrinter_result_u, size1);
1149*12890SJoyce.McIntosh@Sun.COM 	FIXUP_PDU_SIZE(spoolss_GetPrinter_result, size2);
1150*12890SJoyce.McIntosh@Sun.COM 	FIXUP_PDU_SIZE(spoolss_GetPrinter, size3);
1151*12890SJoyce.McIntosh@Sun.COM }
1152