extern int DEBUGLEVEL;
extern int max_send;
-extern files_struct Files[];
-extern connection_struct Connections[];
extern fstring local_machine;
extern fstring global_myworkgroup;
#define NERR_BufTooSmall (NERR_BASE+23)
#define NERR_JobNotFound (NERR_BASE+51)
#define NERR_DestNotFound (NERR_BASE+52)
-#define ERROR_INVALID_LEVEL 124
#define ACCESS_READ 0x01
#define ACCESS_WRITE 0x02
#define SNLEN 15 /* service name length */
#define QNLEN 12 /* queue name maximum length */
-extern int Client;
-extern int oplock_sock;
extern int smb_read_error;
-static BOOL api_Unsupported(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len);
-static BOOL api_TooSmall(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len);
-static int CopyExpanded(int cnum, int snum, char** dst, char* src, int* n)
+static int CopyExpanded(connection_struct *conn,
+ int snum, char** dst, char* src, int* n)
{
- pstring buf;
- int l;
+ pstring buf;
+ int l;
- if (!src || !dst || !n || !(*dst)) return(0);
+ if (!src || !dst || !n || !(*dst)) return(0);
- StrnCpy(buf,src,sizeof(buf)/2);
- string_sub(buf,"%S",lp_servicename(snum));
- standard_sub(cnum,buf);
- StrnCpy(*dst,buf,*n);
- l = strlen(*dst) + 1;
- (*dst) += l;
- (*n) -= l;
- return l;
+ StrnCpy(buf,src,sizeof(buf)/2);
+ pstring_sub(buf,"%S",lp_servicename(snum));
+ standard_sub(conn,buf);
+ StrnCpy(*dst,buf,*n);
+ l = strlen(*dst) + 1;
+ (*dst) += l;
+ (*n) -= l;
+ return l;
}
static int CopyAndAdvance(char** dst, char* src, int* n)
{
int l;
if (!src || !dst || !n || !(*dst)) return(0);
- StrnCpy(*dst,src,*n);
+ StrnCpy(*dst,src,*n-1);
l = strlen(*dst) + 1;
(*dst) += l;
(*n) -= l;
return l;
}
-static int StrlenExpanded(int cnum, int snum, char* s)
+static int StrlenExpanded(connection_struct *conn, int snum, char* s)
{
- pstring buf;
- if (!s) return(0);
- StrnCpy(buf,s,sizeof(buf)/2);
- string_sub(buf,"%S",lp_servicename(snum));
- standard_sub(cnum,buf);
- return strlen(buf) + 1;
+ pstring buf;
+ if (!s) return(0);
+ StrnCpy(buf,s,sizeof(buf)/2);
+ pstring_sub(buf,"%S",lp_servicename(snum));
+ standard_sub(conn,buf);
+ return strlen(buf) + 1;
}
-static char* Expand(int cnum, int snum, char* s)
+static char* Expand(connection_struct *conn, int snum, char* s)
{
- static pstring buf;
- if (!s) return(NULL);
- StrnCpy(buf,s,sizeof(buf)/2);
- string_sub(buf,"%S",lp_servicename(snum));
- standard_sub(cnum,buf);
- return &buf[0];
+ static pstring buf;
+ if (!s) return(NULL);
+ StrnCpy(buf,s,sizeof(buf)/2);
+ pstring_sub(buf,"%S",lp_servicename(snum));
+ standard_sub(conn,buf);
+ return &buf[0];
}
/*******************************************************************
cause of some of the ipc problems being experienced. lkcl26dec97
******************************************************************/
+
static void copy_trans_params_and_data(char *outbuf, int align,
- struct mem_buf *rparam, struct mem_buf *rdata,
- int param_offset, int data_offset,
- int param_len, int data_len)
+ char *rparam, int param_offset, int param_len,
+ char *rdata, int data_offset, int data_len)
{
- char *copy_into = smb_buf(outbuf);
+ char *copy_into = smb_buf(outbuf)+1;
+
+ if(param_len < 0)
+ param_len = 0;
+
+ if(data_len < 0)
+ data_len = 0;
DEBUG(5,("copy_trans_params_and_data: params[%d..%d] data[%d..%d]\n",
param_offset, param_offset + param_len,
data_offset , data_offset + data_len));
- if (param_len) mem_buf_copy(copy_into, rparam, param_offset, param_len);
+ if (param_len)
+ memcpy(copy_into, &rparam[param_offset], param_len);
+
copy_into += param_len + align;
- if (data_len ) mem_buf_copy(copy_into, rdata , data_offset , data_len);
+
+ if (data_len )
+ memcpy(copy_into, &rdata[data_offset], data_len);
}
/****************************************************************************
- send a trans reply
- ****************************************************************************/
+ Send a trans reply.
+ ****************************************************************************/
+
static void send_trans_reply(char *outbuf,
- struct mem_buf *rdata,
- struct mem_buf *rparam,
- uint16 *setup, int lsetup, int max_data_ret)
+ char *rparam, int rparam_len,
+ char *rdata, int rdata_len,
+ BOOL buffer_too_large)
{
- int i;
int this_ldata,this_lparam;
- int tot_data=0,tot_param=0;
+ int tot_data_sent = 0;
+ int tot_param_sent = 0;
int align;
- int ldata = rdata ? mem_buf_len(rdata ) : 0;
- int lparam = rparam ? mem_buf_len(rparam) : 0;
-
- BOOL buffer_too_large = max_data_ret ? ldata > max_data_ret : False;
+ int ldata = rdata ? rdata_len : 0;
+ int lparam = rparam ? rparam_len : 0;
if (buffer_too_large)
- {
- DEBUG(5,("send_trans_reply: buffer %d too large %d\n", ldata, max_data_ret));
- ldata = max_data_ret;
- }
+ DEBUG(5,("send_trans_reply: buffer %d too large\n", ldata ));
- this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */
- this_ldata = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam));
+ this_lparam = MIN(lparam,max_send - 500); /* hack */
+ this_ldata = MIN(ldata,max_send - (500+this_lparam));
-#ifdef CONFUSE_NETMONITOR_MSRPC_DECODING
- /* if you don't want Net Monitor to decode your packets, do this!!! */
- align = ((this_lparam+1)%4);
-#else
- align = (this_lparam%4);
-#endif
+ align = ((this_lparam)%4);
- set_message(outbuf,10+lsetup,align+this_ldata+this_lparam,True);
+ set_message(outbuf,10,1+align+this_ldata+this_lparam,True);
if (buffer_too_large)
{
}
copy_trans_params_and_data(outbuf, align,
- rparam , rdata,
- tot_param , tot_data,
- this_lparam, this_ldata);
+ rparam, tot_param_sent, this_lparam,
+ rdata, tot_data_sent, this_ldata);
SSVAL(outbuf,smb_vwv0,lparam);
SSVAL(outbuf,smb_vwv1,ldata);
SSVAL(outbuf,smb_vwv3,this_lparam);
- SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf));
+ SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf));
SSVAL(outbuf,smb_vwv5,0);
SSVAL(outbuf,smb_vwv6,this_ldata);
- SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf));
+ SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align,outbuf));
SSVAL(outbuf,smb_vwv8,0);
- SSVAL(outbuf,smb_vwv9,lsetup);
-
- for (i=0;i<lsetup;i++)
- {
- SSVAL(outbuf,smb_vwv10+i*SIZEOFWORD,setup[i]);
- }
+ SSVAL(outbuf,smb_vwv9,0);
show_msg(outbuf);
- send_smb(Client,outbuf);
+ send_smb(smbd_server_fd(),outbuf);
- tot_data = this_ldata;
- tot_param = this_lparam;
+ tot_data_sent = this_ldata;
+ tot_param_sent = this_lparam;
- while (tot_data < ldata || tot_param < lparam)
+ while (tot_data_sent < ldata || tot_param_sent < lparam)
{
- this_lparam = MIN(lparam-tot_param, max_send - 500); /* hack */
- this_ldata = MIN(ldata -tot_data , max_send - (500+this_lparam));
+ this_lparam = MIN(lparam-tot_param_sent, max_send - 500); /* hack */
+ this_ldata = MIN(ldata -tot_data_sent, max_send - (500+this_lparam));
+
+ if(this_lparam < 0)
+ this_lparam = 0;
+
+ if(this_ldata < 0)
+ this_ldata = 0;
align = (this_lparam%4);
- set_message(outbuf,10,this_ldata+this_lparam+align,False);
+ set_message(outbuf,10,1+this_ldata+this_lparam+align,False);
copy_trans_params_and_data(outbuf, align,
- rparam , rdata,
- tot_param , tot_data,
- this_lparam, this_ldata);
+ rparam, tot_param_sent, this_lparam,
+ rdata, tot_data_sent, this_ldata);
SSVAL(outbuf,smb_vwv3,this_lparam);
- SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf));
- SSVAL(outbuf,smb_vwv5,tot_param);
+ SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf));
+ SSVAL(outbuf,smb_vwv5,tot_param_sent);
SSVAL(outbuf,smb_vwv6,this_ldata);
- SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf));
- SSVAL(outbuf,smb_vwv8,tot_data);
+ SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align,outbuf));
+ SSVAL(outbuf,smb_vwv8,tot_data_sent);
SSVAL(outbuf,smb_vwv9,0);
show_msg(outbuf);
- send_smb(Client,outbuf);
+ send_smb(smbd_server_fd(),outbuf);
- tot_data += this_ldata;
- tot_param += this_lparam;
+ tot_data_sent += this_ldata;
+ tot_param_sent += this_lparam;
}
}
{
int i, n;
if (!p || !(*p)) return(1);
- if (!isdigit(**p)) return 1;
+ if (!isdigit((int)**p)) return 1;
for (n = 0;;) {
i = **p;
if (isdigit(i))
case 'W': /* word (2 byte) */
n += 2;
break;
+ case 'K': /* status word? (2 byte) */
+ n += 2;
+ break;
case 'N': /* count of substructures (word) at end */
n += 2;
break;
}
#if CHECK_TYPES
str = va_arg(args,char*);
- if (strncmp(str,p->curpos,strlen(str)) != 0) {
- DEBUG(2,("type error in package: %s instead of %*s\n",str,
- strlen(str),p->curpos));
- va_end(args);
-#if AJT
- ajt_panic();
-#endif
- return 0;
- }
+ SMB_ASSERT(strncmp(str,p->curpos,strlen(str)) == 0);
#endif
stringneeded = -1;
- if (!p->curpos) return(0);
+ if (!p->curpos) {
+ va_end(args);
+ return(0);
+ }
switch( *p->curpos++ ) {
case 'W': /* word (2 byte) */
temp = va_arg(args,int);
if (p->buflen >= needed) SSVAL(p->structbuf,0,temp);
break;
+ case 'K': /* status word? (2 byte) */
+ needed = 2;
+ temp = va_arg(args,int);
+ if (p->buflen >= needed) SSVAL(p->structbuf,0,temp);
+ break;
case 'N': /* count of substructures (word) at end */
needed = 2;
p->subcount = va_arg(args,int);
needed = get_counter(&p->curpos);
{
char *s = va_arg(args,char*);
- if (p->buflen >= needed) StrnCpy(p->structbuf,s?s:"",needed);
+ if (p->buflen >= needed) StrnCpy(p->structbuf,s?s:"",needed-1);
}
break;
case 'z': /* offset to zero terminated string (4 byte) */
/****************************************************************************
get a print queue
****************************************************************************/
-
static void PackDriverData(struct pack_desc* desc)
{
char drivdata[4+4+32];
case 5:
desc->format = "z";
break;
+ case 51:
+ desc->format = "K";
+ break;
case 52:
desc->format = "WzzzzzzzzN";
desc->subformat = "z";
return True;
}
-static void fill_printjob_info(int cnum, int snum, int uLevel,
+
+#define JOB_STATUS_QUEUED 0
+#define JOB_STATUS_PAUSED 1
+#define JOB_STATUS_SPOOLING 2
+#define JOB_STATUS_PRINTING 3
+#define JOB_STATUS_PRINTED 4
+
+#define QUEUE_STATUS_PAUSED 1
+#define QUEUE_STATUS_ERROR 2
+
+/* turn a print job status into a on the wire status
+ right now these are complete guesses - need to fill them in (tridge)
+*/
+static int printj_status(int v)
+{
+ switch (v) {
+ case LPQ_QUEUED:
+ return JOB_STATUS_QUEUED;
+ case LPQ_PAUSED:
+ return JOB_STATUS_PAUSED;
+ case LPQ_SPOOLING:
+ return JOB_STATUS_SPOOLING;
+ case LPQ_PRINTING:
+ return JOB_STATUS_PRINTING;
+ }
+ return 0;
+}
+
+/* turn a print queue status into a on the wire status
+ right now these are complete guesses - need to fill them in (tridge)
+*/
+static int printq_status(int v)
+{
+ switch (v) {
+ case LPQ_QUEUED:
+ return 0;
+ case LPQ_PAUSED:
+ return QUEUE_STATUS_PAUSED;
+ }
+ return 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)
{
/* the client expects localtime */
t -= TimeDiff(t);
- PACKI(desc,"W",printjob_encode(snum, queue->job)); /* uJobId */
+ PACKI(desc,"W",queue->job); /* uJobId */
if (uLevel == 1) {
PACKS(desc,"B21",queue->user); /* szUserName */
PACKS(desc,"B",""); /* pad */
PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */
PACKS(desc,"z",""); /* pszParms */
PACKI(desc,"W",n+1); /* uPosition */
- PACKI(desc,"W",queue->status); /* fsStatus */
+ PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */
PACKS(desc,"z",""); /* pszStatus */
PACKI(desc,"D",t); /* ulSubmitted */
PACKI(desc,"D",queue->size); /* ulSize */
PACKI(desc,"W",queue->priority); /* uPriority */
PACKS(desc,"z",queue->user); /* pszUserName */
PACKI(desc,"W",n+1); /* uPosition */
- PACKI(desc,"W",queue->status); /* fsStatus */
+ PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */
PACKI(desc,"D",t); /* ulSubmitted */
PACKI(desc,"D",queue->size); /* ulSize */
PACKS(desc,"z","Samba"); /* pszComment */
}
}
-static void fill_printq_info(int cnum, int snum, int uLevel,
- struct pack_desc* desc,
- int count, print_queue_struct* queue,
- print_status_struct* status)
-{
- switch (uLevel) {
- case 1:
- case 2:
- PACKS(desc,"B13",SERVICE(snum));
- break;
- case 3:
- case 4:
- case 5:
- PACKS(desc,"z",Expand(cnum,snum,SERVICE(snum)));
- break;
- }
- if (uLevel == 1 || uLevel == 2) {
- PACKS(desc,"B",""); /* alignment */
- PACKI(desc,"W",5); /* priority */
- PACKI(desc,"W",0); /* start time */
- PACKI(desc,"W",0); /* until time */
- PACKS(desc,"z",""); /* pSepFile */
- PACKS(desc,"z","lpd"); /* pPrProc */
- PACKS(desc,"z",SERVICE(snum)); /* pDestinations */
- PACKS(desc,"z",""); /* pParms */
- if (snum < 0) {
- PACKS(desc,"z","UNKNOWN PRINTER");
- PACKI(desc,"W",LPSTAT_ERROR);
- }
- else if (!status || !status->message[0]) {
- PACKS(desc,"z",Expand(cnum,snum,lp_comment(snum)));
- PACKI(desc,"W",LPSTAT_OK); /* status */
- } else {
- PACKS(desc,"z",status->message);
- PACKI(desc,"W",status->status); /* status */
- }
- PACKI(desc,(uLevel == 1 ? "W" : "N"),count);
- }
- if (uLevel == 3 || uLevel == 4) {
- PACKI(desc,"W",5); /* uPriority */
- PACKI(desc,"W",0); /* uStarttime */
- PACKI(desc,"W",0); /* uUntiltime */
- PACKI(desc,"W",5); /* pad1 */
- PACKS(desc,"z",""); /* pszSepFile */
- PACKS(desc,"z","WinPrint"); /* pszPrProc */
- PACKS(desc,"z",""); /* pszParms */
- if (!status || !status->message[0]) {
- PACKS(desc,"z",Expand(cnum,snum,lp_comment(snum))); /* pszComment */
- PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
- } else {
- PACKS(desc,"z",status->message); /* pszComment */
- PACKI(desc,"W",status->status); /* fsStatus */
- }
- PACKI(desc,(uLevel == 3 ? "W" : "N"),count); /* cJobs */
- PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */
- PACKS(desc,"z",lp_printerdriver(snum)); /* pszDriverName */
- PackDriverData(desc); /* pDriverData */
- }
- if (uLevel == 2 || uLevel == 4) {
- int i;
- for (i=0;i<count;i++)
- fill_printjob_info(cnum,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
- }
+static void fill_printq_info_52(connection_struct *conn, int snum, int uLevel,
+ struct pack_desc* desc,
+ int count, print_queue_struct* queue,
+ print_status_struct* status)
+{
+ int i,ok=0;
+ pstring tok,driver,datafile,langmon,helpfile,datatype;
+ char *p,*q;
+ FILE *f;
+ pstring fname;
+
+ pstrcpy(fname,lp_driverfile());
+ f=sys_fopen(fname,"r");
+ if (!f) {
+ DEBUG(3,("fill_printq_info: Can't open %s - %s\n",fname,strerror(errno)));
+ desc->errcode=NERR_notsupported;
+ return;
+ }
+
+ if((p=(char *)malloc(8192*sizeof(char))) == NULL) {
+ DEBUG(0,("fill_printq_info: malloc fail !\n"));
+ desc->errcode=NERR_notsupported;
+ fclose(f);
+ return;
+ }
- if (uLevel==52) {
- int i,ok=0;
- pstring tok,driver,datafile,langmon,helpfile,datatype;
- char *p,*q;
- FILE *f;
- pstring fname;
-
- pstrcpy(fname,lp_driverfile());
- f=fopen(fname,"r");
- if (!f) {
- DEBUG(3,("fill_printq_info: Can't open %s - %s\n",fname,strerror(errno)));
- desc->errcode=NERR_notsupported;
- return;
- }
+ memset(p, '\0',8192*sizeof(char));
+ q=p;
+
+ /* lookup the long printer driver name in the file
+ description */
+ while (f && !feof(f) && !ok) {
+ p = q; /* reset string pointer */
+ fgets(p,8191,f);
+ p[strlen(p)-1]='\0';
+ if (next_token(&p,tok,":",sizeof(tok)) &&
+ (strlen(lp_printerdriver(snum)) == strlen(tok)) &&
+ (!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
+ ok=1;
+ }
+ fclose(f);
+
+ /* driver file name */
+ if (ok && !next_token(&p,driver,":",sizeof(driver))) ok = 0;
+ /* data file name */
+ if (ok && !next_token(&p,datafile,":",sizeof(datafile))) ok = 0;
+ /*
+ * for the next tokens - which may be empty - I have
+ * to check for empty tokens first because the
+ * next_token function will skip all empty token
+ * fields */
+ if (ok) {
+ /* help file */
+ if (*p == ':') {
+ *helpfile = '\0';
+ p++;
+ } else if (!next_token(&p,helpfile,":",sizeof(helpfile))) ok = 0;
+ }
+
+ if (ok) {
+ /* language monitor */
+ if (*p == ':') {
+ *langmon = '\0';
+ p++;
+ } else if (!next_token(&p,langmon,":",sizeof(langmon)))
+ ok = 0;
+ }
+
+ /* default data type */
+ if (ok && !next_token(&p,datatype,":",sizeof(datatype)))
+ ok = 0;
+
+ if (ok) {
+ PACKI(desc,"W",0x0400); /* don't know */
+ PACKS(desc,"z",lp_printerdriver(snum)); /* long printer name */
+ PACKS(desc,"z",driver); /* Driverfile Name */
+ PACKS(desc,"z",datafile); /* Datafile name */
+ PACKS(desc,"z",langmon); /* language monitor */
+ PACKS(desc,"z",lp_driverlocation(snum)); /* share to retrieve files */
+ PACKS(desc,"z",datatype); /* default data type */
+ PACKS(desc,"z",helpfile); /* helpfile name */
+ PACKS(desc,"z",driver); /* driver name */
+ DEBUG(3,("Driver:%s:\n",driver));
+ DEBUG(3,("Data File:%s:\n",datafile));
+ DEBUG(3,("Language Monitor:%s:\n",langmon));
+ DEBUG(3,("Data Type:%s:\n",datatype));
+ DEBUG(3,("Help File:%s:\n",helpfile));
+ PACKI(desc,"N",count); /* number of files to copy */
+ for (i=0;i<count;i++) {
+ /* no need to check return value here
+ * - it was already tested in
+ * get_printerdrivernumber */
+ next_token(&p,tok,",",sizeof(tok));
+ PACKS(desc,"z",tok); /* driver files to copy */
+ DEBUG(3,("file:%s:\n",tok));
+ }
+
+ DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",
+ SERVICE(snum),count));
+ } else {
+ DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
+ desc->errcode=NERR_notsupported;
+ }
+ free(q);
+}
- p=(char *)malloc(8192*sizeof(char));
- bzero(p, 8192*sizeof(char));
- q=p;
- /* lookup the long printer driver name in the file description */
- while (f && !feof(f) && !ok)
- {
- p = q; /* reset string pointer */
- fgets(p,8191,f);
- p[strlen(p)-1]='\0';
- if (next_token(&p,tok,":") &&
- (strlen(lp_printerdriver(snum)) == strlen(tok)) &&
- (!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
- ok=1;
- }
- fclose(f);
+static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
+ struct pack_desc* desc,
+ int count, print_queue_struct* queue,
+ print_status_struct* status)
+{
+ switch (uLevel) {
+ case 1:
+ case 2:
+ PACKS(desc,"B13",SERVICE(snum));
+ break;
+ case 3:
+ case 4:
+ case 5:
+ PACKS(desc,"z",Expand(conn,snum,SERVICE(snum)));
+ break;
+ case 51:
+ PACKI(desc,"K",printq_status(status->status));
+ break;
+ }
- /* driver file name */
- if (ok && !next_token(&p,driver,":")) ok = 0;
- /* data file name */
- if (ok && !next_token(&p,datafile,":")) ok = 0;
- /*
- * for the next tokens - which may be empty - I have to check for empty
- * tokens first because the next_token function will skip all empty
- * token fields
- */
- if (ok) {
- /* help file */
- if (*p == ':') {
- *helpfile = '\0';
- p++;
- } else if (!next_token(&p,helpfile,":")) ok = 0;
- }
+ if (uLevel == 1 || uLevel == 2) {
+ PACKS(desc,"B",""); /* alignment */
+ PACKI(desc,"W",5); /* priority */
+ PACKI(desc,"W",0); /* start time */
+ PACKI(desc,"W",0); /* until time */
+ PACKS(desc,"z",""); /* pSepFile */
+ PACKS(desc,"z","lpd"); /* pPrProc */
+ PACKS(desc,"z",SERVICE(snum)); /* pDestinations */
+ PACKS(desc,"z",""); /* pParms */
+ if (snum < 0) {
+ 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 */
+ }
+ PACKI(desc,(uLevel == 1 ? "W" : "N"),count);
+ }
- if (ok) {
- /* language monitor */
- if (*p == ':') {
- *langmon = '\0';
- p++;
- } else if (!next_token(&p,langmon,":")) ok = 0;
- }
+ if (uLevel == 3 || uLevel == 4) {
+ PACKI(desc,"W",5); /* uPriority */
+ PACKI(desc,"W",0); /* uStarttime */
+ PACKI(desc,"W",0); /* uUntiltime */
+ PACKI(desc,"W",5); /* pad1 */
+ PACKS(desc,"z",""); /* pszSepFile */
+ PACKS(desc,"z","WinPrint"); /* pszPrProc */
+ PACKS(desc,"z",""); /* pszParms */
+ if (!status || !status->message[0]) {
+ PACKS(desc,"z",Expand(conn,snum,lp_comment(snum))); /* pszComment */
+ PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
+ } else {
+ PACKS(desc,"z",status->message); /* pszComment */
+ PACKI(desc,"W",printq_status(status->status)); /* fsStatus */
+ }
+ PACKI(desc,(uLevel == 3 ? "W" : "N"),count); /* cJobs */
+ PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */
+ PACKS(desc,"z",lp_printerdriver(snum)); /* pszDriverName */
+ PackDriverData(desc); /* pDriverData */
+ }
- /* default data type */
- if (ok && !next_token(&p,datatype,":")) ok = 0;
-
- if (ok) {
- PACKI(desc,"W",0x0400); /* don't know */
- PACKS(desc,"z",lp_printerdriver(snum)); /* long printer name */
- PACKS(desc,"z",driver); /* Driverfile Name */
- PACKS(desc,"z",datafile); /* Datafile name */
- PACKS(desc,"z",langmon); /* language monitor */
- PACKS(desc,"z",lp_driverlocation(snum)); /* share to retrieve files */
- PACKS(desc,"z",datatype); /* default data type */
- PACKS(desc,"z",helpfile); /* helpfile name */
- PACKS(desc,"z",driver); /* driver name */
- DEBUG(3,("Driver:%s:\n",driver));
- DEBUG(3,("Data File:%s:\n",datafile));
- DEBUG(3,("Language Monitor:%s:\n",langmon));
- DEBUG(3,("Data Type:%s:\n",datatype));
- DEBUG(3,("Help File:%s:\n",helpfile));
- PACKI(desc,"N",count); /* number of files to copy */
- for (i=0;i<count;i++)
- {
- /* no need to check return value here - it was already tested in
- * get_printerdrivernumber
- */
- next_token(&p,tok,",");
- PACKS(desc,"z",tok); /* driver files to copy */
- DEBUG(3,("file:%s:\n",tok));
- }
+ 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);
+ }
- DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",
- SERVICE(snum),count));
- } else {
- DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
- desc->errcode=NERR_notsupported;
- }
- free(q);
- }
+ if (uLevel==52) {
+ fill_printq_info_52(conn, snum, uLevel, desc, count, queue, status);
+ }
}
/* This function returns the number of files for a given driver */
-int get_printerdrivernumber(int snum)
+static int get_printerdrivernumber(int snum)
{
int i=0,ok=0;
pstring tok;
pstrcpy(fname,lp_driverfile());
DEBUG(4,("In get_printerdrivernumber: %s\n",fname));
- f=fopen(fname,"r");
+ f=sys_fopen(fname,"r");
if (!f) {
DEBUG(3,("get_printerdrivernumber: Can't open %s - %s\n",fname,strerror(errno)));
return(0);
}
- p=(char *)malloc(8192*sizeof(char));
+ if((p=(char *)malloc(8192*sizeof(char))) == NULL) {
+ DEBUG(3,("get_printerdrivernumber: malloc fail !\n"));
+ fclose(f);
+ return 0;
+ }
+
q=p; /* need it to free memory because p change ! */
/* lookup the long printer driver name in the file description */
{
p = q; /* reset string pointer */
fgets(p,8191,f);
- if (next_token(&p,tok,":") &&
+ if (next_token(&p,tok,":",sizeof(tok)) &&
(!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
ok=1;
}
return(0);
/* count the number of files */
- while (next_token(&p,tok,","))
+ while (next_token(&p,tok,",",sizeof(tok)))
i++;
}
free(q);
return(i);
}
-static BOOL api_DosPrintQGetInfo(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_DosPrintQGetInfo(connection_struct *conn,
+ uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
char *QueueName = p;
- int uLevel,cbBuf;
+ int uLevel;
int count=0;
int snum;
char* str3;
print_queue_struct *queue=NULL;
print_status_struct status;
- bzero(&status,sizeof(status));
- bzero(&desc,sizeof(desc));
+ memset((char *)&status,'\0',sizeof(status));
+ memset((char *)&desc,'\0',sizeof(desc));
p = skip_string(p,1);
uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
str3 = p + 4;
/* remove any trailing username */
/* check it's a supported varient */
if (!prefix_ok(str1,"zWrLh")) return False;
- if (!check_printq_info(&desc,uLevel,str2,str3)) 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)) {
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));
+ 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);
}
- else
- count = get_printqueue(snum,cnum,&queue,&status);
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
desc.base = *rdata;
desc.buflen = mdrcnt;
if (init_package(&desc,1,count)) {
- desc.subcount = count;
- fill_printq_info(cnum,snum,uLevel,&desc,count,queue,&status);
+ desc.subcount = count;
+ fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status);
+ } else if(uLevel == 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();
}
*rdata_len = desc.usedlen;
/****************************************************************************
view list of all print jobs on all queues
****************************************************************************/
-static BOOL api_DosPrintQEnum(int cnum, uint16 vuid, char* param, char* data,
+static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param, char* data,
int mdrcnt, int mprcnt,
char **rdata, char** rparam,
int *rdata_len, int *rparam_len)
int* subcntarr = NULL;
int queuecnt, subcnt=0, succnt=0;
- bzero(&desc,sizeof(desc));
+ memset((char *)&desc,'\0',sizeof(desc));
DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
if (!prefix_ok(param_format,"WrLeh")) return False;
- if (!check_printq_info(&desc,uLevel,output_format1,output_format2))
- return False;
+ if (!check_printq_info(&desc,uLevel,output_format1,output_format2)) {
+ /*
+ * 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);
+ }
+
queuecnt = 0;
for (i = 0; i < services; i++)
if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
queuecnt++;
if (uLevel > 0) {
- queue = (print_queue_struct**)malloc(queuecnt*sizeof(print_queue_struct*));
+ if((queue = (print_queue_struct**)malloc(queuecnt*sizeof(print_queue_struct*))) == NULL) {
+ DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
+ return False;
+ }
memset(queue,0,queuecnt*sizeof(print_queue_struct*));
- status = (print_status_struct*)malloc(queuecnt*sizeof(print_status_struct));
+ if((status = (print_status_struct*)malloc(queuecnt*sizeof(print_status_struct))) == NULL) {
+ DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
+ return False;
+ }
memset(status,0,queuecnt*sizeof(print_status_struct));
- subcntarr = (int*)malloc(queuecnt*sizeof(int));
+ if((subcntarr = (int*)malloc(queuecnt*sizeof(int))) == NULL) {
+ DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
+ return False;
+ }
subcnt = 0;
n = 0;
for (i = 0; i < services; i++)
if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- subcntarr[n] = get_printqueue(i,cnum,&queue[n],&status[n]);
+ subcntarr[n] = print_queue_status(i, &queue[n],&status[n]);
subcnt += subcntarr[n];
n++;
}
succnt = 0;
for (i = 0; i < services; i++)
if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- fill_printq_info(cnum,i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
+ fill_printq_info(conn,i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
n++;
if (desc.errcode == NERR_Success) succnt = n;
}
pstrcat(fname,"/");
pstrcat(fname,SERVER_LIST);
- f = fopen(fname,"r");
+ f = sys_fopen(fname,"r");
if (!f) {
DEBUG(4,("Can't open %s - %s\n",fname,strerror(errno)));
(*servers) = (struct srv_info_struct *)
Realloc(*servers,sizeof(**servers)*alloced);
if (!(*servers)) return(0);
- bzero((char *)((*servers)+count),sizeof(**servers)*(alloced-count));
+ memset((char *)((*servers)+count),'\0',sizeof(**servers)*(alloced-count));
}
s = &(*servers)[count];
- if (!next_token(&ptr,s->name , NULL)) continue;
- if (!next_token(&ptr,stype , NULL)) continue;
- if (!next_token(&ptr,s->comment, NULL)) continue;
- if (!next_token(&ptr,s->domain , NULL)) {
+ if (!next_token(&ptr,s->name , NULL, sizeof(s->name))) continue;
+ if (!next_token(&ptr,stype , NULL, sizeof(stype))) continue;
+ if (!next_token(&ptr,s->comment, NULL, sizeof(s->comment))) continue;
+ if (!next_token(&ptr,s->domain , NULL, sizeof(s->domain))) {
/* this allows us to cope with an old nmbd */
pstrcpy(s->domain,global_myworkgroup);
}
view list of servers available (or possibly domains). The info is
extracted from lists saved by nmbd on the local host
****************************************************************************/
-static BOOL api_RNetServerEnum(int cnum, uint16 vuid, char *param, char *data,
+static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param, char *data,
int mdrcnt, int mprcnt, char **rdata,
char **rparam, int *rdata_len, int *rparam_len)
{
*rdata_len = fixed_len + string_len;
*rdata = REALLOC(*rdata,*rdata_len);
- bzero(*rdata,*rdata_len);
+ memset(*rdata,'\0',*rdata_len);
p2 = (*rdata) + fixed_len; /* auxilliary data (strings) will go here */
p = *rdata;
/****************************************************************************
command 0x34 - suspected of being a "Lookup Names" stub api
****************************************************************************/
-static BOOL api_RNetGroupGetUsers(int cnum, uint16 vuid, char *param, char *data,
+static BOOL api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid, char *param, char *data,
int mdrcnt, int mprcnt, char **rdata,
char **rparam, int *rdata_len, int *rparam_len)
{
if (!prefix_ok(str1,"zWrLeh")) return False;
*rdata_len = 0;
- *rdata = NULL;
*rparam_len = 8;
*rparam = REALLOC(*rparam,*rparam_len);
return True;
}
-static int fill_share_info(int cnum, int snum, int uLevel,
+static int fill_share_info(connection_struct *conn, int snum, int uLevel,
char** buf, int* buflen,
char** stringbuf, int* stringspace, char* baseaddr)
{
if (!buf)
{
len = 0;
- if (uLevel > 0) len += StrlenExpanded(cnum,snum,lp_comment(snum));
+ if (uLevel > 0) len += StrlenExpanded(conn,snum,lp_comment(snum));
if (uLevel > 1) len += strlen(lp_pathname(snum)) + 1;
if (buflen) *buflen = struct_len;
if (stringspace) *stringspace = len;
if (strequal("IPC$",lp_servicename(snum))) type = STYPE_IPC;
SSVAL(p,14,type); /* device type */
SIVAL(p,16,PTR_DIFF(p2,baseaddr));
- len += CopyExpanded(cnum,snum,&p2,lp_comment(snum),&l2);
+ len += CopyExpanded(conn,snum,&p2,lp_comment(snum),&l2);
}
if (uLevel > 1)
return len;
}
-static BOOL api_RNetShareGetInfo(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
*rdata = REALLOC(*rdata,mdrcnt);
p = *rdata;
- *rdata_len = fill_share_info(cnum,snum,uLevel,&p,&mdrcnt,0,0,0);
+ *rdata_len = fill_share_info(conn,snum,uLevel,&p,&mdrcnt,0,0,0);
if (*rdata_len < 0) return False;
*rparam_len = 6;
/****************************************************************************
view list of shares available
****************************************************************************/
-static BOOL api_RNetShareEnum(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
if (lp_browseable(i) && lp_snum_ok(i))
{
total++;
- data_len += fill_share_info(cnum,i,uLevel,0,&f_len,0,&s_len,0);
+ data_len += fill_share_info(conn,i,uLevel,0,&f_len,0,&s_len,0);
if (data_len <= buf_len)
{
counted++;
s_len = string_len;
for (i = 0; i < count;i++)
if (lp_browseable(i) && lp_snum_ok(i))
- if (fill_share_info(cnum,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0)
+ if (fill_share_info(conn,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0)
break;
*rparam_len = 8;
/****************************************************************************
get the time of day info
****************************************************************************/
-static BOOL api_NetRemoteTOD(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
}
/****************************************************************************
- set the user password
- ****************************************************************************/
-static BOOL api_SetUserPassword(int cnum,uint16 vuid, char *param,char *data,
+ Set the user password.
+*****************************************************************************/
+
+static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
p = skip_string(p,1);
+ memset(pass1,'\0',sizeof(pass1));
+ memset(pass2,'\0',sizeof(pass2));
memcpy(pass1,p,16);
memcpy(pass2,p+16,16);
(void)Get_Pwnam( user, True);
/*
- * Attempt the plaintext password change first.
- * Older versions of Windows seem to do this.
+ * Attempt to verify the old password against smbpasswd entries
+ * Win98 clients send old and new password in plaintext for this call.
*/
- if (password_ok(user,pass1,strlen(pass1),NULL) &&
- chgpasswd(user,pass1,pass2,False))
{
- SSVAL(*rparam,0,NERR_Success);
+ fstring saved_pass2;
+ struct smb_passwd *smbpw = NULL;
+
+ /*
+ * Save the new password as change_oem_password overwrites it
+ * with zeros.
+ */
+
+ fstrcpy(saved_pass2, pass2);
+
+ if (check_plaintext_password(user,pass1,strlen(pass1),&smbpw) &&
+ change_oem_password(smbpw,pass2,False))
+ {
+ SSVAL(*rparam,0,NERR_Success);
+
+ /*
+ * If unix password sync was requested, attempt to change
+ * the /etc/passwd database also. Return failure if this cannot
+ * be done.
+ */
+
+ if(lp_unix_password_sync() && !chgpasswd(user,pass1,saved_pass2,False))
+ SSVAL(*rparam,0,NERR_badpass);
+ }
+ }
+
+ /*
+ * If the above failed, attempt the plaintext password change.
+ * This tests against the /etc/passwd database only.
+ */
+
+ if(SVAL(*rparam,0) != NERR_Success)
+ {
+ if (password_ok(user, pass1,strlen(pass1),NULL) &&
+ chgpasswd(user,pass1,pass2,False))
+ {
+ SSVAL(*rparam,0,NERR_Success);
+ }
}
/*
* If the plaintext change failed, attempt
- * the encrypted. NT will generate this
- * after trying the samr method.
+ * the old encrypted method. NT will generate this
+ * after trying the samr method. Note that this
+ * method is done as a last resort as this
+ * password change method loses the NT password hash
+ * and cannot change the UNIX password as no plaintext
+ * is received.
*/
if(SVAL(*rparam,0) != NERR_Success)
}
}
- bzero(pass1,sizeof(fstring));
- bzero(pass2,sizeof(fstring));
+ memset((char *)pass1,'\0',sizeof(fstring));
+ memset((char *)pass2,'\0',sizeof(fstring));
return(True);
}
Set the user password (SamOEM version - gets plaintext).
****************************************************************************/
-static BOOL api_SamOEMChangePassword(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
fstring user;
- fstring new_passwd;
- struct smb_passwd *sampw = NULL;
char *p = param + 2;
- int ret = True;
-
*rparam_len = 2;
*rparam = REALLOC(*rparam,*rparam_len);
* Check the parameter definition is correct.
*/
if(!strequal(param + 2, "zsT")) {
- DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %sn\n", param + 2));
+ DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", param + 2));
return False;
}
p = skip_string(p, 1);
if(!strequal(p, "B516B16")) {
- DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %sn\n", p));
+ DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
return False;
}
p = skip_string(p,1);
*/
(void)Get_Pwnam( user, True);
- if(check_oem_password( user, (unsigned char *)data, &sampw,
- new_passwd, (int)sizeof(new_passwd)) == False) {
- return True;
- }
-
- /*
- * At this point we have the new case-sensitive plaintext
- * password in the fstring new_passwd. If we wanted to synchronise
- * with UNIX passwords we would call a UNIX password changing
- * function here. However it would have to be done as root
- * as the plaintext of the old users password is not
- * available. JRA.
- */
-
- if(lp_unix_password_sync())
- ret = chgpasswd(user,"", new_passwd, True);
-
- if(ret && change_oem_password( sampw, new_passwd, False)) {
+ if (pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL))
+ {
SSVAL(*rparam,0,NERR_Success);
}
delete a print job
Form: <W> <>
****************************************************************************/
-static BOOL api_RDosPrintJobDel(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- int function = SVAL(param,0);
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int jobid, snum;
- int i, count;
-
- printjob_decode(SVAL(p,0), &snum, &jobid);
-
- /* check it's a supported varient */
- if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
- return(False);
-
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
+ int function = SVAL(param,0);
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int jobid, errcode;
- *rdata_len = 0;
+ jobid = SVAL(p,0);
- SSVAL(*rparam,0,NERR_Success);
+ /* check it's a supported varient */
+ if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
+ return(False);
- if (snum >= 0 && VALID_SNUM(snum))
- {
- print_queue_struct *queue=NULL;
- lpq_reset(snum);
- count = get_printqueue(snum,cnum,&queue,NULL);
-
- for (i=0;i<count;i++)
- if ((queue[i].job&0xFF) == jobid)
- {
- switch (function) {
- case 81: /* delete */
- DEBUG(3,("Deleting queue entry %d\n",queue[i].job));
- del_printqueue(cnum,snum,queue[i].job);
- break;
- case 82: /* pause */
- case 83: /* resume */
- DEBUG(3,("%s queue entry %d\n",
- (function==82?"pausing":"resuming"),queue[i].job));
- status_printjob(cnum,snum,queue[i].job,
- (function==82?LPQ_PAUSED:LPQ_QUEUED));
- break;
- }
- break;
- }
-
- if (i==count)
- SSVAL(*rparam,0,NERR_JobNotFound);
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ *rdata_len = 0;
- if (queue) free(queue);
- }
+ if (!print_job_exists(jobid)) {
+ errcode = NERR_JobNotFound;
+ goto out;
+ }
- SSVAL(*rparam,2,0); /* converter word */
+ errcode = NERR_notsupported;
+
+ switch (function) {
+ case 81: /* delete */
+ if (print_job_delete(jobid)) errcode = NERR_Success;
+ break;
+ case 82: /* pause */
+ if (print_job_pause(jobid)) errcode = NERR_Success;
+ break;
+ case 83: /* resume */
+ if (print_job_resume(jobid)) errcode = NERR_Success;
+ break;
+ }
+
+ out:
+ SSVAL(*rparam,0,errcode);
+ SSVAL(*rparam,2,0); /* converter word */
- return(True);
+ return(True);
}
/****************************************************************************
Purge a print queue - or pause or resume it.
****************************************************************************/
-static BOOL api_WPrintQueuePurge(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_WPrintQueuePurge(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- int function = SVAL(param,0);
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *QueueName = skip_string(str2,1);
- int snum;
+ int function = SVAL(param,0);
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *QueueName = skip_string(str2,1);
+ int errcode = NERR_notsupported;
+ int snum;
- /* check it's a supported varient */
- if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
- return(False);
+ /* check it's a supported varient */
+ if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
+ return(False);
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ *rdata_len = 0;
- *rdata_len = 0;
+ snum = print_queue_snum(QueueName);
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
+ if (snum == -1) {
+ errcode = NERR_JobNotFound;
+ goto out;
+ }
- 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);
- }
- }
+ switch (function) {
+ case 74: /* Pause queue */
+ if (print_queue_pause(snum)) errcode = NERR_Success;
+ break;
+ case 75: /* Resume queue */
+ if (print_queue_resume(snum)) errcode = NERR_Success;
+ break;
+ case 103: /* Purge */
+ if (print_queue_purge(snum)) errcode = NERR_Success;
+ break;
+ }
- if (snum >= 0 && VALID_SNUM(snum)) {
- lpq_reset(snum);
-
- switch (function) {
- case 74: /* Pause queue */
- case 75: /* Resume queue */
- status_printqueue(cnum,snum,(function==74?LPSTAT_STOPPED:LPSTAT_OK));
- DEBUG(3,("Print queue %s, queue=%s\n",
- (function==74?"pause":"resume"),QueueName));
- break;
- case 103: /* Purge */
- {
- print_queue_struct *queue=NULL;
- int i, count;
- count = get_printqueue(snum,cnum,&queue,NULL);
- for (i = 0; i < count; i++)
- del_printqueue(cnum,snum,queue[i].job);
-
- if (queue) free(queue);
- DEBUG(3,("Print queue purge, queue=%s\n",QueueName));
- break;
- }
- }
- }
+ out:
+ SSVAL(*rparam,0,errcode);
+ SSVAL(*rparam,2,0); /* converter word */
- return(True);
+ return(True);
}
static int check_printjob_info(struct pack_desc* desc,
int uLevel, char* id)
{
- desc->subformat = NULL;
- switch( uLevel ) {
- case 0: desc->format = "W"; break;
- case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
- case 2: desc->format = "WWzWWDDzz"; break;
- case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
- default: return False;
- }
- if (strcmp(desc->format,id) != 0) return False;
- return True;
+ desc->subformat = NULL;
+ switch( uLevel ) {
+ case 0: desc->format = "W"; break;
+ case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
+ case 2: desc->format = "WWzWWDDzz"; break;
+ case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
+ default: return False;
+ }
+ if (strcmp(desc->format,id) != 0) return False;
+ return True;
}
-static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data,
+static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- struct pack_desc desc;
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int jobid, snum;
- int uLevel = SVAL(p,2);
- int function = SVAL(p,4); /* what is this ?? */
- int i;
- char *s = data;
-
- printjob_decode(SVAL(p,0), &snum, &jobid);
-
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- /* check it's a supported varient */
- if ((strcmp(str1,"WWsTP")) || (!check_printjob_info(&desc,uLevel,str2)))
- return(False);
-
- switch (function) {
- case 0x6: /* change job place in the queue, data gives the new place */
- if (snum >= 0 && VALID_SNUM(snum))
- {
- print_queue_struct *queue=NULL;
- int count;
+ struct pack_desc desc;
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int jobid;
+ int uLevel = SVAL(p,2);
+ int function = SVAL(p,4);
+ int place, errcode;
+
+ jobid = SVAL(p,0);
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam,*rparam_len);
- lpq_reset(snum);
- count = get_printqueue(snum,cnum,&queue,NULL);
- for (i=0;i<count;i++) /* find job */
- if ((queue[i].job&0xFF) == jobid) break;
-
- if (i==count) {
- desc.errcode=NERR_JobNotFound;
- if (queue) free(queue);
- }
- else {
- desc.errcode=NERR_Success;
- i++;
-#if 0
- {
- int place= SVAL(data,0);
- /* we currently have no way of doing this. Can any unix do it? */
- if (i < place) /* move down */;
- else if (i > place ) /* move up */;
- }
-#endif
- desc.errcode=NERR_notsupported; /* not yet supported */
- if (queue) free(queue);
- }
- }
- else desc.errcode=NERR_JobNotFound;
- break;
- case 0xb: /* change print job name, data gives the name */
- /* jobid, snum should be zero */
- if (isalpha(*s))
- {
- pstring name;
- int l = 0;
- while (l<64 && *s)
- {
- if (issafe(*s)) name[l++] = *s;
- s++;
- }
- name[l] = 0;
+ *rdata_len = 0;
- DEBUG(3,("Setting print name to %s\n",name));
-
- become_root(True);
-
- for (i=0;i<MAX_FNUMS;i++)
- if (Files[i].open && Files[i].print_file)
- {
- pstring wd;
- int fcnum = Files[i].cnum;
- GetWd(wd);
- unbecome_user();
-
- if (!become_user(&Connections[fcnum], fcnum,vuid) ||
- !become_service(fcnum,True))
+ /* check it's a supported varient */
+ if ((strcmp(str1,"WWsTP")) ||
+ (!check_printjob_info(&desc,uLevel,str2)))
+ return(False);
+
+ if (!print_job_exists(jobid)) {
+ errcode=NERR_JobNotFound;
+ goto out;
+ }
+
+ errcode = NERR_notsupported;
+
+ switch (function) {
+ case 0x6:
+ /* change job place in the queue,
+ data gives the new place */
+ place = SVAL(data,0);
+ if (print_job_set_place(jobid, place)) {
+ errcode=NERR_Success;
+ }
break;
-
- if (sys_rename(Files[i].name,name) == 0)
- string_set(&Files[i].name,name);
- break;
- }
- unbecome_root(True);
- }
- desc.errcode=NERR_Success;
-
- break;
- default: /* not implemented */
- return False;
- }
-
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0); /* converter word */
-
- return(True);
+ case 0xb:
+ /* change print job name, data gives the name */
+ if (print_job_set_name(jobid, data)) {
+ errcode=NERR_Success;
+ }
+ break;
+
+ default:
+ return False;
+ }
+
+ out:
+ SSVALS(*rparam,0,errcode);
+ SSVAL(*rparam,2,0); /* converter word */
+
+ return(True);
}
/****************************************************************************
get info about the server
****************************************************************************/
-static BOOL api_RNetServerGetInfo(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
pstring comment;
uint32 servertype= lp_default_server_announce();
- pstrcpy(comment,lp_serverstring());
+ pstrcpy(comment,string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
if ((count=get_server_info(SV_TYPE_ALL,&servers,global_myworkgroup))>0) {
for (i=0;i<count;i++)
SIVAL(p,6,0);
} else {
SIVAL(p,6,PTR_DIFF(p2,*rdata));
- standard_sub(cnum,comment);
+ standard_sub(conn,comment);
StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
p2 = skip_string(p2,1);
}
/****************************************************************************
get info about the server
****************************************************************************/
-static BOOL api_NetWkstaGetInfo(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
#define AF_OP_ACCOUNTS 3
-static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
Don't depend on vuser being non-null !!. JRA */
user_struct *vuser = get_valid_user_struct(vuid);
if(vuser != NULL)
- DEBUG(3,(" Username of UID %d is %s\n", vuser->uid, vuser->name));
+ DEBUG(3,(" Username of UID %d is %s\n", (int)vuser->uid, vuser->name));
*rparam_len = 6;
*rparam = REALLOC(*rparam,*rparam_len);
if (uLevel == 11) /* modelled after NTAS 3.51 reply */
{
- SSVAL(p,usri11_priv,Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
+ SSVAL(p,usri11_priv,conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */
SIVALS(p,usri11_password_age,-1); /* password age */
SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
- pstrcpy(p2, lp_logon_path());
+ pstrcpy(p2, lp_logon_home());
p2 = skip_string(p2,1);
SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
pstrcpy(p2,"");
memset(p+22,' ',16); /* password */
SIVALS(p,38,-1); /* password age */
SSVAL(p,42,
- Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
+ conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
- pstrcpy(p2,lp_logon_path());
+ pstrcpy(p2,lp_logon_home());
p2 = skip_string(p2,1);
SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
*p2++ = 0;
SSVAL(p,52,0); /* flags */
- SIVAL(p,54,0); /* script_path */
+ SIVAL(p,54,PTR_DIFF(p2,*rdata)); /* script_path */
+ pstrcpy(p2,lp_logon_script());
+ standard_sub( conn, p2 );
+ p2 = skip_string(p2,1);
if (uLevel == 2)
{
SIVAL(p,60,0); /* auth_flags */
/*******************************************************************
get groups that a user is a member of
******************************************************************/
-static BOOL api_NetUserGetGroups(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
}
-static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
int uLevel;
struct pack_desc desc;
char* name;
- char* logon_script;
uLevel = SVAL(p,0);
name = p + 2;
- bzero(&desc,sizeof(desc));
+ memset((char *)&desc,'\0',sizeof(desc));
DEBUG(3,("WWkstaUserLogon uLevel=%d name=%s\n",uLevel,name));
PACKS(&desc,"B21",name); /* eff. name */
PACKS(&desc,"B",""); /* pad */
PACKI(&desc,"W",
- Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
+ conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
PACKI(&desc,"D",0); /* auth flags XXX */
PACKI(&desc,"W",0); /* num logons */
PACKI(&desc,"W",0); /* bad pw count */
/* JHT - By calling lp_logon_script() and standard_sub() we have */
/* made sure all macros are fully substituted and available */
- logon_script = lp_logon_script();
- standard_sub( cnum, logon_script );
- PACKS(&desc,"z", logon_script); /* script path */
+ {
+ pstring logon_script;
+ pstrcpy(logon_script,lp_logon_script());
+ standard_sub( conn, logon_script );
+ PACKS(&desc,"z", logon_script); /* script path */
+ }
/* End of JHT mods */
PACKI(&desc,"D",0x00000000); /* reserved */
/****************************************************************************
api_WAccessGetUserPerms
****************************************************************************/
-static BOOL api_WAccessGetUserPerms(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
/****************************************************************************
api_WPrintJobEnumerate
****************************************************************************/
-static BOOL api_WPrintJobGetInfo(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
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);
- int uLevel,cbBuf;
+ int uLevel;
int count;
int i;
int snum;
print_status_struct status;
uLevel = SVAL(p,2);
- cbBuf = SVAL(p,4);
- bzero(&desc,sizeof(desc));
- bzero(&status,sizeof(status));
+ memset((char *)&desc,'\0',sizeof(desc));
+ memset((char *)&status,'\0',sizeof(status));
DEBUG(3,("WPrintJobGetInfo uLevel=%d uJobId=0x%X\n",uLevel,SVAL(p,0)));
if (strcmp(str1,"WWrLh") != 0) return False;
if (!check_printjob_info(&desc,uLevel,str2)) return False;
- printjob_decode(SVAL(p,0), &snum, &job);
+ job = SVAL(p,0);
if (snum < 0 || !VALID_SNUM(snum)) return(False);
- count = get_printqueue(snum,cnum,&queue,&status);
+ count = print_queue_status(snum,&queue,&status);
for (i = 0; i < count; i++) {
- if ((queue[i].job & 0xFF) == job) break;
+ if (queue[i].job == job) break;
}
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
desc.base = *rdata;
if (init_package(&desc,1,0)) {
if (i < count) {
- fill_printjob_info(cnum,snum,uLevel,&desc,&queue[i],i);
+ fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
*rdata_len = desc.usedlen;
}
else {
return(True);
}
-static BOOL api_WPrintJobEnumerate(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
char* name = p;
- int uLevel,cbBuf;
+ int uLevel;
int count;
int i, succnt=0;
int snum;
print_queue_struct *queue=NULL;
print_status_struct status;
- bzero(&desc,sizeof(desc));
- bzero(&status,sizeof(status));
+ memset((char *)&desc,'\0',sizeof(desc));
+ memset((char *)&status,'\0',sizeof(status));
p = skip_string(p,1);
uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
if (snum < 0 || !VALID_SNUM(snum)) return(False);
- count = get_printqueue(snum,cnum,&queue,&status);
+ count = print_queue_status(snum,&queue,&status);
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
desc.base = *rdata;
desc.buflen = mdrcnt;
if (init_package(&desc,count,0)) {
succnt = 0;
for (i = 0; i < count; i++) {
- fill_printjob_info(cnum,snum,uLevel,&desc,&queue[i],i);
+ fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
if (desc.errcode == NERR_Success) succnt = i+1;
}
}
return True;
}
-static void fill_printdest_info(int cnum, int snum, int uLevel,
+static void fill_printdest_info(connection_struct *conn, int snum, int uLevel,
struct pack_desc* desc)
{
char buf[100];
}
}
-static BOOL api_WPrintDestGetInfo(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
char* PrinterName = p;
- int uLevel,cbBuf;
+ int uLevel;
struct pack_desc desc;
int snum;
- bzero(&desc,sizeof(desc));
+ memset((char *)&desc,'\0',sizeof(desc));
p = skip_string(p,1);
uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
DEBUG(3,("WPrintDestGetInfo uLevel=%d PrinterName=%s\n",uLevel,PrinterName));
desc.base = *rdata;
desc.buflen = mdrcnt;
if (init_package(&desc,1,0)) {
- fill_printdest_info(cnum,snum,uLevel,&desc);
+ fill_printdest_info(conn,snum,uLevel,&desc);
}
*rdata_len = desc.usedlen;
}
return(True);
}
-static BOOL api_WPrintDestEnum(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_WPrintDestEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
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);
- int uLevel,cbBuf;
+ int uLevel;
int queuecnt;
int i, n, succnt=0;
struct pack_desc desc;
int services = lp_numservices();
- bzero(&desc,sizeof(desc));
+ memset((char *)&desc,'\0',sizeof(desc));
uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
DEBUG(3,("WPrintDestEnum uLevel=%d\n",uLevel));
n = 0;
for (i = 0; i < services; i++) {
if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- fill_printdest_info(cnum,i,uLevel,&desc);
+ fill_printdest_info(conn,i,uLevel,&desc);
n++;
if (desc.errcode == NERR_Success) succnt = n;
}
return(True);
}
-static BOOL api_WPrintDriverEnum(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_WPrintDriverEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
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);
- int uLevel,cbBuf;
+ int uLevel;
int succnt;
struct pack_desc desc;
- bzero(&desc,sizeof(desc));
+ memset((char *)&desc,'\0',sizeof(desc));
uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
DEBUG(3,("WPrintDriverEnum uLevel=%d\n",uLevel));
return(True);
}
-static BOOL api_WPrintQProcEnum(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_WPrintQProcEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
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);
- int uLevel,cbBuf;
+ int uLevel;
int succnt;
struct pack_desc desc;
- bzero(&desc,sizeof(desc));
+ memset((char *)&desc,'\0',sizeof(desc));
uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
DEBUG(3,("WPrintQProcEnum uLevel=%d\n",uLevel));
return(True);
}
-static BOOL api_WPrintPortEnum(int cnum,uint16 vuid, char *param,char *data,
+static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
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);
- int uLevel,cbBuf;
+ int uLevel;
int succnt;
struct pack_desc desc;
- bzero(&desc,sizeof(desc));
+ memset((char *)&desc,'\0',sizeof(desc));
uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
DEBUG(3,("WPrintPortEnum uLevel=%d\n",uLevel));
if (uLevel != 0 || strcmp(str2,"B9") != 0) return False;
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- bzero(&desc,sizeof(desc));
+ memset((char *)&desc,'\0',sizeof(desc));
desc.base = *rdata;
desc.buflen = mdrcnt;
desc.format = str2;
return(True);
}
-struct api_cmd
-{
- char * pipe_clnt_name;
- char * pipe_srv_name;
- BOOL (*fn) (pipes_struct *, prs_struct *);
-};
-
-static struct api_cmd api_fd_commands[] =
-{
- { "lsarpc", "lsass", api_ntlsa_rpc },
- { "samr", "lsass", api_samr_rpc },
- { "srvsvc", "ntsvcs", api_srvsvc_rpc },
- { "wkssvc", "ntsvcs", api_wkssvc_rpc },
- { "NETLOGON", "lsass", api_netlog_rpc },
- { "winreg", "winreg", api_reg_rpc },
- { NULL, NULL, NULL }
-};
+/****************************************************************************
+ Start the first part of an RPC reply which began with an SMBtrans request.
+****************************************************************************/
-static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
+static BOOL api_rpc_trans_reply(char *outbuf, pipes_struct *p)
{
- BOOL ntlmssp_auth = False;
- fstring ack_pipe_name;
- int i = 0;
-
- DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
+ char *rdata = malloc(p->max_trans_reply);
+ int data_len;
- for (i = 0; api_fd_commands[i].pipe_clnt_name; i++)
- {
- if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
- api_fd_commands[i].fn != NULL)
- {
- DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
- api_fd_commands[i].pipe_clnt_name,
- api_fd_commands[i].pipe_srv_name));
- fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name);
- break;
- }
+ if(rdata == NULL) {
+ DEBUG(0,("api_rpc_trans_reply: malloc fail.\n"));
+ return False;
}
- if (api_fd_commands[i].fn == NULL) return False;
-
- /* decode the bind request */
- smb_io_rpc_hdr_rb("", &p->hdr_rb, pd, 0);
-
- if (pd->offset == 0) return False;
-
- if (p->hdr.auth_len != 0)
- {
- /* decode the authentication verifier */
- smb_io_rpc_auth_ntlmssp_req("", &p->ntlmssp_req, pd, 0);
-
- if (pd->offset == 0) return False;
-
- /* ignore the version number for now */
- ntlmssp_auth = strequal(p->ntlmssp_req.ntlmssp_str, "NTLMSSP");
- }
-
- /* name has to be \PIPE\xxxxx */
- fstrcpy(ack_pipe_name, "\\PIPE\\");
- fstrcat(ack_pipe_name, p->pipe_srv_name);
-
- DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
-
- prs_init(&(p->rdata), 1024, 4, 0, False);
- prs_init(&(p->rhdr ), 0x10, 4, 0, False);
- prs_init(&(p->rauth), 1024, 4, 0, False);
-
- /***/
- /*** do the bind ack first ***/
- /***/
-
- make_rpc_hdr_ba(&p->hdr_ba,
- p->hdr_rb.bba.max_tsize,
- p->hdr_rb.bba.max_rsize,
- p->hdr_rb.bba.assoc_gid,
- ack_pipe_name,
- 0x1, 0x0, 0x0,
- &(p->hdr_rb.transfer));
-
- smb_io_rpc_hdr_ba("", &p->hdr_ba, &p->rdata, 0);
- mem_realloc_data(p->rdata.data, p->rdata.offset);
-
- /***/
- /*** now the authentication ***/
- /***/
-
- if (ntlmssp_auth)
- {
- uint8 data[16];
- bzero(data, sizeof(data)); /* first 8 bytes are non-zero */
-
- make_rpc_auth_ntlmssp_resp(&p->ntlmssp_resp,
- 0x0a, 0x06, 0,
- "NTLMSSP", 2,
- 0x00000000, 0x0000b2b3, 0x000082b1,
- data);
- smb_io_rpc_auth_ntlmssp_resp("", &p->ntlmssp_resp, &p->rauth, 0);
- mem_realloc_data(p->rauth.data, p->rauth.offset);
+ if((data_len = read_from_pipe( p, rdata, p->max_trans_reply)) < 0) {
+ free(rdata);
+ return False;
}
- /***/
- /*** then do the header, now we know the length ***/
- /***/
-
- make_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST,
- p->hdr.call_id,
- p->rdata.offset + p->rauth.offset,
- p->rauth.offset);
-
- smb_io_rpc_hdr("", &p->hdr, &p->rhdr, 0);
- mem_realloc_data(p->rhdr.data, p->rdata.offset);
-
- /***/
- /*** link rpc header, bind acknowledgment and authentication responses ***/
- /***/
-
- p->rhdr.data->offset.start = 0;
- p->rhdr.data->offset.end = p->rhdr.offset;
- p->rhdr.data->next = p->rdata.data;
-
- if (ntlmssp_auth)
- {
- p->rdata.data->offset.start = p->rhdr.offset;
- p->rdata.data->offset.end = p->rhdr.offset + p->rdata.offset;
- p->rdata.data->next = p->rauth.data;
-
- p->rauth.data->offset.start = p->rhdr.offset + p->rdata.offset;
- p->rauth.data->offset.end = p->rhdr.offset + p->rauth.offset + p->rdata.offset;
- p->rauth.data->next = NULL;
- }
- else
- {
- p->rdata.data->offset.start = p->rhdr.offset;
- p->rdata.data->offset.end = p->rhdr.offset + p->rdata.offset;
- p->rdata.data->next = NULL;
- }
+ send_trans_reply(outbuf, NULL, 0, rdata, data_len, p->out_data.current_pdu_len > data_len);
+ free(rdata);
return True;
}
-static BOOL api_pipe_request(pipes_struct *p, prs_struct *pd)
-{
- int i = 0;
-
- for (i = 0; api_fd_commands[i].pipe_clnt_name; i++)
- {
- if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
- api_fd_commands[i].fn != NULL)
- {
- DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name));
- return api_fd_commands[i].fn(p, pd);
- }
- }
- return False;
-}
+/****************************************************************************
+ WaitNamedPipeHandleState
+****************************************************************************/
-static BOOL api_dce_rpc_command(char *outbuf,
- pipes_struct *p,
- prs_struct *pd)
+static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param, int param_len)
{
- BOOL reply = False;
- if (pd->data == NULL) return False;
+ uint16 priority;
- /* process the rpc header */
- smb_io_rpc_hdr("", &p->hdr, pd, 0);
+ if (!param || param_len < 2)
+ return False;
- if (pd->offset == 0) return False;
-
- switch (p->hdr.pkt_type)
- {
- case RPC_BIND :
- {
- reply = api_pipe_bind_req(p, pd);
- break;
- }
- case RPC_REQUEST:
- {
- reply = api_pipe_request (p, pd);
- break;
- }
- }
+ priority = SVAL(param,0);
+ DEBUG(4,("WaitNamedPipeHandleState priority %x\n", priority));
- if (reply)
- {
+ if (wait_rpc_pipe_hnd_state(p, priority)) {
/* now send the reply */
- send_trans_reply(outbuf, p->rhdr.data, NULL, NULL, 0, p->file_offset);
-
- if (mem_buf_len(p->rhdr.data) <= p->file_offset)
- {
- /* all of data was sent: no need to wait for SMBreadX calls */
- mem_free_data(p->rhdr .data);
- mem_free_data(p->rdata.data);
- }
+ send_trans_reply(outbuf, NULL, 0, NULL, 0, False);
+ return True;
}
-
- return reply;
+ return False;
}
+
/****************************************************************************
SetNamedPipeHandleState
****************************************************************************/
-static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param)
+
+static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param, int param_len)
{
uint16 id;
- if (!param) return False;
+ if (!param || param_len < 2)
+ return False;
- id = param[0] + (param[1] << 8);
- DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n", id));
+ id = SVAL(param,0);
+ DEBUG(4,("SetNamedPipeHandleState to code %x\n", id));
- if (set_rpc_pipe_hnd_state(p, id))
- {
+ if (set_rpc_pipe_hnd_state(p, id)) {
/* now send the reply */
- send_trans_reply(outbuf, NULL, NULL, NULL, 0, p->file_offset);
-
+ send_trans_reply(outbuf, NULL, 0, NULL, 0, False);
return True;
}
return False;
/****************************************************************************
- when no reply is generated, indicate unsupported.
+ When no reply is generated, indicate unsupported.
****************************************************************************/
+
static BOOL api_no_reply(char *outbuf, int max_rdata_len)
{
- struct mem_buf rparam;
-
- mem_init(&rparam, 0);
- mem_alloc_data(&rparam, 4);
-
- rparam.offset.start = 0;
- rparam.offset.end = 4;
+ char rparam[4];
/* unsupported */
- SSVAL(rparam.data,0,NERR_notsupported);
- SSVAL(rparam.data,2,0); /* converter word */
+ SSVAL(rparam,0,NERR_notsupported);
+ SSVAL(rparam,2,0); /* converter word */
DEBUG(3,("Unsupported API fd command\n"));
/* now send the reply */
- send_trans_reply(outbuf, NULL, &rparam, NULL, 0, max_rdata_len);
-
- mem_free_data(&rparam);
+ send_trans_reply(outbuf, rparam, 4, NULL, 0, False);
- return(-1);
+ return -1;
}
/****************************************************************************
- handle remote api calls delivered to a named pipe already opened.
- ****************************************************************************/
-static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
+ Handle remote api calls delivered to a named pipe already opened.
+ ****************************************************************************/
+
+static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
uint16 *setup,char *data,char *params,
int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
{
- BOOL reply = False;
-
+ BOOL reply = False;
+ pipes_struct *p = NULL;
int pnum;
int subcommand;
- pipes_struct *p = NULL;
- prs_struct pd;
- struct mem_buf data_buf;
DEBUG(5,("api_fd_reply\n"));
- /* fake up a data buffer from the api_fd_reply data parameters */
- mem_create(&data_buf, data, tdscnt, 0, False);
- data_buf.offset.start = 0;
- data_buf.offset.end = tdscnt;
-
- /* fake up a parsing structure */
- pd.data = &data_buf;
- pd.align = 4;
- pd.io = True;
- pd.offset = 0;
-
/* First find out the name of this file. */
- if (suwcnt != 2)
- {
+ if (suwcnt != 2) {
DEBUG(0,("Unexpected named pipe transaction.\n"));
return(-1);
}
/* Get the file handle and hence the file name. */
- pnum = setup[1];
- subcommand = setup[0];
- get_rpc_pipe(pnum, &p);
+ /*
+ * NB. The setup array has already been transformed
+ * via SVAL and so is in gost byte order.
+ */
+ pnum = ((int)setup[1]) & 0xFFFF;
+ subcommand = ((int)setup[0]) & 0xFFFF;
- if (p != NULL)
- {
- DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)",
- subcommand, p->name, pnum));
- DEBUG(3,("(tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d,cnum=%d,vuid=%d)\n",
- tdscnt,tpscnt,mdrcnt,mprcnt,cnum,vuid));
+ if(!(p = get_rpc_pipe(pnum))) {
+ DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
+ return api_no_reply(outbuf, mdrcnt);
+ }
- /* record maximum data length that can be transmitted in an SMBtrans */
- p->file_offset = mdrcnt;
+ DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)", subcommand, p->name, pnum));
- DEBUG(10,("api_fd_reply: p:%p file_offset: %d\n",
- p, p->file_offset));
+ /* record maximum data length that can be transmitted in an SMBtrans */
+ p->max_trans_reply = mdrcnt;
- switch (subcommand)
- {
- case 0x26:
- {
- /* dce/rpc command */
- reply = api_dce_rpc_command(outbuf, p, &pd);
- break;
- }
- case 0x01:
- {
- /* Set Named Pipe Handle state */
- reply = api_SNPHS(outbuf, p, params);
- break;
- }
- }
- }
- else
- {
- DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
+ DEBUG(10,("api_fd_reply: p:%p max_trans_reply: %d\n", p, p->max_trans_reply));
+
+ switch (subcommand) {
+ case 0x26:
+ /* dce/rpc command */
+ reply = write_to_pipe(p, data, tdscnt);
+ if (reply)
+ reply = api_rpc_trans_reply(outbuf, p);
+ break;
+ case 0x53:
+ /* Wait Named Pipe Handle state */
+ reply = api_WNPHS(outbuf, p, params, tpscnt);
+ break;
+ case 0x01:
+ /* Set Named Pipe Handle state */
+ reply = api_SNPHS(outbuf, p, params, tpscnt);
+ break;
}
if (!reply)
- {
return api_no_reply(outbuf, mdrcnt);
- }
+
return -1;
}
/****************************************************************************
- the buffer was too small
- ****************************************************************************/
-static BOOL api_TooSmall(int cnum,uint16 vuid, char *param,char *data,
+ The buffer was too small
+ ****************************************************************************/
+
+static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
/****************************************************************************
- the request is not supported
- ****************************************************************************/
-static BOOL api_Unsupported(int cnum,uint16 vuid, char *param,char *data,
+ The request is not supported
+ ****************************************************************************/
+
+static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
char *name;
int id;
- BOOL (*fn)(int,uint16,char *,char *,int,int,char **,char **,int *,int *);
+ BOOL (*fn)(connection_struct *,uint16,char *,char *,
+ int,int,char **,char **,int *,int *);
int flags;
} api_commands[] = {
{"RNetShareEnum", 0, api_RNetShareEnum,0},
/****************************************************************************
- handle remote api calls
- ****************************************************************************/
-static int api_reply(int cnum,uint16 vuid,char *outbuf,char *data,char *params,
+ Handle remote api calls
+ ****************************************************************************/
+
+static int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params,
int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
{
- int api_command = SVAL(params,0);
- struct mem_buf rdata_buf;
- struct mem_buf rparam_buf;
+ int api_command;
char *rdata = NULL;
char *rparam = NULL;
int rdata_len = 0;
BOOL reply=False;
int i;
+ if (!params) {
+ DEBUG(0,("ERROR: NULL params in api_reply()\n"));
+ return 0;
+ }
+
+ api_command = SVAL(params,0);
+
DEBUG(3,("Got API command %d of form <%s> <%s> (tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
- api_command,params+2,skip_string(params+2,1),
+ api_command,
+ params+2,
+ skip_string(params+2,1),
tdscnt,tpscnt,mdrcnt,mprcnt));
- for (i=0;api_commands[i].name;i++)
- if (api_commands[i].id == api_command && api_commands[i].fn)
- {
- DEBUG(3,("Doing %s\n",api_commands[i].name));
- break;
- }
+ for (i=0;api_commands[i].name;i++) {
+ if (api_commands[i].id == api_command && api_commands[i].fn) {
+ DEBUG(3,("Doing %s\n",api_commands[i].name));
+ break;
+ }
+ }
- rdata = (char *)malloc(1024); if (rdata) bzero(rdata,1024);
- rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024);
+ rdata = (char *)malloc(1024);
+ if (rdata)
+ memset(rdata,'\0',1024);
- reply = api_commands[i].fn(cnum,vuid,params,data,mdrcnt,mprcnt,
+ rparam = (char *)malloc(1024);
+ if (rparam)
+ memset(rparam,'\0',1024);
+
+ if(!rdata || !rparam) {
+ DEBUG(0,("api_reply: malloc fail !\n"));
+ return -1;
+ }
+
+ reply = api_commands[i].fn(conn,vuid,params,data,mdrcnt,mprcnt,
&rdata,&rparam,&rdata_len,&rparam_len);
if (rdata_len > mdrcnt ||
- rparam_len > mprcnt)
- {
- reply = api_TooSmall(cnum,vuid,params,data,mdrcnt,mprcnt,
+ rparam_len > mprcnt) {
+ reply = api_TooSmall(conn,vuid,params,data,mdrcnt,mprcnt,
&rdata,&rparam,&rdata_len,&rparam_len);
- }
-
+ }
/* if we get False back then it's actually unsupported */
if (!reply)
- api_Unsupported(cnum,vuid,params,data,mdrcnt,mprcnt,
+ api_Unsupported(conn,vuid,params,data,mdrcnt,mprcnt,
&rdata,&rparam,&rdata_len,&rparam_len);
-
- mem_create(&rdata_buf , rdata , rdata_len , 0, False);
- mem_create(&rparam_buf, rparam, rparam_len, 0, False);
-
- rdata_buf.offset.start = 0;
- rdata_buf.offset.end = rdata_len;
-
- rparam_buf.offset.start = 0;
- rparam_buf.offset.end = rparam_len;
+ send_trans_reply(outbuf, rparam, rparam_len, rdata, rdata_len, False);
- /* now send the reply */
- send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0);
-
- if (rdata ) free(rdata);
- if (rparam) free(rparam);
+ if (rdata )
+ free(rdata);
+ if (rparam)
+ free(rparam);
- return(-1);
+ return -1;
}
/****************************************************************************
handle named pipe commands
****************************************************************************/
-static int named_pipe(int cnum,uint16 vuid, char *outbuf,char *name,
+static int named_pipe(connection_struct *conn,uint16 vuid, char *outbuf,char *name,
uint16 *setup,char *data,char *params,
int suwcnt,int tdscnt,int tpscnt,
int msrcnt,int mdrcnt,int mprcnt)
DEBUG(3,("named pipe command on <%s> name\n", name));
if (strequal(name,"LANMAN"))
+ return api_reply(conn,vuid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt);
+
+ if (strequal(name,"WKSSVC") ||
+ strequal(name,"SRVSVC") ||
+ strequal(name,"WINREG") ||
+ strequal(name,"SAMR") ||
+ strequal(name,"LSARPC"))
{
- return api_reply(cnum,vuid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt);
+ DEBUG(4,("named pipe command from Win95 (wow!)\n"));
+ return api_fd_reply(conn,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt);
}
if (strlen(name) < 1)
- {
- return api_fd_reply(cnum,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt);
- }
+ return api_fd_reply(conn,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt);
if (setup)
- {
DEBUG(3,("unknown named pipe: setup 0x%X setup1=%d\n", (int)setup[0],(int)setup[1]));
- }
return 0;
}
/****************************************************************************
- reply to a SMBtrans
- ****************************************************************************/
-int reply_trans(char *inbuf,char *outbuf, int size, int bufsize)
-{
- fstring name;
+ Reply to a SMBtrans.
+ ****************************************************************************/
- char *data=NULL,*params=NULL;
- uint16 *setup=NULL;
-
- int outsize = 0;
- int cnum = SVAL(inbuf,smb_tid);
- uint16 vuid = SVAL(inbuf,smb_uid);
-
- int tpscnt = SVAL(inbuf,smb_vwv0);
- int tdscnt = SVAL(inbuf,smb_vwv1);
- int mprcnt = SVAL(inbuf,smb_vwv2);
- int mdrcnt = SVAL(inbuf,smb_vwv3);
- int msrcnt = CVAL(inbuf,smb_vwv4);
- BOOL close_on_completion = BITSETW(inbuf+smb_vwv5,0);
- BOOL one_way = BITSETW(inbuf+smb_vwv5,1);
- int pscnt = SVAL(inbuf,smb_vwv9);
- int psoff = SVAL(inbuf,smb_vwv10);
- int dscnt = SVAL(inbuf,smb_vwv11);
- int dsoff = SVAL(inbuf,smb_vwv12);
- int suwcnt = CVAL(inbuf,smb_vwv13);
-
- bzero(name, sizeof(name));
- fstrcpy(name,smb_buf(inbuf));
-
- if (dscnt > tdscnt || pscnt > tpscnt) {
- exit_server("invalid trans parameters\n");
- }
+int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int bufsize)
+{
+ fstring name;
+ int name_offset = 0;
+ char *data=NULL,*params=NULL;
+ uint16 *setup=NULL;
+ int outsize = 0;
+ uint16 vuid = SVAL(inbuf,smb_uid);
+ int tpscnt = SVAL(inbuf,smb_vwv0);
+ int tdscnt = SVAL(inbuf,smb_vwv1);
+ int mprcnt = SVAL(inbuf,smb_vwv2);
+ int mdrcnt = SVAL(inbuf,smb_vwv3);
+ int msrcnt = CVAL(inbuf,smb_vwv4);
+ BOOL close_on_completion = BITSETW(inbuf+smb_vwv5,0);
+ BOOL one_way = BITSETW(inbuf+smb_vwv5,1);
+ int pscnt = SVAL(inbuf,smb_vwv9);
+ int psoff = SVAL(inbuf,smb_vwv10);
+ int dscnt = SVAL(inbuf,smb_vwv11);
+ int dsoff = SVAL(inbuf,smb_vwv12);
+ int suwcnt = CVAL(inbuf,smb_vwv13);
+
+ memset(name, '\0',sizeof(name));
+ fstrcpy(name,smb_buf(inbuf));
+
+ if (dscnt > tdscnt || pscnt > tpscnt) {
+ exit_server("invalid trans parameters\n");
+ }
- if (tdscnt)
- {
- data = (char *)malloc(tdscnt);
- memcpy(data,smb_base(inbuf)+dsoff,dscnt);
- }
- if (tpscnt)
- {
- params = (char *)malloc(tpscnt);
- memcpy(params,smb_base(inbuf)+psoff,pscnt);
- }
-
- if (suwcnt)
- {
- int i;
- setup = (uint16 *)malloc(suwcnt*sizeof(setup[0]));
- for (i=0;i<suwcnt;i++)
- setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD);
- }
+ if (tdscnt) {
+ if((data = (char *)malloc(tdscnt)) == NULL) {
+ DEBUG(0,("reply_trans: data malloc fail for %d bytes !\n", tdscnt));
+ return(ERROR(ERRDOS,ERRnomem));
+ }
+ memcpy(data,smb_base(inbuf)+dsoff,dscnt);
+ }
+ if (tpscnt) {
+ if((params = (char *)malloc(tpscnt)) == NULL) {
+ DEBUG(0,("reply_trans: param malloc fail for %d bytes !\n", tpscnt));
+ return(ERROR(ERRDOS,ERRnomem));
+ }
+ memcpy(params,smb_base(inbuf)+psoff,pscnt);
+ }
- if (pscnt < tpscnt || dscnt < tdscnt)
- {
- /* We need to send an interim response then receive the rest
- of the parameter/data bytes */
- outsize = set_message(outbuf,0,0,True);
- show_msg(outbuf);
- send_smb(Client,outbuf);
- }
+ if (suwcnt) {
+ int i;
+ if((setup = (uint16 *)malloc(suwcnt*sizeof(uint16))) == NULL) {
+ DEBUG(0,("reply_trans: setup malloc fail for %d bytes !\n", (int)(suwcnt * sizeof(uint16))));
+ return(ERROR(ERRDOS,ERRnomem));
+ }
+ for (i=0;i<suwcnt;i++)
+ setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD);
+ }
- /* receive the rest of the trans packet */
- while (pscnt < tpscnt || dscnt < tdscnt)
- {
- BOOL ret;
- int pcnt,poff,dcnt,doff,pdisp,ddisp;
-
- ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,SMB_SECONDARY_WAIT);
- if ((ret && (CVAL(inbuf, smb_com) != SMBtrans)) || !ret)
- {
- if(ret)
- DEBUG(0,("reply_trans: Invalid secondary trans packet\n"));
- else
- DEBUG(0,("reply_trans: %s in getting secondary trans response.\n",
- (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
- if (params) free(params);
- if (data) free(data);
- if (setup) free(setup);
- return(ERROR(ERRSRV,ERRerror));
+ if (pscnt < tpscnt || dscnt < tdscnt) {
+ /* We need to send an interim response then receive the rest
+ of the parameter/data bytes */
+ outsize = set_message(outbuf,0,0,True);
+ show_msg(outbuf);
+ send_smb(smbd_server_fd(),outbuf);
}
- show_msg(inbuf);
+ /* receive the rest of the trans packet */
+ while (pscnt < tpscnt || dscnt < tdscnt) {
+ BOOL ret;
+ int pcnt,poff,dcnt,doff,pdisp,ddisp;
- tpscnt = SVAL(inbuf,smb_vwv0);
- tdscnt = SVAL(inbuf,smb_vwv1);
+ ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
+
+ if ((ret && (CVAL(inbuf, smb_com) != SMBtranss)) || !ret) {
+ if(ret) {
+ DEBUG(0,("reply_trans: Invalid secondary trans packet\n"));
+ } else {
+ DEBUG(0,("reply_trans: %s in getting secondary trans response.\n",
+ (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
+ }
+ if (params)
+ free(params);
+ if (data)
+ free(data);
+ if (setup)
+ free(setup);
+ return(ERROR(ERRSRV,ERRerror));
+ }
- pcnt = SVAL(inbuf,smb_vwv2);
- poff = SVAL(inbuf,smb_vwv3);
- pdisp = SVAL(inbuf,smb_vwv4);
+ show_msg(inbuf);
- dcnt = SVAL(inbuf,smb_vwv5);
- doff = SVAL(inbuf,smb_vwv6);
- ddisp = SVAL(inbuf,smb_vwv7);
-
- pscnt += pcnt;
- dscnt += dcnt;
-
- if (dscnt > tdscnt || pscnt > tpscnt) {
- exit_server("invalid trans parameters\n");
- }
-
- if (pcnt)
- memcpy(params+pdisp,smb_base(inbuf)+poff,pcnt);
- if (dcnt)
- memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt);
- }
-
-
- DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n",name,tdscnt,tpscnt,suwcnt));
-
- if (strncmp(name,"\\PIPE\\",strlen("\\PIPE\\")) == 0)
- {
- DEBUG(5,("calling named_pipe\n"));
- outsize = named_pipe(cnum,vuid,outbuf,name+strlen("\\PIPE\\"),setup,data,params,
- suwcnt,tdscnt,tpscnt,msrcnt,mdrcnt,mprcnt);
- }
- else
- {
- DEBUG(3,("invalid pipe name\n"));
- outsize = 0;
- }
-
-
- if (data) free(data);
- if (params) free(params);
- if (setup) free(setup);
+ tpscnt = SVAL(inbuf,smb_vwv0);
+ tdscnt = SVAL(inbuf,smb_vwv1);
+
+ pcnt = SVAL(inbuf,smb_vwv2);
+ poff = SVAL(inbuf,smb_vwv3);
+ pdisp = SVAL(inbuf,smb_vwv4);
+
+ dcnt = SVAL(inbuf,smb_vwv5);
+ doff = SVAL(inbuf,smb_vwv6);
+ ddisp = SVAL(inbuf,smb_vwv7);
+
+ pscnt += pcnt;
+ dscnt += dcnt;
+
+ if (dscnt > tdscnt || pscnt > tpscnt) {
+ exit_server("invalid trans parameters\n");
+ }
+
+ if (pcnt)
+ memcpy(params+pdisp,smb_base(inbuf)+poff,pcnt);
+ if (dcnt)
+ memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt);
+ }
+
+
+ DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n",
+ name,tdscnt,tpscnt,suwcnt));
+
+ /*
+ * WinCE wierdness....
+ */
- if (close_on_completion)
- close_cnum(cnum,vuid);
+ if (name[0] == '\\' && (StrnCaseCmp(&name[1],local_machine, strlen(local_machine)) == 0) &&
+ (name[strlen(local_machine)+1] == '\\'))
+ name_offset = strlen(local_machine)+1;
+
+ if (strncmp(&name[name_offset],"\\PIPE\\",strlen("\\PIPE\\")) == 0) {
+ DEBUG(5,("calling named_pipe\n"));
+ outsize = named_pipe(conn,vuid,outbuf,
+ name+name_offset+strlen("\\PIPE\\"),setup,data,params,
+ suwcnt,tdscnt,tpscnt,msrcnt,mdrcnt,mprcnt);
+ } else {
+ DEBUG(3,("invalid pipe name\n"));
+ outsize = 0;
+ }
- if (one_way)
- return(-1);
-
- if (outsize == 0)
- return(ERROR(ERRSRV,ERRnosupport));
+
+ if (data)
+ free(data);
+ if (params)
+ free(params);
+ if (setup)
+ free(setup);
+
+ if (close_on_completion)
+ close_cnum(conn,vuid);
- return(outsize);
+ if (one_way)
+ return(-1);
+
+ if (outsize == 0)
+ return(ERROR(ERRSRV,ERRnosupport));
+
+ return(outsize);
}