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