summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-03-23 03:12:58 +0000
committerJeremy Allison <jra@samba.org>2001-03-23 03:12:58 +0000
commita44721750944af9beb46f169a49a439b614a8622 (patch)
treed919f0287d64c24cec28ede7dd657117323512d0 /source3/smbd
parentda8805b377e361a7cab399b3c786a25f7175e7cf (diff)
downloadsamba-a44721750944af9beb46f169a49a439b614a8622.tar.gz
samba-a44721750944af9beb46f169a49a439b614a8622.tar.bz2
samba-a44721750944af9beb46f169a49a439b614a8622.zip
Two OS/2 printer fixes from Jim McDonough @ IBM.
First one adds a new info level into the lanman printing and an ioctl to the trans2 code. Andrew - this uses ASCII only. It looks ok to me but please check ! Second one adds a parameter "os2 driver map" that allows OS/2 driver names to be mapped. Jeremy. (This used to be commit da79b519e0b6b4317d7fb5260d74e0e74a7e0b46)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/lanman.c71
-rw-r--r--source3/smbd/trans2.c67
2 files changed, 121 insertions, 17 deletions
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 45ce286634..e9df2ed41e 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -474,7 +474,7 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
PACKI(desc,"D",queue->size); /* ulSize */
PACKS(desc,"z",queue->file); /* pszComment */
}
- if (uLevel == 2 || uLevel == 3) {
+ if (uLevel == 2 || uLevel == 3 || uLevel == 4) {
PACKI(desc,"W",queue->priority); /* uPriority */
PACKS(desc,"z",queue->user); /* pszUserName */
PACKI(desc,"W",n+1); /* uPosition */
@@ -494,6 +494,17 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
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 */
}
}
}
@@ -859,7 +870,8 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
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));
@@ -907,9 +919,19 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
count = print_queue_status(snum, &queue,&status);
}
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
+ 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);
@@ -948,7 +970,8 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
if (queue) free(queue);
-
+ if (tmpdata) free (tmpdata);
+
return(True);
}
@@ -2000,6 +2023,7 @@ static int check_printjob_info(struct pack_desc* desc,
case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
case 2: desc->format = "WWzWWDDzz"; break;
case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
+ case 4: desc->format = "WWzWWDDzzzzzDDDDDDD"; break;
default: return False;
}
if (strcmp(desc->format,id) != 0) return False;
@@ -2755,6 +2779,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
struct pack_desc desc;
print_queue_struct *queue=NULL;
print_status_struct status;
+ char *tmpdata=NULL;
uLevel = SVAL(p,2);
@@ -2776,9 +2801,19 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
for (i = 0; i < count; i++) {
if (queue[i].job == job) break;
}
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
+
+ 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,0)) {
if (i < count) {
@@ -2798,6 +2833,7 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
SSVAL(*rparam,4,desc.neededlen);
if (queue) free(queue);
+ if (tmpdata) free(tmpdata);
DEBUG(4,("WPrintJobGetInfo: errorcode %d\n",desc.errcode));
return(True);
@@ -2932,6 +2968,7 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
int uLevel;
struct pack_desc desc;
int snum;
+ char *tmpdata=NULL;
memset((char *)&desc,'\0',sizeof(desc));
@@ -2959,9 +2996,18 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
desc.neededlen = 0;
}
else {
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
+ 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,0)) {
fill_printdest_info(conn,snum,uLevel,&desc);
}
@@ -2975,6 +3021,7 @@ static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *par
SSVAL(*rparam,4,desc.neededlen);
DEBUG(4,("WPrintDestGetInfo: errorcode %d\n",desc.errcode));
+ if (tmpdata) free (tmpdata);
return(True);
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 0489e23040..b9c8ab086c 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -30,6 +30,7 @@ extern int smb_read_error;
extern fstring local_machine;
extern int global_oplock_break;
extern uint32 global_client_caps;
+extern pstring global_myname;
/****************************************************************************
Send the required number of replies back.
@@ -2193,6 +2194,41 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
return(-1);
}
+#define LMCAT_SPL 0x53
+#define LMFUNC_GETJOBID 0x60
+
+/****************************************************************************
+ reply to a TRANS2_IOCTL - used for OS/2 printing.
+****************************************************************************/
+
+static int call_trans2ioctl(connection_struct *conn, char* inbuf,
+ char* outbuf, int length, int bufsize,
+ char** pparams, char** ppdata)
+{
+ char *pdata = *ppdata;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv15);
+
+ if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
+ (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
+ pdata = Realloc(*ppdata, 32);
+ if(pdata == NULL) {
+ return(ERROR(ERRDOS,ERRnomem));
+ }
+ *ppdata = pdata;
+
+ /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2
+ CAN ACCEPT THIS IN UNICODE. JRA. */
+
+ SSVAL(pdata,0,fsp->print_jobid); /* Job number */
+ StrnCpy(pdata+2, global_myname, 15); /* Our NetBIOS name */
+ StrnCpy(pdata+18, lp_servicename(SNUM(conn)), 13); /* Service name */
+ send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
+ return(-1);
+ } else {
+ DEBUG(2,("Unknown TRANS2_IOCTL\n"));
+ return(ERROR(ERRSRV,ERRerror));
+ }
+}
/****************************************************************************
reply to a SMBfindclose (stop trans2 directory search)
@@ -2301,9 +2337,24 @@ int reply_trans2(connection_struct *conn,
/* All trans2 messages we handle have smb_sucnt == 1 - ensure this
is so as a sanity check */
if (suwcnt != 1) {
- DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
- END_PROFILE(SMBtrans2);
- return(ERROR(ERRSRV,ERRerror));
+ /*
+ * Need to have rc=0 for ioctl to get job id for OS/2.
+ * Network printing will fail if function is not successful.
+ * Similar function in reply.c will be used if protocol
+ * is LANMAN1.0 instead of LM1.2X002.
+ * Until DosPrintSetJobInfo with PRJINFO3 is supported,
+ * outbuf doesn't have to be set(only job id is used).
+ */
+ if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
+ (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
+ (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
+ DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
+ } else {
+ DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
+ DEBUG(2,("Transaction is %d\n",tran_call));
+ END_PROFILE(SMBtrans2);
+ return(ERROR(ERRSRV,ERRerror));
+ }
}
/* Allocate the space for the maximum needed parameters and data */
@@ -2466,10 +2517,16 @@ int reply_trans2(connection_struct *conn,
case TRANSACT2_GET_DFS_REFERRAL:
START_PROFILE_NESTED(Trans2_get_dfs_referral);
- outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
- bufsize, &params, &data);
+ outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
+ bufsize, &params, &data);
END_PROFILE_NESTED(Trans2_get_dfs_referral);
break;
+ case TRANSACT2_IOCTL:
+ START_PROFILE_NESTED(Trans2_ioctl);
+ outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
+ bufsize,&params,&data);
+ END_PROFILE_NESTED(Trans2_ioctl);
+ break;
default:
/* Error in request */
DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));