The branch, master has been updated via f56d900... s3-lanman: use spoolss for api_WPrintDestGetInfo() and api_WPrintDestEnum(). via c88ff10... s3-lanman: fix debug message in api_WPrintJobEnumerate(). via 566ea59... s3-lanman: remove a unnecessary memset in api_WPrintJobEnumerate(). via fe1f503... s3-lanman: remove unused code. via f23bcb5... s3-lanman: use spoolss for api_DosPrintQGetInfo and api_DosPrintQEnum. from f11a5d1... Don't return an intermediate reply on async on a pipe call (Windows doesn't).
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit f56d9006d5790b8b752c72600ccd3942a2742f17 Author: Günther Deschner <g...@samba.org> Date: Wed Apr 28 01:11:19 2010 +0200 s3-lanman: use spoolss for api_WPrintDestGetInfo() and api_WPrintDestEnum(). With this, I think, all implemented RAP printing calls are routed over SPOOLSS. Torture tests to follow... Guenther commit c88ff10d690094617ed382a6ff16921a7bef2a63 Author: Günther Deschner <g...@samba.org> Date: Wed Apr 28 01:10:49 2010 +0200 s3-lanman: fix debug message in api_WPrintJobEnumerate(). Guenther commit 566ea59b27b97038f7fd4315746019eab002a599 Author: Günther Deschner <g...@samba.org> Date: Wed Apr 28 01:07:08 2010 +0200 s3-lanman: remove a unnecessary memset in api_WPrintJobEnumerate(). Guenther commit fe1f503a957aa0041ae101e27950b7e31a965548 Author: Günther Deschner <g...@samba.org> Date: Tue Apr 27 23:12:40 2010 +0200 s3-lanman: remove unused code. Guenther commit f23bcb5c5e64cfd6b8a4b19568d40919c28610f1 Author: Günther Deschner <g...@samba.org> Date: Tue Apr 27 22:55:11 2010 +0200 s3-lanman: use spoolss for api_DosPrintQGetInfo and api_DosPrintQEnum. Guenther ----------------------------------------------------------------------- Summary of changes: source3/smbd/lanman.c | 644 +++++++++++++++++++++++++------------------------ 1 files changed, 325 insertions(+), 319 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 4b7703b..e3c94cf 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -168,32 +168,6 @@ static int StrlenExpanded(connection_struct *conn, int snum, char *s) return strlen(buf) + 1; } -static char *Expand(connection_struct *conn, int snum, char *s) -{ - TALLOC_CTX *ctx = talloc_tos(); - char *buf = NULL; - - if (!s) { - return NULL; - } - buf = talloc_strdup(ctx,s); - if (!buf) { - return 0; - } - buf = talloc_string_sub(ctx,buf,"%S",lp_servicename(snum)); - if (!buf) { - return 0; - } - return talloc_sub_advanced(ctx, - lp_servicename(SNUM(conn)), - conn->server_info->unix_name, - conn->connectpath, - conn->server_info->utok.gid, - conn->server_info->sanitized_username, - pdb_get_domain(conn->server_info->sam_account), - buf); -} - /******************************************************************* Check a API string for validity when we only need to check the prefix. ******************************************************************/ @@ -533,21 +507,6 @@ static int check_printq_info(struct pack_desc* desc, /* turn a print job status into a on the wire status */ -static int printj_status(int v) -{ - switch (v) { - case LPQ_QUEUED: - return RAP_JOB_STATUS_QUEUED; - case LPQ_PAUSED: - return RAP_JOB_STATUS_PAUSED; - case LPQ_SPOOLING: - return RAP_JOB_STATUS_SPOOLING; - case LPQ_PRINTING: - return RAP_JOB_STATUS_PRINTING; - } - return 0; -} - static int printj_spoolss_status(int v) { if (v == JOB_STATUS_QUEUED) @@ -563,75 +522,15 @@ static int printj_spoolss_status(int v) /* turn a print queue status into a on the wire status */ -static int printq_status(int v) +static int printq_spoolss_status(int v) { - switch (v) { - case LPQ_QUEUED: + if (v == PRINTER_STATUS_OK) return 0; - case LPQ_PAUSED: + if (v & PRINTER_STATUS_PAUSED) return RAP_QUEUE_STATUS_PAUSED; - } return RAP_QUEUE_STATUS_ERROR; } -static void fill_printjob_info(connection_struct *conn, int snum, int uLevel, - struct pack_desc *desc, - print_queue_struct *queue, int n) -{ - time_t t = queue->time; - - /* the client expects localtime */ - t -= get_time_zone(t); - - PACKI(desc,"W",pjobid_to_rap(lp_const_servicename(snum),queue->job)); /* uJobId */ - if (uLevel == 1) { - PACKS(desc,"B21",queue->fs_user); /* szUserName */ - PACKS(desc,"B",""); /* pad */ - PACKS(desc,"B16",""); /* szNotifyName */ - PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */ - PACKS(desc,"z",""); /* pszParms */ - PACKI(desc,"W",n+1); /* uPosition */ - PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */ - PACKS(desc,"z",""); /* pszStatus */ - PACKI(desc,"D",t); /* ulSubmitted */ - PACKI(desc,"D",queue->size); /* ulSize */ - PACKS(desc,"z",queue->fs_file); /* pszComment */ - } - if (uLevel == 2 || uLevel == 3 || uLevel == 4) { - PACKI(desc,"W",queue->priority); /* uPriority */ - PACKS(desc,"z",queue->fs_user); /* pszUserName */ - PACKI(desc,"W",n+1); /* uPosition */ - PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */ - PACKI(desc,"D",t); /* ulSubmitted */ - PACKI(desc,"D",queue->size); /* ulSize */ - PACKS(desc,"z","Samba"); /* pszComment */ - PACKS(desc,"z",queue->fs_file); /* pszDocument */ - if (uLevel == 3) { - PACKS(desc,"z",""); /* pszNotifyName */ - PACKS(desc,"z","PM_Q_RAW"); /* pszDataType */ - PACKS(desc,"z",""); /* pszParms */ - PACKS(desc,"z",""); /* pszStatus */ - PACKS(desc,"z",SERVICE(snum)); /* pszQueue */ - PACKS(desc,"z","lpd"); /* pszQProcName */ - PACKS(desc,"z",""); /* pszQProcParms */ - PACKS(desc,"z","NULL"); /* pszDriverName */ - PackDriverData(desc); /* pDriverData */ - PACKS(desc,"z",""); /* pszPrinterName */ - } else if (uLevel == 4) { /* OS2 */ - PACKS(desc,"z",""); /* pszSpoolFileName */ - PACKS(desc,"z",""); /* pszPortName */ - PACKS(desc,"z",""); /* pszStatus */ - PACKI(desc,"D",0); /* ulPagesSpooled */ - PACKI(desc,"D",0); /* ulPagesSent */ - PACKI(desc,"D",0); /* ulPagesPrinted */ - PACKI(desc,"D",0); /* ulTimePrinted */ - PACKI(desc,"D",0); /* ulExtendJobStatus */ - PACKI(desc,"D",0); /* ulStartPage */ - PACKI(desc,"D",0); /* ulEndPage */ - } - } -} - static time_t spoolss_Time_to_time_t(const struct spoolss_Time *r) { struct tm unixtime; @@ -707,55 +606,15 @@ static void fill_spoolss_printjob_info(int uLevel, } /******************************************************************** - Return a driver name given an snum. - Returns True if from tdb, False otherwise. - ********************************************************************/ - -static bool get_driver_name(int snum, char **pp_drivername) -{ - NT_PRINTER_INFO_LEVEL *info = NULL; - bool in_tdb = false; - - get_a_printer (NULL, &info, 2, lp_servicename(snum)); - if (info != NULL) { - *pp_drivername = talloc_strdup(talloc_tos(), - info->info_2->drivername); - in_tdb = true; - free_a_printer(&info, 2); - if (!*pp_drivername) { - return false; - } - } - - return in_tdb; -} - -/******************************************************************** Respond to the DosPrintQInfo command with a level of 52 This is used to get printer driver information for Win9x clients ********************************************************************/ -static void fill_printq_info_52(connection_struct *conn, int snum, - struct pack_desc* desc, int count ) +static void fill_printq_info_52(struct spoolss_DriverInfo3 *driver, + struct pack_desc* desc, int count, + const char *printer_name) { int i; fstring location; - struct spoolss_DriverInfo8 *driver = NULL; - NT_PRINTER_INFO_LEVEL *printer = NULL; - - if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) { - DEBUG(3,("fill_printq_info_52: Failed to lookup printer [%s]\n", - lp_servicename(snum))); - goto err; - } - - if (!W_ERROR_IS_OK(get_a_printer_driver(talloc_tos(), &driver, printer->info_2->drivername, - "Windows 4.0", 0)) ) - { - DEBUG(3,("fill_printq_info_52: Failed to lookup driver [%s]\n", - printer->info_2->drivername)); - goto err; - } - trim_string((char *)driver->driver_path, "\\print$\\WIN40\\0\\", 0); trim_string((char *)driver->data_file, "\\print$\\WIN40\\0\\", 0); trim_string((char *)driver->help_file, "\\print$\\WIN40\\0\\", 0); @@ -795,40 +654,32 @@ static void fill_printq_info_52(connection_struct *conn, int snum, DEBUG(3,("fill_printq_info_52: file count specified by client [%d] != number of dependent files [%i]\n", count, i)); - DEBUG(3,("fill_printq_info on <%s> gave %d entries\n", SERVICE(snum),i)); + DEBUG(3,("fill_printq_info on <%s> gave %d entries\n", printer_name, i)); desc->errcode=NERR_Success; - goto done; - -err: - DEBUG(3,("fill_printq_info: Can't supply driver files\n")); - desc->errcode=NERR_notsupported; - -done: - if ( printer ) - free_a_printer( &printer, 2 ); - free_a_printer_driver(driver); } -static void fill_printq_info(connection_struct *conn, int snum, int uLevel, +static void fill_printq_info(int uLevel, struct pack_desc* desc, - int count, print_queue_struct* queue, - print_status_struct* status) + int count, + union spoolss_JobInfo *job_info, + struct spoolss_DriverInfo3 *driver_info, + struct spoolss_PrinterInfo2 *printer_info) { switch (uLevel) { case 1: case 2: - PACKS(desc,"B13",SERVICE(snum)); + PACKS(desc,"B13", printer_info->printername); break; case 3: case 4: case 5: - PACKS(desc,"z",Expand(conn,snum,SERVICE(snum))); + PACKS(desc,"z", printer_info->printername); break; case 51: - PACKI(desc,"K",printq_status(status->status)); + PACKI(desc,"K", printq_spoolss_status(printer_info->status)); break; } @@ -839,25 +690,19 @@ static void fill_printq_info(connection_struct *conn, int snum, int uLevel, PACKI(desc,"W",0); /* until time */ PACKS(desc,"z",""); /* pSepFile */ PACKS(desc,"z","lpd"); /* pPrProc */ - PACKS(desc,"z",SERVICE(snum)); /* pDestinations */ + PACKS(desc,"z", printer_info->printername); /* pDestinations */ PACKS(desc,"z",""); /* pParms */ - if (snum < 0) { + if (printer_info->printername == NULL) { PACKS(desc,"z","UNKNOWN PRINTER"); PACKI(desc,"W",LPSTAT_ERROR); - } - else if (!status || !status->message[0]) { - PACKS(desc,"z",Expand(conn,snum,lp_comment(snum))); - PACKI(desc,"W",LPSTAT_OK); /* status */ } else { - PACKS(desc,"z",status->message); - PACKI(desc,"W",printq_status(status->status)); /* status */ + PACKS(desc,"z", printer_info->comment); + PACKI(desc,"W", printq_spoolss_status(printer_info->status)); /* status */ } PACKI(desc,(uLevel == 1 ? "W" : "N"),count); } if (uLevel == 3 || uLevel == 4) { - char *drivername = NULL; - PACKI(desc,"W",5); /* uPriority */ PACKI(desc,"W",0); /* uStarttime */ PACKI(desc,"W",0); /* uUntiltime */ @@ -868,62 +713,32 @@ static void fill_printq_info(connection_struct *conn, int snum, int uLevel, PACKS(desc,"z",NULL); /* pszComment - don't ask.... JRA */ /* "don't ask" that it's done this way to fix corrupted Win9X/ME printer comments. */ - if (!status) { - PACKI(desc,"W",LPSTAT_OK); /* fsStatus */ - } else { - PACKI(desc,"W",printq_status(status->status)); /* fsStatus */ - } + PACKI(desc,"W", printq_spoolss_status(printer_info->status)); /* fsStatus */ PACKI(desc,(uLevel == 3 ? "W" : "N"),count); /* cJobs */ - PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */ - get_driver_name(snum,&drivername); - if (!drivername) { - return; - } - PACKS(desc,"z",drivername); /* pszDriverName */ + PACKS(desc,"z", printer_info->printername); /* pszPrinters */ + PACKS(desc,"z", printer_info->drivername); /* pszDriverName */ PackDriverData(desc); /* pDriverData */ } if (uLevel == 2 || uLevel == 4) { int i; - for (i=0;i<count;i++) - fill_printjob_info(conn,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i); + for (i = 0; i < count; i++) { + fill_spoolss_printjob_info(uLevel == 2 ? 1 : 2, desc, &job_info[i].info2, i); + } } if (uLevel==52) - fill_printq_info_52( conn, snum, desc, count ); + fill_printq_info_52(driver_info, desc, count, printer_info->printername); } /* This function returns the number of files for a given driver */ -static int get_printerdrivernumber(int snum) +static int get_printerdrivernumber(const struct spoolss_DriverInfo3 *driver) { int result = 0; - struct spoolss_DriverInfo8 *driver; - NT_PRINTER_INFO_LEVEL *printer = NULL; - - ZERO_STRUCT(driver); - - if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) { - DEBUG(3,("get_printerdrivernumber: Failed to lookup printer [%s]\n", - lp_servicename(snum))); - goto done; - } - - if (!W_ERROR_IS_OK(get_a_printer_driver(talloc_tos(), &driver, printer->info_2->drivername, - "Windows 4.0", 0)) ) - { - DEBUG(3,("get_printerdrivernumber: Failed to lookup driver [%s]\n", - printer->info_2->drivername)); - goto done; - } /* count the number of files */ while (driver->dependent_files && *driver->dependent_files[result]) result++; - done: - if ( printer ) - free_a_printer( &printer, 2 ); - - free_a_printer_driver(driver); return result; } @@ -940,18 +755,24 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid, char *p = skip_string(param,tpscnt,str2); char *QueueName = p; unsigned int uLevel; - int count=0; - int snum; + uint32_t count = 0; char *str3; struct pack_desc desc; - print_queue_struct *queue=NULL; - print_status_struct status; char* tmpdata=NULL; + WERROR werr = WERR_OK; + TALLOC_CTX *mem_ctx = talloc_tos(); + NTSTATUS status; + struct rpc_pipe_client *cli = NULL; + struct policy_handle handle; + struct spoolss_DevmodeContainer devmode_ctr; + union spoolss_DriverInfo driver_info; + union spoolss_JobInfo *job_info; + union spoolss_PrinterInfo printer_info; + if (!str1 || !str2 || !p) { return False; } - memset((char *)&status,'\0',sizeof(status)); memset((char *)&desc,'\0',sizeof(desc)); p = skip_string(param,tpscnt,p); @@ -989,21 +810,78 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid, return(True); } - snum = find_service(QueueName); - if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) - return False; + ZERO_STRUCT(handle); + + status = rpc_pipe_open_internal(mem_ctx, &ndr_table_spoolss.syntax_id, + rpc_spoolss_dispatch, conn->server_info, + &cli); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("api_DosPrintQGetInfo: could not connect to spoolss: %s\n", + nt_errstr(status))); + desc.errcode = W_ERROR_V(ntstatus_to_werror(status)); + goto out; + } + + ZERO_STRUCT(devmode_ctr); + + status = rpccli_spoolss_OpenPrinter(cli, mem_ctx, + QueueName, + NULL, + devmode_ctr, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle, + &werr); + if (!NT_STATUS_IS_OK(status)) { + desc.errcode = W_ERROR_V(ntstatus_to_werror(status)); + goto out; + } + if (!W_ERROR_IS_OK(werr)) { + desc.errcode = W_ERROR_V(werr); + goto out; + } if (uLevel==52) { - count = get_printerdrivernumber(snum); + uint32_t server_major_version; + uint32_t server_minor_version; + + werr = rpccli_spoolss_getprinterdriver2(cli, mem_ctx, + &handle, + "Windows 4.0", + 3, /* level */ + 0, + 0, /* version */ + 0, + &driver_info, + &server_major_version, + &server_minor_version); + if (!W_ERROR_IS_OK(werr)) { + desc.errcode = W_ERROR_V(werr); + goto out; + } + + count = get_printerdrivernumber(&driver_info.info3); DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count)); } else { - count = print_queue_status(snum, &queue,&status); + uint32_t num_jobs; + werr = rpccli_spoolss_enumjobs(cli, mem_ctx, + &handle, + 0, /* firstjob */ + 0xff, /* numjobs */ + 2, /* level */ + 0, /* offered */ + &num_jobs, + &job_info); + if (!W_ERROR_IS_OK(werr)) { + desc.errcode = W_ERROR_V(werr); + goto out; + } + + count = num_jobs; } if (mdrcnt > 0) { *rdata = smb_realloc_limit(*rdata,mdrcnt); if (!*rdata) { - SAFE_FREE(queue); return False; } desc.base = *rdata; @@ -1019,7 +897,7 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid, if (init_package(&desc,1,count)) { desc.subcount = count; - fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status); + fill_printq_info(uLevel,&desc,count, job_info, &driver_info.info3, &printer_info.info2); } *rdata_len = desc.usedlen; @@ -1032,11 +910,15 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid, if (!mdrcnt && lp_disable_spoolss()) desc.errcode = ERRbuftoosmall; + out: + if (is_valid_policy_hnd(&handle)) { + rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); + } + *rdata_len = desc.usedlen; *rparam_len = 6; *rparam = smb_realloc_limit(*rparam,*rparam_len); if (!*rparam) { - SAFE_FREE(queue); SAFE_FREE(tmpdata); return False; } @@ -1046,7 +928,6 @@ static bool api_DosPrintQGetInfo(connection_struct *conn, uint16 vuid, DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode)); - SAFE_FREE(queue); SAFE_FREE(tmpdata); return(True); @@ -1068,14 +949,19 @@ static bool api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char *p = skip_string(param,tpscnt,output_format1); unsigned int uLevel = get_safe_SVAL(param,tpscnt,p,0,-1); -- Samba Shared Repository