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