diff options
-rw-r--r-- | source3/param/loadparm.c | 4 | ||||
-rw-r--r-- | source3/smbd/lanman.c | 190 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 72 |
3 files changed, 99 insertions, 167 deletions
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 3fdb884a51..6b3ded8c60 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -178,6 +178,7 @@ typedef struct int maxdisksize; int lpqcachetime; int iMaxSmbdProcesses; + BOOL bLanmanPrinting; int iTotalPrintJobs; int syslog; int os_level; @@ -822,6 +823,7 @@ static struct parm_struct parm_table[] = { {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT}, {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL}, {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, + {"lanman printing only", P_BOOL, P_GLOBAL, &Globals.bLanmanPrinting, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL}, @@ -1213,6 +1215,7 @@ static void init_globals(void) Globals.max_xmit = 65535; Globals.max_mux = 50; /* This is *needed* for profile support. */ Globals.lpqcachetime = 10; + Globals.bLanmanPrinting = False; Globals.iMaxSmbdProcesses = 0;/* no limit specified */ Globals.iTotalPrintJobs = 0; /* no limit specified */ Globals.pwordlevel = 0; @@ -1570,6 +1573,7 @@ FN_GLOBAL_INTEGER(lp_security, &Globals.security) FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize) FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime) FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses) +FN_GLOBAL_INTEGER(lp_lanman_printing_only, &Globals.bLanmanPrinting) FN_GLOBAL_INTEGER(lp_totalprintjobs, &Globals.iTotalPrintJobs) FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog) static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as) diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index aaf8b3fafe..c84812cb83 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -845,120 +845,112 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn, char **rdata,char **rparam, int *rdata_len,int *rparam_len) { - char *str1 = param+2; - char *str2 = skip_string(str1,1); - char *p = skip_string(str2,1); - char *QueueName = p; - int uLevel; - int count=0; - int snum; - char* str3; - struct pack_desc desc; - print_queue_struct *queue=NULL; - print_status_struct status; - char* tmpdata=NULL; + char *str1 = param+2; + char *str2 = skip_string(str1,1); + char *p = skip_string(str2,1); + char *QueueName = p; + int uLevel; + int count=0; + int snum; + char* str3; + struct pack_desc desc; + print_queue_struct *queue=NULL; + print_status_struct status; + char* tmpdata=NULL; - memset((char *)&status,'\0',sizeof(status)); - memset((char *)&desc,'\0',sizeof(desc)); + memset((char *)&status,'\0',sizeof(status)); + memset((char *)&desc,'\0',sizeof(desc)); - p = skip_string(p,1); - uLevel = SVAL(p,0); - str3 = p + 4; + p = skip_string(p,1); + uLevel = SVAL(p,0); + str3 = p + 4; - /* remove any trailing username */ - if ((p = strchr_m(QueueName,'%'))) *p = 0; + /* remove any trailing username */ + if ((p = strchr_m(QueueName,'%'))) + *p = 0; - DEBUG(3,("PrintQueue uLevel=%d name=%s\n",uLevel,QueueName)); + DEBUG(3,("api_DosPrintQGetInfo uLevel=%d name=%s\n",uLevel,QueueName)); - /* check it's a supported varient */ - if (!prefix_ok(str1,"zWrLh")) return False; - if (!check_printq_info(&desc,uLevel,str2,str3)) { - /* - * Patch from Scott Moomaw <scott@bridgewater.edu> - * to return the 'invalid info level' error if an - * unknown level was requested. - */ - *rdata_len = 0; - *rparam_len = 6; - *rparam = REALLOC(*rparam,*rparam_len); - SSVALS(*rparam,0,ERROR_INVALID_LEVEL); - SSVAL(*rparam,2,0); - SSVAL(*rparam,4,0); - return(True); - } + /* check it's a supported varient */ + if (!prefix_ok(str1,"zWrLh")) + return False; + if (!check_printq_info(&desc,uLevel,str2,str3)) { + /* + * Patch from Scott Moomaw <scott@bridgewater.edu> + * to return the 'invalid info level' error if an + * unknown level was requested. + */ + *rdata_len = 0; + *rparam_len = 6; + *rparam = REALLOC(*rparam,*rparam_len); + SSVALS(*rparam,0,ERROR_INVALID_LEVEL); + SSVAL(*rparam,2,0); + SSVAL(*rparam,4,0); + return(True); + } - snum = lp_servicenumber(QueueName); - if (snum < 0 && pcap_printername_ok(QueueName,NULL)) { - int pnum = lp_servicenumber(PRINTERS_NAME); - if (pnum >= 0) { - lp_add_printer(QueueName,pnum); - snum = lp_servicenumber(QueueName); - } - } + snum = lp_servicenumber(QueueName); + if (snum < 0 && pcap_printername_ok(QueueName,NULL)) { + int pnum = lp_servicenumber(PRINTERS_NAME); + if (pnum >= 0) { + lp_add_printer(QueueName,pnum); + snum = lp_servicenumber(QueueName); + } + } - if (snum < 0 || !VALID_SNUM(snum)) return(False); + if (snum < 0 || !VALID_SNUM(snum)) + return(False); - if (uLevel==52) { - count = get_printerdrivernumber(snum); - DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count)); - } else { - count = print_queue_status(snum, &queue,&status); - } + if (uLevel==52) { + count = get_printerdrivernumber(snum); + DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count)); + } else { + count = print_queue_status(snum, &queue,&status); + } - if (mdrcnt > 0) { - *rdata = REALLOC(*rdata,mdrcnt); - desc.base = *rdata; - desc.buflen = mdrcnt; - } else { - /* - * Don't return data but need to get correct length - * init_package will return wrong size if buflen=0 - */ - desc.buflen = getlen(desc.format); - desc.base = tmpdata = (char *) malloc (desc.buflen); - } + if (mdrcnt > 0) { + *rdata = REALLOC(*rdata,mdrcnt); + desc.base = *rdata; + desc.buflen = mdrcnt; + } else { + /* + * Don't return data but need to get correct length + * init_package will return wrong size if buflen=0 + */ + desc.buflen = getlen(desc.format); + desc.base = tmpdata = (char *) malloc (desc.buflen); + } - if (init_package(&desc,1,count)) { - desc.subcount = count; - fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status); - } else if(uLevel == 0) { -#if 0 - /* - * This is a *disgusting* hack. - * This is *so* bad that even I'm embarrassed (and I - * have no shame). Here's the deal : - * Until we get the correct SPOOLSS code into smbd - * then when we're running with NT SMB support then - * NT makes this call with a level of zero, and then - * immediately follows it with an open request to - * the \\SRVSVC pipe. If we allow that open to - * succeed then NT barfs when it cannot open the - * \\SPOOLSS pipe immediately after and continually - * whines saying "Printer name is invalid" forever - * after. If we cause *JUST THIS NEXT OPEN* of \\SRVSVC - * to fail, then NT downgrades to using the downlevel code - * and everything works as well as before. I hate - * myself for adding this code.... JRA. - */ - - fail_next_srvsvc_open(); -#endif - } + if (init_package(&desc,1,count)) { + desc.subcount = count; + fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status); + } - *rdata_len = desc.usedlen; + *rdata_len = desc.usedlen; - *rparam_len = 6; - *rparam = REALLOC(*rparam,*rparam_len); - SSVALS(*rparam,0,desc.errcode); - SSVAL(*rparam,2,0); - SSVAL(*rparam,4,desc.neededlen); + /* + * We must set the return code to ERRbuftoosmall + * in order to support lanman style printing with Win NT/2k + * clients --jerry + */ + if (!mdrcnt && lp_lanman_printing_only()) + desc.errcode = ERRbuftoosmall; + + *rdata_len = desc.usedlen; + *rparam_len = 6; + *rparam = REALLOC(*rparam,*rparam_len); + SSVALS(*rparam,0,desc.errcode); + SSVAL(*rparam,2,0); + SSVAL(*rparam,4,desc.neededlen); - DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode)); + DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode)); - if (queue) free(queue); - if (tmpdata) free (tmpdata); + if (queue) + free(queue); + if (tmpdata) + free (tmpdata); - return(True); + return(True); } /**************************************************************************** diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index f0403f011e..d342e44ca4 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -459,69 +459,6 @@ to open_mode %x\n", (unsigned long)desired_access, (unsigned long)share_access, return smb_open_mode; } -#if 0 -/* - * This is a *disgusting* hack. - * This is *so* bad that even I'm embarrassed (and I - * have no shame). Here's the deal : - * Until we get the correct SPOOLSS code into smbd - * then when we're running with NT SMB support then - * NT makes this call with a level of zero, and then - * immediately follows it with an open request to - * the \\SRVSVC pipe. If we allow that open to - * succeed then NT barfs when it cannot open the - * \\SPOOLSS pipe immediately after and continually - * whines saying "Printer name is invalid" forever - * after. If we cause *JUST THIS NEXT OPEN* of \\SRVSVC - * to fail, then NT downgrades to using the downlevel code - * and everything works as well as before. I hate - * myself for adding this code.... JRA. - * - * The HACK_FAIL_TIME define allows only a 2 - * second window for this to occur, just in - * case... - */ - -static BOOL fail_next_srvsvc = False; -static time_t fail_time; -#define HACK_FAIL_TIME 2 /* In seconds. */ - -void fail_next_srvsvc_open(void) -{ - /* Check client is WinNT proper; Win2K doesn't like Jeremy's hack - matty */ - if (get_remote_arch() != RA_WINNT) - return; - - fail_next_srvsvc = True; - fail_time = time(NULL); - DEBUG(10,("fail_next_srvsvc_open: setting up timeout close of \\srvsvc pipe for print fix.\n")); -} - -/* - * HACK alert.... see above - JRA. - */ - -BOOL should_fail_next_srvsvc_open(const char *pipename) -{ - - DEBUG(10,("should_fail_next_srvsvc_open: fail = %d, pipe = %s\n", - (int)fail_next_srvsvc, pipename)); - - if(fail_next_srvsvc && (time(NULL) > fail_time + HACK_FAIL_TIME)) { - fail_next_srvsvc = False; - fail_time = (time_t)0; - DEBUG(10,("should_fail_next_srvsvc_open: End of timeout close of \\srvsvc pipe for print fix.\n")); - } - - if(fail_next_srvsvc && strequal(pipename, "srvsvc")) { - fail_next_srvsvc = False; - DEBUG(10,("should_fail_next_srvsvc_open: Deliberately failing open of \\srvsvc pipe for print fix.\n")); - return True; - } - return False; -} -#endif - /**************************************************************************** Reply to an NT create and X call on a pipe. ****************************************************************************/ @@ -536,6 +473,10 @@ static int nt_open_pipe(char *fname, connection_struct *conn, DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname)); /* See if it is one we want to handle. */ + + if (lp_lanman_printing_only() && strequal(fname, "\\spoolss")) + return(ERROR(ERRSRV,ERRaccess)); + for( i = 0; known_nt_pipes[i]; i++ ) if( strequal(fname,known_nt_pipes[i])) break; @@ -546,11 +487,6 @@ static int nt_open_pipe(char *fname, connection_struct *conn, /* Strip \\ off the name. */ fname++; -#if 0 - if(should_fail_next_srvsvc_open(fname)) - return (ERROR(ERRSRV,ERRaccess)); -#endif - DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname)); p = open_rpc_pipe_p(fname, conn, vuid); |