3 Unix SMB/Netbios implementation.
5 Inter-process communication and named pipe handling
6 Copyright (C) Andrew Tridgell 1992-1995
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 This file handles the named pipe and mailslot calls
24 in the SMBtrans protocol
34 extern int DEBUGLEVEL
;
36 extern files_struct Files
[];
37 extern connection_struct Connections
[];
39 extern fstring local_machine
;
41 #define NERR_Success 0
42 #define NERR_badpass 86
43 #define NERR_notsupported 50
45 #define NERR_BASE (2100)
46 #define NERR_BufTooSmall (NERR_BASE+23)
47 #define NERR_JobNotFound (NERR_BASE+51)
48 #define NERR_DestNotFound (NERR_BASE+52)
49 #define ERROR_INVALID_LEVEL 124
50 #define ERROR_MORE_DATA 234
52 #define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
54 #define ACCESS_READ 0x01
55 #define ACCESS_WRITE 0x02
56 #define ACCESS_CREATE 0x04
58 #define SHPWLEN 8 /* share password length */
59 #define NNLEN 12 /* 8.3 net name length */
60 #define SNLEN 15 /* service name length */
61 #define QNLEN 12 /* queue name maximum length */
65 static BOOL
api_Unsupported(int cnum
,uint16 vuid
, char *param
,char *data
,
66 int mdrcnt
,int mprcnt
,
67 char **rdata
,char **rparam
,
68 int *rdata_len
,int *rparam_len
);
69 static BOOL
api_TooSmall(int cnum
,uint16 vuid
, char *param
,char *data
,
70 int mdrcnt
,int mprcnt
,
71 char **rdata
,char **rparam
,
72 int *rdata_len
,int *rparam_len
);
75 static int CopyExpanded(int cnum
, int snum
, char** dst
, char* src
, int* n
)
80 if (!src
|| !dst
|| !n
|| !(*dst
)) return(0);
82 StrnCpy(buf
,src
,sizeof(buf
)/2);
83 string_sub(buf
,"%S",lp_servicename(snum
));
84 standard_sub(cnum
,buf
);
92 static int CopyAndAdvance(char** dst
, char* src
, int* n
)
95 if (!src
|| !dst
|| !n
|| !(*dst
)) return(0);
103 static int StrlenExpanded(int cnum
, int snum
, char* s
)
107 StrnCpy(buf
,s
,sizeof(buf
)/2);
108 string_sub(buf
,"%S",lp_servicename(snum
));
109 standard_sub(cnum
,buf
);
110 return strlen(buf
) + 1;
113 static char* Expand(int cnum
, int snum
, char* s
)
116 if (!s
) return(NULL
);
117 StrnCpy(buf
,s
,sizeof(buf
)/2);
118 string_sub(buf
,"%S",lp_servicename(snum
));
119 standard_sub(cnum
,buf
);
123 /*******************************************************************
124 check a API string for validity when we only need to check the prefix
125 ******************************************************************/
126 static BOOL
prefix_ok(char *str
,char *prefix
)
128 return(strncmp(str
,prefix
,strlen(prefix
)) == 0);
132 /****************************************************************************
134 ****************************************************************************/
135 static void send_trans_reply(char *outbuf
,char *data
,char *param
,uint16
*setup
,
136 int ldata
,int lparam
,int lsetup
)
139 int this_ldata
,this_lparam
;
140 int tot_data
=0,tot_param
=0;
143 this_lparam
= MIN(lparam
,max_send
- (500+lsetup
*SIZEOFWORD
)); /* hack */
144 this_ldata
= MIN(ldata
,max_send
- (500+lsetup
*SIZEOFWORD
+this_lparam
));
146 align
= (this_lparam
%4);
148 set_message(outbuf
,10+lsetup
,align
+this_ldata
+this_lparam
,True
);
150 memcpy(smb_buf(outbuf
),param
,this_lparam
);
152 memcpy(smb_buf(outbuf
)+this_lparam
+align
,data
,this_ldata
);
154 SSVAL(outbuf
,smb_vwv0
,lparam
);
155 SSVAL(outbuf
,smb_vwv1
,ldata
);
156 SSVAL(outbuf
,smb_vwv3
,this_lparam
);
157 SSVAL(outbuf
,smb_vwv4
,smb_offset(smb_buf(outbuf
),outbuf
));
158 SSVAL(outbuf
,smb_vwv5
,0);
159 SSVAL(outbuf
,smb_vwv6
,this_ldata
);
160 SSVAL(outbuf
,smb_vwv7
,smb_offset(smb_buf(outbuf
)+this_lparam
+align
,outbuf
));
161 SSVAL(outbuf
,smb_vwv8
,0);
162 SSVAL(outbuf
,smb_vwv9
,lsetup
);
163 for (i
=0;i
<lsetup
;i
++)
164 SSVAL(outbuf
,smb_vwv10
+i
*SIZEOFWORD
,setup
[i
]);
167 send_smb(Client
,outbuf
);
169 tot_data
= this_ldata
;
170 tot_param
= this_lparam
;
172 while (tot_data
< ldata
|| tot_param
< lparam
)
174 this_lparam
= MIN(lparam
-tot_param
,max_send
- 500); /* hack */
175 this_ldata
= MIN(ldata
-tot_data
,max_send
- (500+this_lparam
));
177 align
= (this_lparam
%4);
179 set_message(outbuf
,10,this_ldata
+this_lparam
+align
,False
);
181 memcpy(smb_buf(outbuf
),param
+tot_param
,this_lparam
);
183 memcpy(smb_buf(outbuf
)+this_lparam
+align
,data
+tot_data
,this_ldata
);
185 SSVAL(outbuf
,smb_vwv3
,this_lparam
);
186 SSVAL(outbuf
,smb_vwv4
,smb_offset(smb_buf(outbuf
),outbuf
));
187 SSVAL(outbuf
,smb_vwv5
,tot_param
);
188 SSVAL(outbuf
,smb_vwv6
,this_ldata
);
189 SSVAL(outbuf
,smb_vwv7
,smb_offset(smb_buf(outbuf
)+this_lparam
+align
,outbuf
));
190 SSVAL(outbuf
,smb_vwv8
,tot_data
);
191 SSVAL(outbuf
,smb_vwv9
,0);
194 send_smb(Client
,outbuf
);
196 tot_data
+= this_ldata
;
197 tot_param
+= this_lparam
;
202 char* format
; /* formatstring for structure */
203 char* subformat
; /* subformat for structure */
204 char* base
; /* baseaddress of buffer */
205 int buflen
; /* remaining size for fixed part; on init: length of base */
206 int subcount
; /* count of substructures */
207 char* structbuf
; /* pointer into buffer for remaining fixed part */
208 int stringlen
; /* remaining size for variable part */
209 char* stringbuf
; /* pointer into buffer for remaining variable part */
210 int neededlen
; /* total needed size */
211 int usedlen
; /* total used size (usedlen <= neededlen and usedlen <= buflen) */
212 char* curpos
; /* current position; pointer into format or subformat */
216 static int get_counter(char** p
)
219 if (!p
|| !(*p
)) return(1);
220 if (!isdigit(**p
)) return 1;
224 n
= 10 * n
+ (i
- '0');
231 static int getlen(char* p
)
237 case 'W': /* word (2 byte) */
240 case 'N': /* count of substructures (word) at end */
243 case 'D': /* double word (4 byte) */
244 case 'z': /* offset to zero terminated string (4 byte) */
245 case 'l': /* offset to user data (4 byte) */
248 case 'b': /* offset to data (with counter) (4 byte) */
252 case 'B': /* byte (with optional counter) */
253 n
+= get_counter(&p
);
260 static BOOL
init_package(struct pack_desc
* p
, int count
, int subcount
)
265 if (!p
->format
|| !p
->base
) return(False
);
267 i
= count
* getlen(p
->format
);
268 if (p
->subformat
) i
+= subcount
* getlen(p
->subformat
);
269 p
->structbuf
= p
->base
;
273 p
->curpos
= p
->format
;
276 p
->errcode
= NERR_BufTooSmall
;
279 p
->errcode
= NERR_Success
;
282 p
->stringbuf
= p
->base
+ i
;
284 return(p
->errcode
== NERR_Success
);
288 static int package(struct pack_desc
* p
, ...)
291 static int package(va_alist
)
297 int needed
=0, stringneeded
;
299 int is_string
=0, stringused
;
306 p
= va_arg(args
,struct pack_desc
*);
311 p
->curpos
= p
->format
;
313 p
->curpos
= p
->subformat
;
318 str
= va_arg(args
,char*);
319 if (strncmp(str
,p
->curpos
,strlen(str
)) != 0) {
320 DEBUG(2,("type error in package: %s instead of %*s\n",str
,
321 strlen(str
),p
->curpos
));
331 if (!p
->curpos
) return(0);
333 switch( *p
->curpos
++ ) {
334 case 'W': /* word (2 byte) */
336 temp
= va_arg(args
,int);
337 if (p
->buflen
>= needed
) SSVAL(p
->structbuf
,0,temp
);
339 case 'N': /* count of substructures (word) at end */
341 p
->subcount
= va_arg(args
,int);
342 if (p
->buflen
>= needed
) SSVAL(p
->structbuf
,0,p
->subcount
);
344 case 'D': /* double word (4 byte) */
346 temp
= va_arg(args
,int);
347 if (p
->buflen
>= needed
) SIVAL(p
->structbuf
,0,temp
);
349 case 'B': /* byte (with optional counter) */
350 needed
= get_counter(&p
->curpos
);
352 char *s
= va_arg(args
,char*);
353 if (p
->buflen
>= needed
) StrnCpy(p
->structbuf
,s
?s
:"",needed
);
356 case 'z': /* offset to zero terminated string (4 byte) */
357 str
= va_arg(args
,char*);
358 stringneeded
= (str
? strlen(str
)+1 : 0);
361 case 'l': /* offset to user data (4 byte) */
362 str
= va_arg(args
,char*);
363 stringneeded
= va_arg(args
,int);
366 case 'b': /* offset to data (with counter) (4 byte) */
367 str
= va_arg(args
,char*);
368 stringneeded
= get_counter(&p
->curpos
);
373 if (stringneeded
>= 0) {
375 if (p
->buflen
>= needed
) {
376 stringused
= stringneeded
;
377 if (stringused
> p
->stringlen
) {
378 stringused
= (is_string
? p
->stringlen
: 0);
379 if (p
->errcode
== NERR_Success
) p
->errcode
= ERROR_MORE_DATA
;
382 SIVAL(p
->structbuf
,0,0);
384 SIVAL(p
->structbuf
,0,PTR_DIFF(p
->stringbuf
,p
->base
));
385 memcpy(p
->stringbuf
,str
?str
:"",stringused
);
386 if (is_string
) p
->stringbuf
[stringused
-1] = '\0';
387 p
->stringbuf
+= stringused
;
388 p
->stringlen
-= stringused
;
389 p
->usedlen
+= stringused
;
392 p
->neededlen
+= stringneeded
;
394 p
->neededlen
+= needed
;
395 if (p
->buflen
>= needed
) {
396 p
->structbuf
+= needed
;
398 p
->usedlen
+= needed
;
401 if (p
->errcode
== NERR_Success
) p
->errcode
= NERR_BufTooSmall
;
407 #define PACK(desc,t,v) package(desc,t,v,0,0,0,0)
408 #define PACKl(desc,t,v,l) package(desc,t,v,l,0,0,0,0)
410 #define PACK(desc,t,v) package(desc,v)
411 #define PACKl(desc,t,v,l) package(desc,v,l)
414 static void PACKI(struct pack_desc
* desc
,char *t
,int v
)
419 static void PACKS(struct pack_desc
* desc
,char *t
,char *v
)
425 /****************************************************************************
427 ****************************************************************************/
429 static void PackDriverData(struct pack_desc
* desc
)
431 char drivdata
[4+4+32];
432 SIVAL(drivdata
,0,sizeof drivdata
); /* cb */
433 SIVAL(drivdata
,4,1000); /* lVersion */
434 memset(drivdata
+8,0,32); /* szDeviceName */
435 strcpy(drivdata
+8,"NULL");
436 PACKl(desc
,"l",drivdata
,sizeof drivdata
); /* pDriverData */
439 static int check_printq_info(struct pack_desc
* desc
,
440 int uLevel
, char *id1
, const char* id2
)
442 desc
->subformat
= NULL
;
445 desc
->format
= "B13";
448 desc
->format
= "B13BWWWzzzzzWW";
451 desc
->format
= "B13BWWWzzzzzWN";
452 desc
->subformat
= "WB21BB16B10zWWzDDz";
455 desc
->format
= "zWWWWzzzzWWzzl";
458 desc
->format
= "zWWWWzzzzWNzzl";
459 desc
->subformat
= "WWzWWDDzz";
464 default: return False
;
466 if (strcmp(desc
->format
,id1
) != 0) return False
;
467 if (desc
->subformat
&& strcmp(desc
->subformat
,id2
) != 0) return False
;
471 static void fill_printjob_info(int cnum
, int snum
, int uLevel
,
472 struct pack_desc
* desc
,
473 print_queue_struct
* queue
, int n
)
475 time_t t
= queue
->time
;
477 /* the client expects localtime */
480 PACKI(desc
,"W",((snum
%0xFF)<<8) | (queue
->job
%0xFF)); /* uJobId */
482 PACKS(desc
,"B21",queue
->user
); /* szUserName */
483 PACKS(desc
,"B",""); /* pad */
484 PACKS(desc
,"B16",""); /* szNotifyName */
485 PACKS(desc
,"B10","PM_Q_RAW"); /* szDataType */
486 PACKS(desc
,"z",""); /* pszParms */
487 PACKI(desc
,"W",n
+1); /* uPosition */
488 PACKI(desc
,"W",queue
->status
); /* fsStatus */
489 PACKS(desc
,"z",""); /* pszStatus */
490 PACKI(desc
,"D",t
); /* ulSubmitted */
491 PACKI(desc
,"D",queue
->size
); /* ulSize */
492 PACKS(desc
,"z",queue
->file
); /* pszComment */
494 if (uLevel
== 2 || uLevel
== 3) {
495 PACKI(desc
,"W",queue
->priority
); /* uPriority */
496 PACKS(desc
,"z",queue
->user
); /* pszUserName */
497 PACKI(desc
,"W",n
+1); /* uPosition */
498 PACKI(desc
,"W",queue
->status
); /* fsStatus */
499 PACKI(desc
,"D",t
); /* ulSubmitted */
500 PACKI(desc
,"D",queue
->size
); /* ulSize */
501 PACKS(desc
,"z","Samba"); /* pszComment */
502 PACKS(desc
,"z",queue
->file
); /* pszDocument */
504 PACKS(desc
,"z",""); /* pszNotifyName */
505 PACKS(desc
,"z","PM_Q_RAW"); /* pszDataType */
506 PACKS(desc
,"z",""); /* pszParms */
507 PACKS(desc
,"z",""); /* pszStatus */
508 PACKS(desc
,"z",SERVICE(snum
)); /* pszQueue */
509 PACKS(desc
,"z","lpd"); /* pszQProcName */
510 PACKS(desc
,"z",""); /* pszQProcParms */
511 PACKS(desc
,"z","NULL"); /* pszDriverName */
512 PackDriverData(desc
); /* pDriverData */
513 PACKS(desc
,"z",""); /* pszPrinterName */
518 static void fill_printq_info(int cnum
, int snum
, int uLevel
,
519 struct pack_desc
* desc
,
520 int count
, print_queue_struct
* queue
,
521 print_status_struct
* status
)
524 PACKS(desc
,"B13",SERVICE(snum
));
526 PACKS(desc
,"z",Expand(cnum
,snum
,SERVICE(snum
)));
528 if (uLevel
== 1 || uLevel
== 2) {
529 PACKS(desc
,"B",""); /* alignment */
530 PACKI(desc
,"W",5); /* priority */
531 PACKI(desc
,"W",0); /* start time */
532 PACKI(desc
,"W",0); /* until time */
533 PACKS(desc
,"z",""); /* pSepFile */
534 PACKS(desc
,"z","lpd"); /* pPrProc */
535 PACKS(desc
,"z",SERVICE(snum
)); /* pDestinations */
536 PACKS(desc
,"z",""); /* pParms */
538 PACKS(desc
,"z","UNKNOWN PRINTER");
539 PACKI(desc
,"W",LPSTAT_ERROR
);
541 else if (!status
|| !status
->message
[0]) {
542 PACKS(desc
,"z",Expand(cnum
,snum
,lp_comment(snum
)));
543 PACKI(desc
,"W",LPSTAT_OK
); /* status */
545 PACKS(desc
,"z",status
->message
);
546 PACKI(desc
,"W",status
->status
); /* status */
548 PACKI(desc
,(uLevel
== 1 ? "W" : "N"),count
);
550 if (uLevel
== 3 || uLevel
== 4) {
551 PACKI(desc
,"W",5); /* uPriority */
552 PACKI(desc
,"W",0); /* uStarttime */
553 PACKI(desc
,"W",0); /* uUntiltime */
554 PACKI(desc
,"W",5); /* pad1 */
555 PACKS(desc
,"z",""); /* pszSepFile */
556 PACKS(desc
,"z","WinPrint"); /* pszPrProc */
557 PACKS(desc
,"z",""); /* pszParms */
558 if (!status
|| !status
->message
[0]) {
559 PACKS(desc
,"z",Expand(cnum
,snum
,lp_comment(snum
))); /* pszComment */
560 PACKI(desc
,"W",LPSTAT_OK
); /* fsStatus */
562 PACKS(desc
,"z",status
->message
); /* pszComment */
563 PACKI(desc
,"W",status
->status
); /* fsStatus */
565 PACKI(desc
,(uLevel
== 3 ? "W" : "N"),count
); /* cJobs */
566 PACKS(desc
,"z",SERVICE(snum
)); /* pszPrinters */
567 PACKS(desc
,"z",lp_printerdriver(snum
)); /* pszDriverName */
568 PackDriverData(desc
); /* pDriverData */
570 if (uLevel
== 2 || uLevel
== 4) {
572 for (i
=0;i
<count
;i
++)
573 fill_printjob_info(cnum
,snum
,uLevel
== 2 ? 1 : 2,desc
,&queue
[i
],i
);
576 DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",SERVICE(snum
),count
));
579 static BOOL
api_DosPrintQGetInfo(int cnum
,uint16 vuid
, char *param
,char *data
,
580 int mdrcnt
,int mprcnt
,
581 char **rdata
,char **rparam
,
582 int *rdata_len
,int *rparam_len
)
584 char *str1
= param
+2;
585 char *str2
= skip_string(str1
,1);
586 char *p
= skip_string(str2
,1);
592 struct pack_desc desc
;
593 print_queue_struct
*queue
=NULL
;
594 print_status_struct status
;
596 bzero(&status
,sizeof(status
));
597 bzero(&desc
,sizeof(desc
));
599 p
= skip_string(p
,1);
604 /* remove any trailing username */
605 if ((p
= strchr(QueueName
,'%'))) *p
= 0;
607 DEBUG(3,("PrintQueue uLevel=%d name=%s\n",uLevel
,QueueName
));
609 /* check it's a supported varient */
610 if (!prefix_ok(str1
,"zWrLh")) return False
;
611 if (!check_printq_info(&desc
,uLevel
,str2
,str3
)) return False
;
613 snum
= lp_servicenumber(QueueName
);
614 if (snum
< 0 && pcap_printername_ok(QueueName
,NULL
)) {
615 int pnum
= lp_servicenumber(PRINTERS_NAME
);
617 lp_add_printer(QueueName
,pnum
);
618 snum
= lp_servicenumber(QueueName
);
622 if (snum
< 0 || !VALID_SNUM(snum
)) return(False
);
624 count
= get_printqueue(snum
,cnum
,&queue
,&status
);
625 if (mdrcnt
> 0) *rdata
= REALLOC(*rdata
,mdrcnt
);
627 desc
.buflen
= mdrcnt
;
628 if (init_package(&desc
,1,count
)) {
629 desc
.subcount
= count
;
630 fill_printq_info(cnum
,snum
,uLevel
,&desc
,count
,queue
,&status
);
633 *rdata_len
= desc
.usedlen
;
636 *rparam
= REALLOC(*rparam
,*rparam_len
);
637 SSVALS(*rparam
,0,desc
.errcode
);
639 SSVAL(*rparam
,4,desc
.neededlen
);
641 DEBUG(4,("printqgetinfo: errorcode %d\n",desc
.errcode
));
643 if (queue
) free(queue
);
649 /****************************************************************************
650 view list of all print jobs on all queues
651 ****************************************************************************/
652 static BOOL
api_DosPrintQEnum(int cnum
, uint16 vuid
, char* param
, char* data
,
653 int mdrcnt
, int mprcnt
,
654 char **rdata
, char** rparam
,
655 int *rdata_len
, int *rparam_len
)
657 char *param_format
= param
+2;
658 char *output_format1
= skip_string(param_format
,1);
659 char *p
= skip_string(output_format1
,1);
660 int uLevel
= SVAL(p
,0);
661 char *output_format2
= p
+ 4;
662 int services
= lp_numservices();
664 struct pack_desc desc
;
665 print_queue_struct
**queue
= NULL
;
666 print_status_struct
*status
= NULL
;
667 int* subcntarr
= NULL
;
668 int queuecnt
, subcnt
=0, succnt
=0;
670 bzero(&desc
,sizeof(desc
));
672 DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel
));
674 if (!prefix_ok(param_format
,"WrLeh")) return False
;
675 if (!check_printq_info(&desc
,uLevel
,output_format1
,output_format2
))
678 for (i
= 0; i
< services
; i
++)
679 if (lp_snum_ok(i
) && lp_print_ok(i
) && lp_browseable(i
))
682 queue
= (print_queue_struct
**)malloc(queuecnt
*sizeof(print_queue_struct
*));
683 memset(queue
,0,queuecnt
*sizeof(print_queue_struct
*));
684 status
= (print_status_struct
*)malloc(queuecnt
*sizeof(print_status_struct
));
685 memset(status
,0,queuecnt
*sizeof(print_status_struct
));
686 subcntarr
= (int*)malloc(queuecnt
*sizeof(int));
689 for (i
= 0; i
< services
; i
++)
690 if (lp_snum_ok(i
) && lp_print_ok(i
) && lp_browseable(i
)) {
691 subcntarr
[n
] = get_printqueue(i
,cnum
,&queue
[n
],&status
[n
]);
692 subcnt
+= subcntarr
[n
];
696 if (mdrcnt
> 0) *rdata
= REALLOC(*rdata
,mdrcnt
);
698 desc
.buflen
= mdrcnt
;
700 if (init_package(&desc
,queuecnt
,subcnt
)) {
703 for (i
= 0; i
< services
; i
++)
704 if (lp_snum_ok(i
) && lp_print_ok(i
) && lp_browseable(i
)) {
705 fill_printq_info(cnum
,i
,uLevel
,&desc
,subcntarr
[n
],queue
[n
],&status
[n
]);
707 if (desc
.errcode
== NERR_Success
) succnt
= n
;
711 if (subcntarr
) free(subcntarr
);
713 *rdata_len
= desc
.usedlen
;
715 *rparam
= REALLOC(*rparam
,*rparam_len
);
716 SSVALS(*rparam
,0,desc
.errcode
);
718 SSVAL(*rparam
,4,succnt
);
719 SSVAL(*rparam
,6,queuecnt
);
721 for (i
= 0; i
< queuecnt
; i
++) {
722 if (queue
&& queue
[i
]) free(queue
[i
]);
725 if (queue
) free(queue
);
726 if (status
) free(status
);
731 /****************************************************************************
732 get info level for a server list query
733 ****************************************************************************/
734 static BOOL
check_server_info(int uLevel
, char* id
)
738 if (strcmp(id
,"B16") != 0) return False
;
741 if (strcmp(id
,"B16BBDz") != 0) return False
;
749 struct srv_info_struct
759 /*******************************************************************
760 get server info lists from the files saved by nmbd. Return the
762 ******************************************************************/
763 static int get_server_info(uint32 servertype
,
764 struct srv_info_struct
**servers
,
773 strcpy(fname
,lp_lockdir());
774 trim_string(fname
,NULL
,"/");
776 strcat(fname
,SERVER_LIST
);
778 f
= fopen(fname
,"r");
781 DEBUG(4,("Can't open %s - %s\n",fname
,strerror(errno
)));
785 /* request for everything is code for request all servers */
786 if (servertype
== SV_TYPE_ALL
) servertype
&= ~SV_TYPE_DOMAIN_ENUM
;
788 DEBUG(4,("Servertype search: %8x\n",servertype
));
793 struct srv_info_struct
*s
;
798 fgets(line
,sizeof(line
)-1,f
);
799 if (!*line
) continue;
801 if (count
== alloced
) {
803 (*servers
) = (struct srv_info_struct
*)
804 Realloc(*servers
,sizeof(**servers
)*alloced
);
805 if (!(*servers
)) return(0);
806 bzero((char *)((*servers
)+count
),sizeof(**servers
)*(alloced
-count
));
808 s
= &(*servers
)[count
];
810 if (!next_token(&ptr
,s
->name
, NULL
)) continue;
811 if (!next_token(&ptr
,stype
, NULL
)) continue;
812 if (!next_token(&ptr
,s
->comment
, NULL
)) continue;
813 if (!next_token(&ptr
,s
->domain
, NULL
)) {
814 /* this allows us to cope with an old nmbd */
815 strcpy(s
->domain
,lp_workgroup());
818 if (sscanf(stype
,"%X",&s
->type
) != 1) {
819 DEBUG(4,("r:host file "));
823 /* doesn't match up: don't want it */
824 if (!(servertype
& s
->type
)) {
825 DEBUG(4,("r:serv type "));
829 if ((servertype
& SV_TYPE_DOMAIN_ENUM
) !=
830 (s
->type
& SV_TYPE_DOMAIN_ENUM
))
832 DEBUG(4,("s: dom mismatch "));
836 if (!strequal(domain
, s
->domain
) && !(servertype
& SV_TYPE_DOMAIN_ENUM
))
843 DEBUG(4,("**SV** %20s %8x %25s %15s\n",
844 s
->name
, s
->type
, s
->comment
, s
->domain
));
846 s
->server_added
= True
;
851 DEBUG(4,("%20s %8x %25s %15s\n",
852 s
->name
, s
->type
, s
->comment
, s
->domain
));
861 /*******************************************************************
862 fill in a server info structure
863 ******************************************************************/
864 static int fill_srv_info(struct srv_info_struct
*service
,
865 int uLevel
, char **buf
, int *buflen
,
866 char **stringbuf
, int *stringspace
, char *baseaddr
)
875 case 0: struct_len
= 16; break;
876 case 1: struct_len
= 26; break;
886 len
= strlen(service
->comment
)+1;
890 if (buflen
) *buflen
= struct_len
;
891 if (stringspace
) *stringspace
= len
;
892 return struct_len
+ len
;
897 if (*buflen
< struct_len
) return -1;
906 l2
= *buflen
- struct_len
;
908 if (!baseaddr
) baseaddr
= p
;
913 StrnCpy(p
,service
->name
,15);
917 StrnCpy(p
,service
->name
,15);
918 SIVAL(p
,18,service
->type
);
919 SIVAL(p
,22,PTR_DIFF(p2
,baseaddr
));
920 len
+= CopyAndAdvance(&p2
,service
->comment
,&l2
);
926 *buf
= p
+ struct_len
;
927 *buflen
-= struct_len
;
940 static BOOL
srv_comp(struct srv_info_struct
*s1
,struct srv_info_struct
*s2
)
942 return(strcmp(s1
->name
,s2
->name
));
945 /****************************************************************************
946 view list of servers available (or possibly domains). The info is
947 extracted from lists saved by nmbd on the local host
948 ****************************************************************************/
949 static BOOL
api_RNetServerEnum(int cnum
, uint16 vuid
, char *param
, char *data
,
950 int mdrcnt
, int mprcnt
, char **rdata
,
951 char **rparam
, int *rdata_len
, int *rparam_len
)
953 char *str1
= param
+2;
954 char *str2
= skip_string(str1
,1);
955 char *p
= skip_string(str2
,1);
956 int uLevel
= SVAL(p
,0);
957 int buf_len
= SVAL(p
,2);
958 uint32 servertype
= IVAL(p
,4);
960 int data_len
, fixed_len
, string_len
;
962 struct srv_info_struct
*servers
=NULL
;
963 int counted
=0,total
=0;
967 BOOL local_request
= servertype
& SV_TYPE_LOCAL_LIST_ONLY
;
969 if (servertype
== SV_TYPE_ALL
) servertype
&= ~SV_TYPE_DOMAIN_ENUM
;
971 domain_request
= ((servertype
& SV_TYPE_DOMAIN_ENUM
) != 0);
975 if (!prefix_ok(str1
,"WrLehD")) return False
;
976 if (!check_server_info(uLevel
,str2
)) return False
;
978 DEBUG(4, ("server request level: %s %8x ", str2
, servertype
));
979 DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request
)));
980 DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request
)));
982 if (strcmp(str1
, "WrLehDz") == 0) {
983 StrnCpy(domain
, p
, sizeof(fstring
)-1);
985 StrnCpy(domain
, lp_workgroup(), sizeof(fstring
)-1);
988 if (lp_browse_list())
989 total
= get_server_info(servertype
,&servers
,domain
);
991 data_len
= fixed_len
= string_len
= 0;
994 qsort(servers
,total
,sizeof(servers
[0]),QSORT_CAST srv_comp
);
999 for (i
=0;i
<total
;i
++)
1001 struct srv_info_struct
*s
= &servers
[i
];
1002 if (lastname
&& strequal(lastname
,s
->name
)) continue;
1004 data_len
+= fill_srv_info(s
,uLevel
,0,&f_len
,0,&s_len
,0);
1005 DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
1006 s
->name
, s
->type
, s
->comment
, s
->domain
));
1008 if (data_len
<= buf_len
) {
1011 string_len
+= s_len
;
1018 *rdata_len
= fixed_len
+ string_len
;
1019 *rdata
= REALLOC(*rdata
,*rdata_len
);
1020 bzero(*rdata
,*rdata_len
);
1022 p2
= (*rdata
) + fixed_len
; /* auxilliary data (strings) will go here */
1028 char *lastname
=NULL
;
1029 int count2
= counted
;
1030 for (i
= 0; i
< total
&& count2
;i
++)
1032 struct srv_info_struct
*s
= &servers
[i
];
1033 if (lastname
&& strequal(lastname
,s
->name
)) continue;
1035 fill_srv_info(s
,uLevel
,&p
,&f_len
,&p2
,&s_len
,*rdata
);
1036 DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
1037 s
->name
, s
->type
, s
->comment
, s
->domain
));
1043 *rparam
= REALLOC(*rparam
,*rparam_len
);
1044 SSVAL(*rparam
,0,NERR_Success
);
1046 SSVAL(*rparam
,4,counted
);
1047 SSVAL(*rparam
,6,counted
+missed
);
1049 if (servers
) free(servers
);
1051 DEBUG(3,("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n",
1052 domain
,uLevel
,counted
,counted
+missed
));
1058 /****************************************************************************
1059 get info about a share
1060 ****************************************************************************/
1061 static BOOL
check_share_info(int uLevel
, char* id
)
1065 if (strcmp(id
,"B13") != 0) return False
;
1068 if (strcmp(id
,"B13BWz") != 0) return False
;
1071 if (strcmp(id
,"B13BWzWWWzB9B") != 0) return False
;
1074 if (strcmp(id
,"B13BWzWWWzB9BB9BWzWWzWW") != 0) return False
;
1076 default: return False
;
1081 static int fill_share_info(int cnum
, int snum
, int uLevel
,
1082 char** buf
, int* buflen
,
1083 char** stringbuf
, int* stringspace
, char* baseaddr
)
1092 case 0: struct_len
= 13; break;
1093 case 1: struct_len
= 20; break;
1094 case 2: struct_len
= 40; break;
1095 case 91: struct_len
= 68; break;
1103 if (uLevel
> 0) len
+= StrlenExpanded(cnum
,snum
,lp_comment(snum
));
1104 if (uLevel
> 1) len
+= strlen(lp_pathname(snum
)) + 1;
1105 if (buflen
) *buflen
= struct_len
;
1106 if (stringspace
) *stringspace
= len
;
1107 return struct_len
+ len
;
1112 if ((*buflen
) < struct_len
) return -1;
1120 p2
= p
+ struct_len
;
1121 l2
= (*buflen
) - struct_len
;
1123 if (!baseaddr
) baseaddr
= p
;
1125 StrnCpy(p
,lp_servicename(snum
),13);
1131 type
= STYPE_DISKTREE
;
1132 if (lp_print_ok(snum
)) type
= STYPE_PRINTQ
;
1133 if (strequal("IPC$",lp_servicename(snum
))) type
= STYPE_IPC
;
1134 SSVAL(p
,14,type
); /* device type */
1135 SIVAL(p
,16,PTR_DIFF(p2
,baseaddr
));
1136 len
+= CopyExpanded(cnum
,snum
,&p2
,lp_comment(snum
),&l2
);
1141 SSVAL(p
,20,ACCESS_READ
|ACCESS_WRITE
|ACCESS_CREATE
); /* permissions */
1142 SSVALS(p
,22,-1); /* max uses */
1143 SSVAL(p
,24,1); /* current uses */
1144 SIVAL(p
,26,PTR_DIFF(p2
,baseaddr
)); /* local pathname */
1145 len
+= CopyAndAdvance(&p2
,lp_pathname(snum
),&l2
);
1146 memset(p
+30,0,SHPWLEN
+2); /* passwd (reserved), pad field */
1151 memset(p
+40,0,SHPWLEN
+2);
1163 (*buf
) = p
+ struct_len
;
1164 (*buflen
) -= struct_len
;
1166 (*stringspace
) = l2
;
1176 static BOOL
api_RNetShareGetInfo(int cnum
,uint16 vuid
, char *param
,char *data
,
1177 int mdrcnt
,int mprcnt
,
1178 char **rdata
,char **rparam
,
1179 int *rdata_len
,int *rparam_len
)
1181 char *str1
= param
+2;
1182 char *str2
= skip_string(str1
,1);
1183 char *netname
= skip_string(str2
,1);
1184 char *p
= skip_string(netname
,1);
1185 int uLevel
= SVAL(p
,0);
1186 int snum
= find_service(netname
);
1188 if (snum
< 0) return False
;
1190 /* check it's a supported varient */
1191 if (!prefix_ok(str1
,"zWrLh")) return False
;
1192 if (!check_share_info(uLevel
,str2
)) return False
;
1194 *rdata
= REALLOC(*rdata
,mdrcnt
);
1196 *rdata_len
= fill_share_info(cnum
,snum
,uLevel
,&p
,&mdrcnt
,0,0,0);
1197 if (*rdata_len
< 0) return False
;
1200 *rparam
= REALLOC(*rparam
,*rparam_len
);
1201 SSVAL(*rparam
,0,NERR_Success
);
1202 SSVAL(*rparam
,2,0); /* converter word */
1203 SSVAL(*rparam
,4,*rdata_len
);
1208 /****************************************************************************
1209 view list of shares available
1210 ****************************************************************************/
1211 static BOOL
api_RNetShareEnum(int cnum
,uint16 vuid
, char *param
,char *data
,
1212 int mdrcnt
,int mprcnt
,
1213 char **rdata
,char **rparam
,
1214 int *rdata_len
,int *rparam_len
)
1216 char *str1
= param
+2;
1217 char *str2
= skip_string(str1
,1);
1218 char *p
= skip_string(str2
,1);
1219 int uLevel
= SVAL(p
,0);
1220 int buf_len
= SVAL(p
,2);
1222 int count
=lp_numservices();
1223 int total
=0,counted
=0;
1225 int data_len
, fixed_len
, string_len
;
1228 if (!prefix_ok(str1
,"WrLeh")) return False
;
1229 if (!check_share_info(uLevel
,str2
)) return False
;
1231 data_len
= fixed_len
= string_len
= 0;
1232 for (i
=0;i
<count
;i
++)
1233 if (lp_browseable(i
) && lp_snum_ok(i
))
1236 data_len
+= fill_share_info(cnum
,i
,uLevel
,0,&f_len
,0,&s_len
,0);
1237 if (data_len
<= buf_len
)
1241 string_len
+= s_len
;
1244 *rdata_len
= fixed_len
+ string_len
;
1245 *rdata
= REALLOC(*rdata
,*rdata_len
);
1246 memset(*rdata
,0,*rdata_len
);
1248 p2
= (*rdata
) + fixed_len
; /* auxillery data (strings) will go here */
1252 for (i
= 0; i
< count
;i
++)
1253 if (lp_browseable(i
) && lp_snum_ok(i
))
1254 if (fill_share_info(cnum
,i
,uLevel
,&p
,&f_len
,&p2
,&s_len
,*rdata
) < 0)
1258 *rparam
= REALLOC(*rparam
,*rparam_len
);
1259 SSVAL(*rparam
,0,NERR_Success
);
1261 SSVAL(*rparam
,4,counted
);
1262 SSVAL(*rparam
,6,total
);
1264 DEBUG(3,("RNetShareEnum gave %d entries of %d (%d %d %d %d)\n",
1265 counted
,total
,uLevel
,
1266 buf_len
,*rdata_len
,mdrcnt
));
1272 /****************************************************************************
1273 get the time of day info
1274 ****************************************************************************/
1275 static BOOL
api_NetRemoteTOD(int cnum
,uint16 vuid
, char *param
,char *data
,
1276 int mdrcnt
,int mprcnt
,
1277 char **rdata
,char **rparam
,
1278 int *rdata_len
,int *rparam_len
)
1282 *rparam
= REALLOC(*rparam
,*rparam_len
);
1285 *rdata
= REALLOC(*rdata
,*rdata_len
);
1287 SSVAL(*rparam
,0,NERR_Success
);
1288 SSVAL(*rparam
,2,0); /* converter word */
1294 time_t unixdate
= time(NULL
);
1296 put_dos_date3(p
,0,unixdate
); /* this is the time that is looked at
1297 by NT in a "net time" operation,
1298 it seems to ignore the one below */
1300 /* the client expects to get localtime, not GMT, in this bit
1301 (I think, this needs testing) */
1302 t
= LocalTime(&unixdate
);
1304 SIVAL(p
,4,0); /* msecs ? */
1305 CVAL(p
,8) = t
->tm_hour
;
1306 CVAL(p
,9) = t
->tm_min
;
1307 CVAL(p
,10) = t
->tm_sec
;
1308 CVAL(p
,11) = 0; /* hundredths of seconds */
1309 SSVALS(p
,12,TimeDiff(unixdate
)/60); /* timezone in minutes from GMT */
1310 SSVAL(p
,14,10000); /* timer interval in 0.0001 of sec */
1311 CVAL(p
,16) = t
->tm_mday
;
1312 CVAL(p
,17) = t
->tm_mon
+ 1;
1313 SSVAL(p
,18,1900+t
->tm_year
);
1314 CVAL(p
,20) = t
->tm_wday
;
1321 /****************************************************************************
1322 set the user password
1323 ****************************************************************************/
1324 static BOOL
api_SetUserPassword(int cnum
,uint16 vuid
, char *param
,char *data
,
1325 int mdrcnt
,int mprcnt
,
1326 char **rdata
,char **rparam
,
1327 int *rdata_len
,int *rparam_len
)
1329 char *p
= skip_string(param
+2,2);
1331 fstring pass1
,pass2
;
1335 p
= skip_string(p
,1);
1337 StrnCpy(pass1
,p
,16);
1338 StrnCpy(pass2
,p
+16,16);
1341 *rparam
= REALLOC(*rparam
,*rparam_len
);
1345 SSVAL(*rparam
,0,NERR_badpass
);
1346 SSVAL(*rparam
,2,0); /* converter word */
1348 DEBUG(3,("Set password for <%s>\n",user
));
1350 if (password_ok(user
,pass1
,strlen(pass1
),NULL
) &&
1351 chgpasswd(user
,pass1
,pass2
))
1353 SSVAL(*rparam
,0,NERR_Success
);
1356 bzero(pass1
,sizeof(fstring
));
1357 bzero(pass2
,sizeof(fstring
));
1362 /****************************************************************************
1365 ****************************************************************************/
1366 static BOOL
api_RDosPrintJobDel(int cnum
,uint16 vuid
, char *param
,char *data
,
1367 int mdrcnt
,int mprcnt
,
1368 char **rdata
,char **rparam
,
1369 int *rdata_len
,int *rparam_len
)
1371 int function
= SVAL(param
,0);
1372 char *str1
= param
+2;
1373 char *str2
= skip_string(str1
,1);
1374 char *p
= skip_string(str2
,1);
1375 int jobid
= (SVAL(p
,0)&0xFF); /* the snum and jobid are encoded
1376 by the print queue api */
1377 int snum
= (SVAL(p
,0)>>8);
1381 /* check it's a supported varient */
1382 if (!(strcsequal(str1
,"W") && strcsequal(str2
,"")))
1386 *rparam
= REALLOC(*rparam
,*rparam_len
);
1390 SSVAL(*rparam
,0,NERR_Success
);
1392 if (snum
>= 0 && VALID_SNUM(snum
))
1394 print_queue_struct
*queue
=NULL
;
1396 count
= get_printqueue(snum
,cnum
,&queue
,NULL
);
1398 for (i
=0;i
<count
;i
++)
1399 if ((queue
[i
].job
%0xFF) == jobid
)
1402 case 81: /* delete */
1403 DEBUG(3,("Deleting queue entry %d\n",queue
[i
].job
));
1404 del_printqueue(cnum
,snum
,queue
[i
].job
);
1406 case 82: /* pause */
1407 case 83: /* resume */
1408 DEBUG(3,("%s queue entry %d\n",
1409 (function
==82?"pausing":"resuming"),queue
[i
].job
));
1410 status_printjob(cnum
,snum
,queue
[i
].job
,
1411 (function
==82?LPQ_PAUSED
:LPQ_QUEUED
));
1418 SSVAL(*rparam
,0,NERR_JobNotFound
);
1420 if (queue
) free(queue
);
1423 SSVAL(*rparam
,2,0); /* converter word */
1428 static BOOL
api_WPrintQueuePurge(int cnum
,uint16 vuid
, char *param
,char *data
,
1429 int mdrcnt
,int mprcnt
,
1430 char **rdata
,char **rparam
,
1431 int *rdata_len
,int *rparam_len
)
1433 char *str1
= param
+2;
1434 char *str2
= skip_string(str1
,1);
1435 char *QueueName
= skip_string(str2
,1);
1438 /* check it's a supported varient */
1439 if (!(strcsequal(str1
,"z") && strcsequal(str2
,"")))
1443 *rparam
= REALLOC(*rparam
,*rparam_len
);
1447 SSVAL(*rparam
,0,NERR_Success
);
1448 SSVAL(*rparam
,2,0); /* converter word */
1450 snum
= lp_servicenumber(QueueName
);
1451 if (snum
< 0 && pcap_printername_ok(QueueName
,NULL
)) {
1452 int pnum
= lp_servicenumber(PRINTERS_NAME
);
1454 lp_add_printer(QueueName
,pnum
);
1455 snum
= lp_servicenumber(QueueName
);
1459 if (snum
>= 0 && VALID_SNUM(snum
)) {
1460 print_queue_struct
*queue
=NULL
;
1464 count
= get_printqueue(snum
,cnum
,&queue
,NULL
);
1465 for (i
= 0; i
< count
; i
++)
1466 del_printqueue(cnum
,snum
,queue
[i
].job
);
1468 if (queue
) free(queue
);
1471 DEBUG(3,("Print queue purge, queue=%s\n",QueueName
));
1477 /****************************************************************************
1478 set the property of a print job (undocumented?)
1479 ? function = 0xb -> set name of print job
1480 ? function = 0x6 -> move print job up/down
1481 Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz>
1482 or <WWsTP> <WB21BB16B10zWWzDDz>
1483 ****************************************************************************/
1484 static int check_printjob_info(struct pack_desc
* desc
,
1485 int uLevel
, char* id
)
1487 desc
->subformat
= NULL
;
1489 case 0: desc
->format
= "W"; break;
1490 case 1: desc
->format
= "WB21BB16B10zWWzDDz"; break;
1491 case 2: desc
->format
= "WWzWWDDzz"; break;
1492 case 3: desc
->format
= "WWzWWDDzzzzzzzzzzlz"; break;
1493 default: return False
;
1495 if (strcmp(desc
->format
,id
) != 0) return False
;
1499 static BOOL
api_PrintJobInfo(int cnum
,uint16 vuid
,char *param
,char *data
,
1500 int mdrcnt
,int mprcnt
,
1501 char **rdata
,char **rparam
,
1502 int *rdata_len
,int *rparam_len
)
1504 struct pack_desc desc
;
1505 char *str1
= param
+2;
1506 char *str2
= skip_string(str1
,1);
1507 char *p
= skip_string(str2
,1);
1508 int jobid
= (SVAL(p
,0)&0xFF); /* the snum and jobid are encoded
1509 by the print queue api */
1510 int snum
= (SVAL(p
,0)>>8);
1511 int uLevel
= SVAL(p
,2);
1512 int function
= SVAL(p
,4); /* what is this ?? */
1517 *rparam
= REALLOC(*rparam
,*rparam_len
);
1521 /* check it's a supported varient */
1522 if ((strcmp(str1
,"WWsTP")) || (!check_printjob_info(&desc
,uLevel
,str2
)))
1526 case 0x6: /* change job place in the queue, data gives the new place */
1527 if (snum
>= 0 && VALID_SNUM(snum
))
1529 print_queue_struct
*queue
=NULL
;
1533 count
= get_printqueue(snum
,cnum
,&queue
,NULL
);
1534 for (i
=0;i
<count
;i
++) /* find job */
1535 if ((queue
[i
].job
%0xFF) == jobid
) break;
1538 desc
.errcode
=NERR_JobNotFound
;
1539 if (queue
) free(queue
);
1542 desc
.errcode
=NERR_Success
;
1546 int place
= SVAL(data
,0);
1547 /* we currently have no way of doing this. Can any unix do it? */
1548 if (i
< place
) /* move down */;
1549 else if (i
> place
) /* move up */;
1552 desc
.errcode
=NERR_notsupported
; /* not yet supported */
1553 if (queue
) free(queue
);
1556 else desc
.errcode
=NERR_JobNotFound
;
1558 case 0xb: /* change print job name, data gives the name */
1559 /* jobid, snum should be zero */
1566 if (issafe(*s
)) name
[l
++] = *s
;
1571 DEBUG(3,("Setting print name to %s\n",name
));
1573 for (i
=0;i
<MAX_OPEN_FILES
;i
++)
1574 if (Files
[i
].open
&& Files
[i
].print_file
)
1580 if (!become_user(Files
[i
].cnum
,vuid
) ||
1581 !become_service(Files
[i
].cnum
,True
))
1584 if (sys_rename(Files
[i
].name
,name
) == 0)
1585 string_set(&Files
[i
].name
,name
);
1589 desc
.errcode
=NERR_Success
;
1592 default: /* not implemented */
1596 SSVALS(*rparam
,0,desc
.errcode
);
1597 SSVAL(*rparam
,2,0); /* converter word */
1603 /****************************************************************************
1604 get info about the server
1605 ****************************************************************************/
1606 static BOOL
api_RNetServerGetInfo(int cnum
,uint16 vuid
, char *param
,char *data
,
1607 int mdrcnt
,int mprcnt
,
1608 char **rdata
,char **rparam
,
1609 int *rdata_len
,int *rparam_len
)
1611 char *str1
= param
+2;
1612 char *str2
= skip_string(str1
,1);
1613 char *p
= skip_string(str2
,1);
1614 int uLevel
= SVAL(p
,0);
1618 DEBUG(4,("NetServerGetInfo level %d\n",uLevel
));
1620 /* check it's a supported varient */
1621 if (!prefix_ok(str1
,"WrLh")) return False
;
1624 if (strcmp(str2
,"B16") != 0) return False
;
1628 if (strcmp(str2
,"B16BBDz") != 0) return False
;
1632 if (strcmp(str2
,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWz")
1637 if (strcmp(str2
,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWzDWz")
1642 if (strcmp(str2
,"DN") != 0) return False
;
1646 if (strcmp(str2
,"B16BBDzWWzzz") != 0) return False
;
1649 default: return False
;
1652 *rdata_len
= mdrcnt
;
1653 *rdata
= REALLOC(*rdata
,*rdata_len
);
1656 p2
= p
+ struct_len
;
1658 StrnCpy(p
,local_machine
,16);
1664 struct srv_info_struct
*servers
=NULL
;
1667 uint32 servertype
=DFLT_SERVER_TYPE
;
1669 strcpy(comment
,lp_serverstring());
1671 if ((count
=get_server_info(SV_TYPE_ALL
,&servers
,lp_workgroup()))>0) {
1672 for (i
=0;i
<count
;i
++)
1673 if (strequal(servers
[i
].name
,local_machine
))
1675 servertype
= servers
[i
].type
;
1676 strcpy(comment
,servers
[i
].comment
);
1679 if (servers
) free(servers
);
1681 SCVAL(p
,0,MAJOR_VERSION
);
1682 SCVAL(p
,1,MINOR_VERSION
);
1683 SIVAL(p
,2,servertype
);
1685 if (mdrcnt
== struct_len
) {
1688 SIVAL(p
,6,PTR_DIFF(p2
,*rdata
));
1689 standard_sub(cnum
,comment
);
1690 StrnCpy(p2
,comment
,MAX(mdrcnt
- struct_len
,0));
1691 p2
= skip_string(p2
,1);
1696 return False
; /* not yet implemented */
1699 *rdata_len
= PTR_DIFF(p2
,*rdata
);
1702 *rparam
= REALLOC(*rparam
,*rparam_len
);
1703 SSVAL(*rparam
,0,NERR_Success
);
1704 SSVAL(*rparam
,2,0); /* converter word */
1705 SSVAL(*rparam
,4,*rdata_len
);
1711 /****************************************************************************
1712 get info about the server
1713 ****************************************************************************/
1714 static BOOL
api_NetWkstaGetInfo(int cnum
,uint16 vuid
, char *param
,char *data
,
1715 int mdrcnt
,int mprcnt
,
1716 char **rdata
,char **rparam
,
1717 int *rdata_len
,int *rparam_len
)
1719 char *str1
= param
+2;
1720 char *str2
= skip_string(str1
,1);
1721 char *p
= skip_string(str2
,1);
1723 extern pstring sesssetup_user
;
1724 int level
= SVAL(p
,0);
1726 DEBUG(4,("NetWkstaGetInfo level %d\n",level
));
1729 *rparam
= REALLOC(*rparam
,*rparam_len
);
1731 /* check it's a supported varient */
1732 if (!(level
==10 && strcsequal(str1
,"WrLh") && strcsequal(str2
,"zzzBBzz")))
1735 *rdata_len
= mdrcnt
+ 1024;
1736 *rdata
= REALLOC(*rdata
,*rdata_len
);
1738 SSVAL(*rparam
,0,NERR_Success
);
1739 SSVAL(*rparam
,2,0); /* converter word */
1745 SIVAL(p
,0,PTR_DIFF(p2
,*rdata
)); /* host name */
1746 strcpy(p2
,local_machine
);
1748 p2
= skip_string(p2
,1);
1751 SIVAL(p
,0,PTR_DIFF(p2
,*rdata
));
1752 strcpy(p2
,sesssetup_user
);
1753 p2
= skip_string(p2
,1);
1756 SIVAL(p
,0,PTR_DIFF(p2
,*rdata
)); /* login domain */
1757 strcpy(p2
,lp_workgroup());
1759 p2
= skip_string(p2
,1);
1762 SCVAL(p
,0,MAJOR_VERSION
); /* system version - e.g 4 in 4.1 */
1763 SCVAL(p
,1,MINOR_VERSION
); /* system version - e.g .1 in 4.1 */
1766 SIVAL(p
,0,PTR_DIFF(p2
,*rdata
));
1767 strcpy(p2
,lp_workgroup()); /* don't know. login domain?? */
1768 p2
= skip_string(p2
,1);
1771 SIVAL(p
,0,PTR_DIFF(p2
,*rdata
)); /* don't know */
1773 p2
= skip_string(p2
,1);
1776 *rdata_len
= PTR_DIFF(p2
,*rdata
);
1778 SSVAL(*rparam
,4,*rdata_len
);
1783 /****************************************************************************
1784 get info about a user
1786 struct user_info_11 {
1787 char usri11_name[21]; 0-20
1789 char *usri11_comment; 22-25
1790 char *usri11_usr_comment; 26-29
1791 unsigned short usri11_priv; 30-31
1792 unsigned long usri11_auth_flags; 32-35
1793 long usri11_password_age; 36-39
1794 char *usri11_homedir; 40-43
1795 char *usri11_parms; 44-47
1796 long usri11_last_logon; 48-51
1797 long usri11_last_logoff; 52-55
1798 unsigned short usri11_bad_pw_count; 56-57
1799 unsigned short usri11_num_logons; 58-59
1800 char *usri11_logon_server; 60-63
1801 unsigned short usri11_country_code; 64-65
1802 char *usri11_workstations; 66-69
1803 unsigned long usri11_max_storage; 70-73
1804 unsigned short usri11_units_per_week; 74-75
1805 unsigned char *usri11_logon_hours; 76-79
1806 unsigned short usri11_code_page; 80-81
1811 usri11_name specifies the user name for which information is retireved
1813 usri11_pad aligns the next data structure element to a word boundary
1815 usri11_comment is a null terminated ASCII comment
1817 usri11_user_comment is a null terminated ASCII comment about the user
1819 usri11_priv specifies the level of the privilege assigned to the user.
1820 The possible values are:
1822 Name Value Description
1823 USER_PRIV_GUEST 0 Guest privilege
1824 USER_PRIV_USER 1 User privilege
1825 USER_PRV_ADMIN 2 Administrator privilege
1827 usri11_auth_flags specifies the account operator privileges. The
1828 possible values are:
1830 Name Value Description
1831 AF_OP_PRINT 0 Print operator
1834 Leach, Naik [Page 28]
\f
1837 INTERNET-DRAFT CIFS Remote Admin Protocol January 10, 1997
1840 AF_OP_COMM 1 Communications operator
1841 AF_OP_SERVER 2 Server operator
1842 AF_OP_ACCOUNTS 3 Accounts operator
1845 usri11_password_age specifies how many seconds have elapsed since the
1846 password was last changed.
1848 usri11_home_dir points to a null terminated ASCII string that contains
1849 the path name of the user's home directory.
1851 usri11_parms points to a null terminated ASCII string that is set
1852 aside for use by applications.
1854 usri11_last_logon specifies the time when the user last logged on.
1855 This value is stored as the number of seconds elapsed since
1856 00:00:00, January 1, 1970.
1858 usri11_last_logoff specifies the time when the user last logged off.
1859 This value is stored as the number of seconds elapsed since
1860 00:00:00, January 1, 1970. A value of 0 means the last logoff
1863 usri11_bad_pw_count specifies the number of incorrect passwords
1864 entered since the last successful logon.
1866 usri11_log1_num_logons specifies the number of times this user has
1867 logged on. A value of -1 means the number of logons is unknown.
1869 usri11_logon_server points to a null terminated ASCII string that
1870 contains the name of the server to which logon requests are sent.
1871 A null string indicates logon requests should be sent to the
1874 usri11_country_code specifies the country code for the user's language
1877 usri11_workstations points to a null terminated ASCII string that
1878 contains the names of workstations the user may log on from.
1879 There may be up to 8 workstations, with the names separated by
1880 commas. A null strings indicates there are no restrictions.
1882 usri11_max_storage specifies the maximum amount of disk space the user
1883 can occupy. A value of 0xffffffff indicates there are no
1886 usri11_units_per_week specifies the equal number of time units into
1887 which a week is divided. This value must be equal to 168.
1889 usri11_logon_hours points to a 21 byte (168 bits) string that
1890 specifies the time during which the user can log on. Each bit
1891 represents one unique hour in a week. The first bit (bit 0, word
1892 0) is Sunday, 0:00 to 0:59, the second bit (bit 1, word 0) is
1896 Leach, Naik [Page 29]
\f
1899 INTERNET-DRAFT CIFS Remote Admin Protocol January 10, 1997
1902 Sunday, 1:00 to 1:59 and so on. A null pointer indicates there
1903 are no restrictions.
1905 usri11_code_page specifies the code page for the user's language of
1908 All of the pointers in this data structure need to be treated
1909 specially. The pointer is a 32 bit pointer. The higher 16 bits need
1910 to be ignored. The converter word returned in the parameters section
1911 needs to be subtracted from the lower 16 bits to calculate an offset
1912 into the return buffer where this ASCII string resides.
1914 There is no auxiliary data in the response.
1916 ****************************************************************************/
1918 #define usri11_name 0
1919 #define usri11_pad 21
1920 #define usri11_comment 22
1921 #define usri11_usr_comment 26
1922 #define usri11_full_name 30
1923 #define usri11_priv 34
1924 #define usri11_auth_flags 36
1925 #define usri11_password_age 40
1926 #define usri11_homedir 44
1927 #define usri11_parms 48
1928 #define usri11_last_logon 52
1929 #define usri11_last_logoff 56
1930 #define usri11_bad_pw_count 60
1931 #define usri11_num_logons 62
1932 #define usri11_logon_server 64
1933 #define usri11_country_code 68
1934 #define usri11_workstations 70
1935 #define usri11_max_storage 74
1936 #define usri11_units_per_week 78
1937 #define usri11_logon_hours 80
1938 #define usri11_code_page 84
1939 #define usri11_end 86
1941 #define USER_PRIV_GUEST 0
1942 #define USER_PRIV_USER 1
1943 #define USER_PRIV_ADMIN 2
1945 #define AF_OP_PRINT 0
1946 #define AF_OP_COMM 1
1947 #define AF_OP_SERVER 2
1948 #define AF_OP_ACCOUNTS 3
1950 static BOOL
api_RNetUserGetInfo(int cnum
,uint16 vuid
, char *param
,char *data
,
1951 int mdrcnt
,int mprcnt
,
1952 char **rdata
,char **rparam
,
1953 int *rdata_len
,int *rparam_len
)
1955 char *str1
= param
+2;
1956 char *str2
= skip_string(str1
,1);
1957 char *UserName
= skip_string(str2
,1);
1958 char *p
= skip_string(UserName
,1);
1959 int uLevel
= SVAL(p
,0);
1963 *rparam
= REALLOC(*rparam
,*rparam_len
);
1965 /* check it's a supported varient */
1966 if (strcmp(str1
,"zWrLh") != 0) return False
;
1969 case 0: p2
= "B21"; break;
1970 case 1: p2
= "B21BB16DWzzWz"; break;
1971 case 2: p2
= "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
1972 case 10: p2
= "B21Bzzz"; break;
1973 case 11: p2
= "B21BzzzWDDzzDDWWzWzDWb21W"; break;
1974 default: return False
;
1977 if (strcmp(p2
,str2
) != 0) return False
;
1979 *rdata_len
= mdrcnt
+ 1024;
1980 *rdata
= REALLOC(*rdata
,*rdata_len
);
1982 SSVAL(*rparam
,0,NERR_Success
);
1983 SSVAL(*rparam
,2,0); /* converter word */
1986 p2
= p
+ usri11_end
;
1989 strcpy(p
+usri11_name
,UserName
); /* 21 bytes - user name */
1993 SCVAL(p
,usri11_pad
,0); /* padding - 1 byte */
1998 SIVAL(p
,usri11_comment
,PTR_DIFF(p2
,p
)); /* comment */
1999 strcpy(p2
,"Comment");
2000 p2
= skip_string(p2
,1);
2002 SIVAL(p
,usri11_usr_comment
,PTR_DIFF(p2
,p
)); /* user_comment */
2003 strcpy(p2
,"UserComment");
2004 p2
= skip_string(p2
,1);
2006 /* EEK! the cifsrap.txt doesn't have this in!!!! */
2007 SIVAL(p
,usri11_full_name
,PTR_DIFF(p2
,p
)); /* full name */
2009 strcpy(p2
,"FullName");
2011 strcpy(p2
,UserName
); /* suggest copying the user name, for now... */
2012 p2
= skip_string(p2
,1);
2014 if (uLevel
== 11) /* modelled after NTAS 3.51 reply */
2016 SSVAL(p
,usri11_priv
,Connections
[cnum
].admin_user
?USER_PRIV_ADMIN
:USER_PRIV_USER
);
2017 SIVAL(p
,usri11_auth_flags
,AF_OP_PRINT
); /* auth flags */
2018 SIVALS(p
,usri11_password_age
,0xffffffff); /* password age */
2019 SIVAL(p
,usri11_homedir
,PTR_DIFF(p2
,p
)); /* home dir */
2020 if (*lp_logon_path())
2022 strcpy(p2
,lp_logon_path());
2026 strcpy(p2
,"\\\\%L\\%U");
2028 standard_sub_basic(p2
);
2029 p2
= skip_string(p2
,1);
2030 SIVAL(p
,usri11_parms
,PTR_DIFF(p2
,p
)); /* parms */
2032 p2
= skip_string(p2
,1);
2033 SIVAL(p
,usri11_last_logon
,0); /* last logon */
2034 SIVAL(p
,usri11_last_logoff
,0); /* last logoff */
2035 SSVALS(p
,usri11_bad_pw_count
,0xffffffff); /* bad pw counts */
2036 SSVALS(p
,usri11_num_logons
,0xffffffff); /* num logons */
2037 SIVAL(p
,usri11_logon_server
,PTR_DIFF(p2
,p
)); /* logon server */
2039 p2
= skip_string(p2
,1);
2040 SSVAL(p
,usri11_country_code
,0); /* country code */
2042 SIVAL(p
,usri11_workstations
,PTR_DIFF(p2
,p
)); /* workstations */
2044 p2
= skip_string(p2
,1);
2046 SIVALS(p
,usri11_max_storage
,0xffffffff); /* max storage */
2047 SSVAL(p
,usri11_units_per_week
,168); /* units per week */
2048 SIVAL(p
,usri11_logon_hours
,PTR_DIFF(p2
,p
)); /* logon hours */
2050 /* a simple way to get logon hours at all times. */
2052 SCVAL(p2
,21,0); /* fix zero termination */
2053 p2
= skip_string(p2
,1);
2055 SSVAL(p
,usri11_code_page
,0); /* code page */
2057 if (uLevel
== 1 || uLevel
== 2)
2059 memset(p
+22,' ',16); /* password */
2060 SIVALS(p
,38,-1); /* password age */
2062 Connections
[cnum
].admin_user
?USER_PRIV_ADMIN
:USER_PRIV_USER
);
2063 SIVAL(p
,44,PTR_DIFF(p2
,*rdata
)); /* home dir */
2064 if (*lp_logon_path())
2066 strcpy(p2
,lp_logon_path());
2070 strcpy(p2
,"\\\\%L\\%U");
2072 standard_sub_basic(p2
);
2073 p2
= skip_string(p2
,1);
2074 SIVAL(p
,48,PTR_DIFF(p2
,*rdata
)); /* comment */
2076 SSVAL(p
,52,0); /* flags */
2077 SIVAL(p
,54,0); /* script_path */
2080 SIVAL(p
,60,0); /* auth_flags */
2081 SIVAL(p
,64,PTR_DIFF(p2
,*rdata
)); /* full_name */
2082 strcpy(p2
,"<Full Name>");
2083 p2
= skip_string(p2
,1);
2084 SIVAL(p
,68,0); /* urs_comment */
2085 SIVAL(p
,72,PTR_DIFF(p2
,*rdata
)); /* parms */
2087 p2
= skip_string(p2
,1);
2088 SIVAL(p
,76,0); /* workstations */
2089 SIVAL(p
,80,0); /* last_logon */
2090 SIVAL(p
,84,0); /* last_logoff */
2091 SIVALS(p
,88,-1); /* acct_expires */
2092 SIVALS(p
,92,-1); /* max_storage */
2093 SSVAL(p
,96,168); /* units_per_week */
2094 SIVAL(p
,98,PTR_DIFF(p2
,*rdata
)); /* logon_hours */
2097 SSVALS(p
,102,-1); /* bad_pw_count */
2098 SSVALS(p
,104,-1); /* num_logons */
2099 SIVAL(p
,106,PTR_DIFF(p2
,*rdata
)); /* logon_server */
2100 strcpy(p2
,"\\\\%L");
2101 standard_sub_basic(p2
);
2102 p2
= skip_string(p2
,1);
2103 SSVAL(p
,110,49); /* country_code */
2104 SSVAL(p
,112,860); /* code page */
2108 *rdata_len
= PTR_DIFF(p2
,*rdata
);
2110 SSVAL(*rparam
,4,*rdata_len
); /* is this right?? */
2115 /*******************************************************************
2116 get groups that a user is a member of
2117 ******************************************************************/
2118 static BOOL
api_NetUserGetGroups(int cnum
,uint16 vuid
, char *param
,char *data
,
2119 int mdrcnt
,int mprcnt
,
2120 char **rdata
,char **rparam
,
2121 int *rdata_len
,int *rparam_len
)
2123 char *str1
= param
+2;
2124 char *str2
= skip_string(str1
,1);
2125 char *UserName
= skip_string(str2
,1);
2126 char *p
= skip_string(UserName
,1);
2127 int uLevel
= SVAL(p
,0);
2132 *rparam
= REALLOC(*rparam
,*rparam_len
);
2134 /* check it's a supported varient */
2135 if (strcmp(str1
,"zWrLeh") != 0) return False
;
2137 case 0: p2
= "B21"; break;
2138 default: return False
;
2140 if (strcmp(p2
,str2
) != 0) return False
;
2142 *rdata_len
= mdrcnt
+ 1024;
2143 *rdata
= REALLOC(*rdata
,*rdata_len
);
2145 SSVAL(*rparam
,0,NERR_Success
);
2146 SSVAL(*rparam
,2,0); /* converter word */
2150 /* XXXX we need a real SAM database some day */
2151 strcpy(p
,"Users"); p
+= 21; count
++;
2152 strcpy(p
,"Domain Users"); p
+= 21; count
++;
2153 strcpy(p
,"Guests"); p
+= 21; count
++;
2154 strcpy(p
,"Domain Guests"); p
+= 21; count
++;
2156 *rdata_len
= PTR_DIFF(p
,*rdata
);
2158 SSVAL(*rparam
,4,count
); /* is this right?? */
2159 SSVAL(*rparam
,6,count
); /* is this right?? */
2165 static BOOL
api_WWkstaUserLogon(int cnum
,uint16 vuid
, char *param
,char *data
,
2166 int mdrcnt
,int mprcnt
,
2167 char **rdata
,char **rparam
,
2168 int *rdata_len
,int *rparam_len
)
2170 char *str1
= param
+2;
2171 char *str2
= skip_string(str1
,1);
2172 char *p
= skip_string(str2
,1);
2174 struct pack_desc desc
;
2180 bzero(&desc
,sizeof(desc
));
2182 DEBUG(3,("WWkstaUserLogon uLevel=%d name=%s\n",uLevel
,name
));
2184 /* check it's a supported varient */
2185 if (strcmp(str1
,"OOWb54WrLh") != 0) return False
;
2186 if (uLevel
!= 1 || strcmp(str2
,"WB21BWDWWDDDDDDDzzzD") != 0) return False
;
2187 if (mdrcnt
> 0) *rdata
= REALLOC(*rdata
,mdrcnt
);
2189 desc
.buflen
= mdrcnt
;
2190 desc
.subformat
= NULL
;
2193 if (init_package(&desc
,1,0))
2195 PACKI(&desc
,"W",0); /* code */
2196 PACKS(&desc
,"B21",name
); /* eff. name */
2197 PACKS(&desc
,"B",""); /* pad */
2199 Connections
[cnum
].admin_user
?USER_PRIV_ADMIN
:USER_PRIV_USER
);
2200 PACKI(&desc
,"D",0); /* auth flags XXX */
2201 PACKI(&desc
,"W",0); /* num logons */
2202 PACKI(&desc
,"W",0); /* bad pw count */
2203 PACKI(&desc
,"D",0); /* last logon */
2204 PACKI(&desc
,"D",-1); /* last logoff */
2205 PACKI(&desc
,"D",-1); /* logoff time */
2206 PACKI(&desc
,"D",-1); /* kickoff time */
2207 PACKI(&desc
,"D",0); /* password age */
2208 PACKI(&desc
,"D",0); /* password can change */
2209 PACKI(&desc
,"D",-1); /* password must change */
2212 strcpy(mypath
,"\\\\");
2213 strcat(mypath
,local_machine
);
2215 PACKS(&desc
,"z",mypath
); /* computer */
2217 PACKS(&desc
,"z",lp_workgroup());/* domain */
2218 PACKS(&desc
,"z",lp_logon_script()); /* script path */
2219 PACKI(&desc
,"D",0x00000000); /* reserved */
2222 *rdata_len
= desc
.usedlen
;
2224 *rparam
= REALLOC(*rparam
,*rparam_len
);
2225 SSVALS(*rparam
,0,desc
.errcode
);
2227 SSVAL(*rparam
,4,desc
.neededlen
);
2229 DEBUG(4,("WWkstaUserLogon: errorcode %d\n",desc
.errcode
));
2234 /****************************************************************************
2235 api_WAccessGetUserPerms
2236 ****************************************************************************/
2237 static BOOL
api_WAccessGetUserPerms(int cnum
,uint16 vuid
, char *param
,char *data
,
2238 int mdrcnt
,int mprcnt
,
2239 char **rdata
,char **rparam
,
2240 int *rdata_len
,int *rparam_len
)
2242 char *str1
= param
+2;
2243 char *str2
= skip_string(str1
,1);
2244 char *user
= skip_string(str2
,1);
2245 char *resource
= skip_string(user
,1);
2247 DEBUG(3,("WAccessGetUserPerms user=%s resource=%s\n",user
,resource
));
2249 /* check it's a supported varient */
2250 if (strcmp(str1
,"zzh") != 0) return False
;
2251 if (strcmp(str2
,"") != 0) return False
;
2254 *rparam
= REALLOC(*rparam
,*rparam_len
);
2255 SSVALS(*rparam
,0,0); /* errorcode */
2256 SSVAL(*rparam
,2,0); /* converter word */
2257 SSVAL(*rparam
,4,0x7f); /* permission flags */
2262 /****************************************************************************
2263 api_WPrintJobEnumerate
2264 ****************************************************************************/
2265 static BOOL
api_WPrintJobGetInfo(int cnum
,uint16 vuid
, char *param
,char *data
,
2266 int mdrcnt
,int mprcnt
,
2267 char **rdata
,char **rparam
,
2268 int *rdata_len
,int *rparam_len
)
2270 char *str1
= param
+2;
2271 char *str2
= skip_string(str1
,1);
2272 char *p
= skip_string(str2
,1);
2273 int uJobId
= SVAL(p
,0);
2279 struct pack_desc desc
;
2280 print_queue_struct
*queue
=NULL
;
2281 print_status_struct status
;
2286 bzero(&desc
,sizeof(desc
));
2287 bzero(&status
,sizeof(status
));
2289 DEBUG(3,("WPrintJobGetInfo uLevel=%d uJobId=0x%X\n",uLevel
,uJobId
));
2291 /* check it's a supported varient */
2292 if (strcmp(str1
,"WWrLh") != 0) return False
;
2293 if (!check_printjob_info(&desc
,uLevel
,str2
)) return False
;
2295 snum
= (unsigned int)uJobId
>> 8; /*## valid serice number??*/
2296 job
= uJobId
& 0xFF;
2298 if (snum
< 0 || !VALID_SNUM(snum
)) return(False
);
2300 count
= get_printqueue(snum
,cnum
,&queue
,&status
);
2301 for (i
= 0; i
< count
; i
++) {
2302 if ((queue
[i
].job
% 0xFF) == job
) break;
2304 if (mdrcnt
> 0) *rdata
= REALLOC(*rdata
,mdrcnt
);
2306 desc
.buflen
= mdrcnt
;
2308 if (init_package(&desc
,1,0)) {
2310 fill_printjob_info(cnum
,snum
,uLevel
,&desc
,&queue
[i
],i
);
2311 *rdata_len
= desc
.usedlen
;
2314 desc
.errcode
= NERR_JobNotFound
;
2320 *rparam
= REALLOC(*rparam
,*rparam_len
);
2321 SSVALS(*rparam
,0,desc
.errcode
);
2323 SSVAL(*rparam
,4,desc
.neededlen
);
2325 if (queue
) free(queue
);
2327 DEBUG(4,("WPrintJobGetInfo: errorcode %d\n",desc
.errcode
));
2331 static BOOL
api_WPrintJobEnumerate(int cnum
,uint16 vuid
, char *param
,char *data
,
2332 int mdrcnt
,int mprcnt
,
2333 char **rdata
,char **rparam
,
2334 int *rdata_len
,int *rparam_len
)
2336 char *str1
= param
+2;
2337 char *str2
= skip_string(str1
,1);
2338 char *p
= skip_string(str2
,1);
2344 struct pack_desc desc
;
2345 print_queue_struct
*queue
=NULL
;
2346 print_status_struct status
;
2348 bzero(&desc
,sizeof(desc
));
2349 bzero(&status
,sizeof(status
));
2351 p
= skip_string(p
,1);
2355 DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel
,name
));
2357 /* check it's a supported varient */
2358 if (strcmp(str1
,"zWrLeh") != 0) return False
;
2359 if (uLevel
> 2) return False
; /* defined only for uLevel 0,1,2 */
2360 if (!check_printjob_info(&desc
,uLevel
,str2
)) return False
;
2362 snum
= lp_servicenumber(name
);
2363 if (snum
< 0 && pcap_printername_ok(name
,NULL
)) {
2364 int pnum
= lp_servicenumber(PRINTERS_NAME
);
2366 lp_add_printer(name
,pnum
);
2367 snum
= lp_servicenumber(name
);
2371 if (snum
< 0 || !VALID_SNUM(snum
)) return(False
);
2373 count
= get_printqueue(snum
,cnum
,&queue
,&status
);
2374 if (mdrcnt
> 0) *rdata
= REALLOC(*rdata
,mdrcnt
);
2376 desc
.buflen
= mdrcnt
;
2378 if (init_package(&desc
,count
,0)) {
2380 for (i
= 0; i
< count
; i
++) {
2381 fill_printjob_info(cnum
,snum
,uLevel
,&desc
,&queue
[i
],i
);
2382 if (desc
.errcode
== NERR_Success
) succnt
= i
+1;
2386 *rdata_len
= desc
.usedlen
;
2389 *rparam
= REALLOC(*rparam
,*rparam_len
);
2390 SSVALS(*rparam
,0,desc
.errcode
);
2392 SSVAL(*rparam
,4,succnt
);
2393 SSVAL(*rparam
,6,count
);
2395 if (queue
) free(queue
);
2397 DEBUG(4,("WPrintJobEnumerate: errorcode %d\n",desc
.errcode
));
2401 static int check_printdest_info(struct pack_desc
* desc
,
2402 int uLevel
, char* id
)
2404 desc
->subformat
= NULL
;
2406 case 0: desc
->format
= "B9"; break;
2407 case 1: desc
->format
= "B9B21WWzW"; break;
2408 case 2: desc
->format
= "z"; break;
2409 case 3: desc
->format
= "zzzWWzzzWW"; break;
2410 default: return False
;
2412 if (strcmp(desc
->format
,id
) != 0) return False
;
2416 static void fill_printdest_info(int cnum
, int snum
, int uLevel
,
2417 struct pack_desc
* desc
)
2420 strcpy(buf
,SERVICE(snum
));
2423 PACKS(desc
,"B9",buf
); /* szName */
2425 PACKS(desc
,"B21",""); /* szUserName */
2426 PACKI(desc
,"W",0); /* uJobId */
2427 PACKI(desc
,"W",0); /* fsStatus */
2428 PACKS(desc
,"z",""); /* pszStatus */
2429 PACKI(desc
,"W",0); /* time */
2432 if (uLevel
== 2 || uLevel
== 3) {
2433 PACKS(desc
,"z",buf
); /* pszPrinterName */
2435 PACKS(desc
,"z",""); /* pszUserName */
2436 PACKS(desc
,"z",""); /* pszLogAddr */
2437 PACKI(desc
,"W",0); /* uJobId */
2438 PACKI(desc
,"W",0); /* fsStatus */
2439 PACKS(desc
,"z",""); /* pszStatus */
2440 PACKS(desc
,"z",""); /* pszComment */
2441 PACKS(desc
,"z","NULL"); /* pszDrivers */
2442 PACKI(desc
,"W",0); /* time */
2443 PACKI(desc
,"W",0); /* pad1 */
2448 static BOOL
api_WPrintDestGetInfo(int cnum
,uint16 vuid
, char *param
,char *data
,
2449 int mdrcnt
,int mprcnt
,
2450 char **rdata
,char **rparam
,
2451 int *rdata_len
,int *rparam_len
)
2453 char *str1
= param
+2;
2454 char *str2
= skip_string(str1
,1);
2455 char *p
= skip_string(str2
,1);
2456 char* PrinterName
= p
;
2458 struct pack_desc desc
;
2461 bzero(&desc
,sizeof(desc
));
2463 p
= skip_string(p
,1);
2467 DEBUG(3,("WPrintDestGetInfo uLevel=%d PrinterName=%s\n",uLevel
,PrinterName
));
2469 /* check it's a supported varient */
2470 if (strcmp(str1
,"zWrLh") != 0) return False
;
2471 if (!check_printdest_info(&desc
,uLevel
,str2
)) return False
;
2473 snum
= lp_servicenumber(PrinterName
);
2474 if (snum
< 0 && pcap_printername_ok(PrinterName
,NULL
)) {
2475 int pnum
= lp_servicenumber(PRINTERS_NAME
);
2477 lp_add_printer(PrinterName
,pnum
);
2478 snum
= lp_servicenumber(PrinterName
);
2484 desc
.errcode
= NERR_DestNotFound
;
2488 if (mdrcnt
> 0) *rdata
= REALLOC(*rdata
,mdrcnt
);
2490 desc
.buflen
= mdrcnt
;
2491 if (init_package(&desc
,1,0)) {
2492 fill_printdest_info(cnum
,snum
,uLevel
,&desc
);
2494 *rdata_len
= desc
.usedlen
;
2498 *rparam
= REALLOC(*rparam
,*rparam_len
);
2499 SSVALS(*rparam
,0,desc
.errcode
);
2501 SSVAL(*rparam
,4,desc
.neededlen
);
2503 DEBUG(4,("WPrintDestGetInfo: errorcode %d\n",desc
.errcode
));
2507 static BOOL
api_WPrintDestEnum(int cnum
,uint16 vuid
, char *param
,char *data
,
2508 int mdrcnt
,int mprcnt
,
2509 char **rdata
,char **rparam
,
2510 int *rdata_len
,int *rparam_len
)
2512 char *str1
= param
+2;
2513 char *str2
= skip_string(str1
,1);
2514 char *p
= skip_string(str2
,1);
2518 struct pack_desc desc
;
2519 int services
= lp_numservices();
2521 bzero(&desc
,sizeof(desc
));
2526 DEBUG(3,("WPrintDestEnum uLevel=%d\n",uLevel
));
2528 /* check it's a supported varient */
2529 if (strcmp(str1
,"WrLeh") != 0) return False
;
2530 if (!check_printdest_info(&desc
,uLevel
,str2
)) return False
;
2533 for (i
= 0; i
< services
; i
++)
2534 if (lp_snum_ok(i
) && lp_print_ok(i
) && lp_browseable(i
))
2537 if (mdrcnt
> 0) *rdata
= REALLOC(*rdata
,mdrcnt
);
2539 desc
.buflen
= mdrcnt
;
2540 if (init_package(&desc
,queuecnt
,0)) {
2543 for (i
= 0; i
< services
; i
++) {
2544 if (lp_snum_ok(i
) && lp_print_ok(i
) && lp_browseable(i
)) {
2545 fill_printdest_info(cnum
,i
,uLevel
,&desc
);
2547 if (desc
.errcode
== NERR_Success
) succnt
= n
;
2552 *rdata_len
= desc
.usedlen
;
2555 *rparam
= REALLOC(*rparam
,*rparam_len
);
2556 SSVALS(*rparam
,0,desc
.errcode
);
2558 SSVAL(*rparam
,4,succnt
);
2559 SSVAL(*rparam
,6,queuecnt
);
2561 DEBUG(4,("WPrintDestEnumerate: errorcode %d\n",desc
.errcode
));
2565 static BOOL
api_WPrintDriverEnum(int cnum
,uint16 vuid
, char *param
,char *data
,
2566 int mdrcnt
,int mprcnt
,
2567 char **rdata
,char **rparam
,
2568 int *rdata_len
,int *rparam_len
)
2570 char *str1
= param
+2;
2571 char *str2
= skip_string(str1
,1);
2572 char *p
= skip_string(str2
,1);
2575 struct pack_desc desc
;
2577 bzero(&desc
,sizeof(desc
));
2582 DEBUG(3,("WPrintDriverEnum uLevel=%d\n",uLevel
));
2584 /* check it's a supported varient */
2585 if (strcmp(str1
,"WrLeh") != 0) return False
;
2586 if (uLevel
!= 0 || strcmp(str2
,"B41") != 0) return False
;
2588 if (mdrcnt
> 0) *rdata
= REALLOC(*rdata
,mdrcnt
);
2590 desc
.buflen
= mdrcnt
;
2591 if (init_package(&desc
,1,0)) {
2592 PACKS(&desc
,"B41","NULL");
2595 succnt
= (desc
.errcode
== NERR_Success
? 1 : 0);
2597 *rdata_len
= desc
.usedlen
;
2600 *rparam
= REALLOC(*rparam
,*rparam_len
);
2601 SSVALS(*rparam
,0,desc
.errcode
);
2603 SSVAL(*rparam
,4,succnt
);
2606 DEBUG(4,("WPrintDriverEnum: errorcode %d\n",desc
.errcode
));
2610 static BOOL
api_WPrintQProcEnum(int cnum
,uint16 vuid
, char *param
,char *data
,
2611 int mdrcnt
,int mprcnt
,
2612 char **rdata
,char **rparam
,
2613 int *rdata_len
,int *rparam_len
)
2615 char *str1
= param
+2;
2616 char *str2
= skip_string(str1
,1);
2617 char *p
= skip_string(str2
,1);
2620 struct pack_desc desc
;
2622 bzero(&desc
,sizeof(desc
));
2627 DEBUG(3,("WPrintQProcEnum uLevel=%d\n",uLevel
));
2629 /* check it's a supported varient */
2630 if (strcmp(str1
,"WrLeh") != 0) return False
;
2631 if (uLevel
!= 0 || strcmp(str2
,"B13") != 0) return False
;
2633 if (mdrcnt
> 0) *rdata
= REALLOC(*rdata
,mdrcnt
);
2635 desc
.buflen
= mdrcnt
;
2637 if (init_package(&desc
,1,0)) {
2638 PACKS(&desc
,"B13","lpd");
2641 succnt
= (desc
.errcode
== NERR_Success
? 1 : 0);
2643 *rdata_len
= desc
.usedlen
;
2646 *rparam
= REALLOC(*rparam
,*rparam_len
);
2647 SSVALS(*rparam
,0,desc
.errcode
);
2649 SSVAL(*rparam
,4,succnt
);
2652 DEBUG(4,("WPrintQProcEnum: errorcode %d\n",desc
.errcode
));
2656 static BOOL
api_WPrintPortEnum(int cnum
,uint16 vuid
, char *param
,char *data
,
2657 int mdrcnt
,int mprcnt
,
2658 char **rdata
,char **rparam
,
2659 int *rdata_len
,int *rparam_len
)
2661 char *str1
= param
+2;
2662 char *str2
= skip_string(str1
,1);
2663 char *p
= skip_string(str2
,1);
2666 struct pack_desc desc
;
2668 bzero(&desc
,sizeof(desc
));
2673 DEBUG(3,("WPrintPortEnum uLevel=%d\n",uLevel
));
2675 /* check it's a supported varient */
2676 if (strcmp(str1
,"WrLeh") != 0) return False
;
2677 if (uLevel
!= 0 || strcmp(str2
,"B9") != 0) return False
;
2679 if (mdrcnt
> 0) *rdata
= REALLOC(*rdata
,mdrcnt
);
2680 bzero(&desc
,sizeof(desc
));
2682 desc
.buflen
= mdrcnt
;
2684 if (init_package(&desc
,1,0)) {
2685 PACKS(&desc
,"B13","lp0");
2688 succnt
= (desc
.errcode
== NERR_Success
? 1 : 0);
2690 *rdata_len
= desc
.usedlen
;
2693 *rparam
= REALLOC(*rparam
,*rparam_len
);
2694 SSVALS(*rparam
,0,desc
.errcode
);
2696 SSVAL(*rparam
,4,succnt
);
2699 DEBUG(4,("WPrintPortEnum: errorcode %d\n",desc
.errcode
));
2710 } api_fd_commands
[] =
2712 { "SetNmdPpHndState", "lsarpc", 1, api_LsarpcSNPHS
},
2713 { "TransactNmPipe", "lsarpc", 0x26, api_LsarpcTNP
},
2714 { NULL
, NULL
, -1, (BOOL (*)())api_Unsupported
}
2717 /****************************************************************************
2718 handle remote api calls delivered to a named pipe already opened.
2719 ****************************************************************************/
2720 static int api_fd_reply(int cnum
,uint16 vuid
,char *outbuf
,
2721 uint16
*setup
,char *data
,char *params
,
2722 int suwcnt
,int tdscnt
,int tpscnt
,int mdrcnt
,int mprcnt
)
2725 char *rparam
= NULL
;
2733 /* First find out the name of this file. */
2736 DEBUG(0,("Unexpected named pipe transaction.\n"));
2740 /* Get the file handle and hence the file name. */
2742 subcommand
= setup
[0];
2744 DEBUG(3,("Got API command %d on pipe %s ",subcommand
,Files
[fd
].name
));
2745 DEBUG(3,("(tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
2746 tdscnt
,tpscnt
,mdrcnt
,mprcnt
));
2748 for (i
=0;api_fd_commands
[i
].name
;i
++)
2749 if (strequal(api_fd_commands
[i
].pipename
, Files
[fd
].name
) &&
2750 api_fd_commands
[i
].subcommand
== subcommand
&&
2751 api_fd_commands
[i
].fn
)
2753 DEBUG(3,("Doing %s\n",api_fd_commands
[i
].name
));
2757 rdata
= (char *)malloc(1024); if (rdata
) bzero(rdata
,1024);
2758 rparam
= (char *)malloc(1024); if (rparam
) bzero(rparam
,1024);
2760 reply
= api_fd_commands
[i
].fn(cnum
,vuid
,params
,data
,mdrcnt
,mprcnt
,
2761 &rdata
,&rparam
,&rdata_len
,&rparam_len
);
2763 if (rdata_len
> mdrcnt
||
2764 rparam_len
> mprcnt
)
2766 reply
= api_TooSmall(cnum
,vuid
,params
,data
,mdrcnt
,mprcnt
,
2767 &rdata
,&rparam
,&rdata_len
,&rparam_len
);
2771 /* if we get False back then it's actually unsupported */
2773 api_Unsupported(cnum
,vuid
,params
,data
,mdrcnt
,mprcnt
,
2774 &rdata
,&rparam
,&rdata_len
,&rparam_len
);
2776 /* now send the reply */
2777 send_trans_reply(outbuf
,rdata
,rparam
,NULL
,rdata_len
,rparam_len
,0);
2789 /****************************************************************************
2790 the buffer was too small
2791 ****************************************************************************/
2792 static BOOL
api_TooSmall(int cnum
,uint16 vuid
, char *param
,char *data
,
2793 int mdrcnt
,int mprcnt
,
2794 char **rdata
,char **rparam
,
2795 int *rdata_len
,int *rparam_len
)
2797 *rparam_len
= MIN(*rparam_len
,mprcnt
);
2798 *rparam
= REALLOC(*rparam
,*rparam_len
);
2802 SSVAL(*rparam
,0,NERR_BufTooSmall
);
2804 DEBUG(3,("Supplied buffer too small in API command\n"));
2810 /****************************************************************************
2811 the request is not supported
2812 ****************************************************************************/
2813 static BOOL
api_Unsupported(int cnum
,uint16 vuid
, char *param
,char *data
,
2814 int mdrcnt
,int mprcnt
,
2815 char **rdata
,char **rparam
,
2816 int *rdata_len
,int *rparam_len
)
2819 *rparam
= REALLOC(*rparam
,*rparam_len
);
2823 SSVAL(*rparam
,0,NERR_notsupported
);
2824 SSVAL(*rparam
,2,0); /* converter word */
2826 DEBUG(3,("Unsupported API command\n"));
2840 } api_commands
[] = {
2841 {"RNetShareEnum", 0, (BOOL (*)())api_RNetShareEnum
,0},
2842 {"RNetShareGetInfo", 1, (BOOL (*)())api_RNetShareGetInfo
,0},
2843 {"RNetServerGetInfo", 13, (BOOL (*)())api_RNetServerGetInfo
,0},
2844 {"RNetUserGetInfo", 56, (BOOL (*)())api_RNetUserGetInfo
,0},
2845 {"NetUserGetGroups", 59, (BOOL (*)())api_NetUserGetGroups
,0},
2846 {"NetWkstaGetInfo", 63, (BOOL (*)())api_NetWkstaGetInfo
,0},
2847 {"DosPrintQEnum", 69, (BOOL (*)())api_DosPrintQEnum
,0},
2848 {"DosPrintQGetInfo", 70, (BOOL (*)())api_DosPrintQGetInfo
,0},
2849 {"WPrintJobEnumerate",76, (BOOL (*)())api_WPrintJobEnumerate
,0},
2850 {"WPrintJobGetInfo", 77, (BOOL (*)())api_WPrintJobGetInfo
,0},
2851 {"RDosPrintJobDel", 81, (BOOL (*)())api_RDosPrintJobDel
,0},
2852 {"RDosPrintJobPause", 82, (BOOL (*)())api_RDosPrintJobDel
,0},
2853 {"RDosPrintJobResume",83, (BOOL (*)())api_RDosPrintJobDel
,0},
2854 {"WPrintDestEnum", 84, (BOOL (*)())api_WPrintDestEnum
,0},
2855 {"WPrintDestGetInfo", 85, (BOOL (*)())api_WPrintDestGetInfo
,0},
2856 {"NetRemoteTOD", 91, (BOOL (*)())api_NetRemoteTOD
,0},
2857 {"WPrintQueuePurge", 103, (BOOL (*)())api_WPrintQueuePurge
,0},
2858 {"NetServerEnum", 104, (BOOL (*)())api_RNetServerEnum
,0},
2859 {"WAccessGetUserPerms",105, (BOOL (*)())api_WAccessGetUserPerms
,0},
2860 {"SetUserPassword", 115, (BOOL (*)())api_SetUserPassword
,0},
2861 {"WWkstaUserLogon", 132, (BOOL (*)())api_WWkstaUserLogon
,0},
2862 {"PrintJobInfo", 147, (BOOL (*)())api_PrintJobInfo
,0},
2863 {"WPrintDriverEnum", 205, (BOOL (*)())api_WPrintDriverEnum
,0},
2864 {"WPrintQProcEnum", 206, (BOOL (*)())api_WPrintQProcEnum
,0},
2865 {"WPrintPortEnum", 207, (BOOL (*)())api_WPrintPortEnum
,0},
2866 {NULL
, -1, (BOOL (*)())api_Unsupported
,0}};
2869 /****************************************************************************
2870 handle remote api calls
2871 ****************************************************************************/
2872 static int api_reply(int cnum
,uint16 vuid
,char *outbuf
,char *data
,char *params
,
2873 int tdscnt
,int tpscnt
,int mdrcnt
,int mprcnt
)
2875 int api_command
= SVAL(params
,0);
2877 char *rparam
= NULL
;
2883 DEBUG(3,("Got API command %d of form <%s> <%s> (tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
2884 api_command
,params
+2,skip_string(params
+2,1),
2885 tdscnt
,tpscnt
,mdrcnt
,mprcnt
));
2887 for (i
=0;api_commands
[i
].name
;i
++)
2888 if (api_commands
[i
].id
== api_command
&& api_commands
[i
].fn
)
2890 DEBUG(3,("Doing %s\n",api_commands
[i
].name
));
2894 rdata
= (char *)malloc(1024); if (rdata
) bzero(rdata
,1024);
2895 rparam
= (char *)malloc(1024); if (rparam
) bzero(rparam
,1024);
2897 reply
= api_commands
[i
].fn(cnum
,vuid
,params
,data
,mdrcnt
,mprcnt
,
2898 &rdata
,&rparam
,&rdata_len
,&rparam_len
);
2901 if (rdata_len
> mdrcnt
||
2902 rparam_len
> mprcnt
)
2904 reply
= api_TooSmall(cnum
,vuid
,params
,data
,mdrcnt
,mprcnt
,
2905 &rdata
,&rparam
,&rdata_len
,&rparam_len
);
2909 /* if we get False back then it's actually unsupported */
2911 api_Unsupported(cnum
,vuid
,params
,data
,mdrcnt
,mprcnt
,
2912 &rdata
,&rparam
,&rdata_len
,&rparam_len
);
2916 /* now send the reply */
2917 send_trans_reply(outbuf
,rdata
,rparam
,NULL
,rdata_len
,rparam_len
,0);
2927 /****************************************************************************
2928 handle named pipe commands
2929 ****************************************************************************/
2930 static int named_pipe(int cnum
,uint16 vuid
, char *outbuf
,char *name
,
2931 uint16
*setup
,char *data
,char *params
,
2932 int suwcnt
,int tdscnt
,int tpscnt
,
2933 int msrcnt
,int mdrcnt
,int mprcnt
)
2936 if (strequal(name
,"LANMAN"))
2937 return(api_reply(cnum
,vuid
,outbuf
,data
,params
,tdscnt
,tpscnt
,mdrcnt
,mprcnt
));
2939 if (strlen(name
) < 1)
2940 return(api_fd_reply(cnum
,vuid
,outbuf
,setup
,data
,params
,suwcnt
,tdscnt
,tpscnt
,mdrcnt
,mprcnt
));
2943 DEBUG(3,("named pipe command on <%s> 0x%X setup1=%d\n",
2944 name
,(int)setup
[0],(int)setup
[1]));
2950 /****************************************************************************
2952 ****************************************************************************/
2953 int reply_trans(char *inbuf
,char *outbuf
)
2957 char *data
=NULL
,*params
=NULL
;
2961 int cnum
= SVAL(inbuf
,smb_tid
);
2962 uint16 vuid
= SVAL(inbuf
,smb_uid
);
2964 int tpscnt
= SVAL(inbuf
,smb_vwv0
);
2965 int tdscnt
= SVAL(inbuf
,smb_vwv1
);
2966 int mprcnt
= SVAL(inbuf
,smb_vwv2
);
2967 int mdrcnt
= SVAL(inbuf
,smb_vwv3
);
2968 int msrcnt
= CVAL(inbuf
,smb_vwv4
);
2969 BOOL close_on_completion
= BITSETW(inbuf
+smb_vwv5
,0);
2970 BOOL one_way
= BITSETW(inbuf
+smb_vwv5
,1);
2971 int pscnt
= SVAL(inbuf
,smb_vwv9
);
2972 int psoff
= SVAL(inbuf
,smb_vwv10
);
2973 int dscnt
= SVAL(inbuf
,smb_vwv11
);
2974 int dsoff
= SVAL(inbuf
,smb_vwv12
);
2975 int suwcnt
= CVAL(inbuf
,smb_vwv13
);
2977 StrnCpy(name
,smb_buf(inbuf
),sizeof(name
)-1);
2981 data
= (char *)malloc(tdscnt
);
2982 memcpy(data
,smb_base(inbuf
)+dsoff
,dscnt
);
2986 params
= (char *)malloc(tpscnt
);
2987 memcpy(params
,smb_base(inbuf
)+psoff
,pscnt
);
2993 setup
= (uint16
*)malloc(suwcnt
*sizeof(setup
[0]));
2994 for (i
=0;i
<suwcnt
;i
++)
2995 setup
[i
] = SVAL(inbuf
,smb_vwv14
+i
*SIZEOFWORD
);
2999 if (pscnt
< tpscnt
|| dscnt
< tdscnt
)
3001 /* We need to send an interim response then receive the rest
3002 of the parameter/data bytes */
3003 outsize
= set_message(outbuf
,0,0,True
);
3005 send_smb(Client
,outbuf
);
3008 /* receive the rest of the trans packet */
3009 while (pscnt
< tpscnt
|| dscnt
< tdscnt
)
3011 int pcnt
,poff
,dcnt
,doff
,pdisp
,ddisp
;
3013 if (!receive_smb(Client
,inbuf
, SMB_SECONDARY_WAIT
) ||
3014 CVAL(inbuf
, smb_com
) != SMBtrans
)
3016 DEBUG(2,("Invalid secondary trans2 packet\n"));
3017 if (params
) free(params
);
3018 if (data
) free(data
);
3019 if (setup
) free(setup
);
3020 return(ERROR(ERRSRV
,ERRerror
));
3025 tpscnt
= SVAL(inbuf
,smb_vwv0
);
3026 tdscnt
= SVAL(inbuf
,smb_vwv1
);
3028 pcnt
= SVAL(inbuf
,smb_vwv2
);
3029 poff
= SVAL(inbuf
,smb_vwv3
);
3030 pdisp
= SVAL(inbuf
,smb_vwv4
);
3032 dcnt
= SVAL(inbuf
,smb_vwv5
);
3033 doff
= SVAL(inbuf
,smb_vwv6
);
3034 ddisp
= SVAL(inbuf
,smb_vwv7
);
3040 memcpy(params
+pdisp
,smb_base(inbuf
)+poff
,pcnt
);
3042 memcpy(data
+ddisp
,smb_base(inbuf
)+doff
,dcnt
);
3046 DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n",name
,tdscnt
,tpscnt
,suwcnt
));
3049 if (strncmp(name
,"\\PIPE\\",strlen("\\PIPE\\")) == 0)
3050 outsize
= named_pipe(cnum
,vuid
,outbuf
,name
+strlen("\\PIPE\\"),setup
,data
,params
,
3051 suwcnt
,tdscnt
,tpscnt
,msrcnt
,mdrcnt
,mprcnt
);
3054 if (data
) free(data
);
3055 if (params
) free(params
);
3056 if (setup
) free(setup
);
3058 if (close_on_completion
)
3059 close_cnum(cnum
,vuid
);
3065 return(ERROR(ERRSRV
,ERRnosupport
));