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