summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/param/loadparm.c4
-rw-r--r--source3/smbd/lanman.c190
-rw-r--r--source3/smbd/nttrans.c72
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);