1997-03-09 17:58:22 +03:00
1996-05-04 11:50:46 +04:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
Inter - process communication and named pipe handling
1997-05-08 05:14:17 +04:00
Copyright ( C ) Andrew Tridgell 1992 - 1997
1996-05-04 11:50:46 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
/*
This file handles the named pipe and mailslot calls
in the SMBtrans protocol
*/
# include "includes.h"
# ifdef CHECK_TYPES
# undef CHECK_TYPES
# endif
# define CHECK_TYPES 0
extern int DEBUGLEVEL ;
1997-02-28 23:39:36 +03:00
extern int max_send ;
1996-05-04 11:50:46 +04:00
extern files_struct Files [ ] ;
extern connection_struct Connections [ ] ;
extern fstring local_machine ;
1997-05-20 04:32:51 +04:00
extern fstring myworkgroup ;
1996-05-04 11:50:46 +04:00
# define NERR_Success 0
# define NERR_badpass 86
# define NERR_notsupported 50
# define NERR_BASE (2100)
# define NERR_BufTooSmall (NERR_BASE+23)
# define NERR_JobNotFound (NERR_BASE+51)
# define NERR_DestNotFound (NERR_BASE+52)
# define ERROR_INVALID_LEVEL 124
# define ERROR_MORE_DATA 234
# define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
# define ACCESS_READ 0x01
# define ACCESS_WRITE 0x02
# define ACCESS_CREATE 0x04
# define SHPWLEN 8 /* share password length */
# define NNLEN 12 /* 8.3 net name length */
# define SNLEN 15 /* service name length */
# define QNLEN 12 /* queue name maximum length */
extern int Client ;
1996-10-26 00:10:53 +04:00
static BOOL api_Unsupported ( int cnum , uint16 vuid , char * param , char * data ,
1996-08-15 19:11:34 +04:00
int mdrcnt , int mprcnt ,
char * * rdata , char * * rparam ,
int * rdata_len , int * rparam_len ) ;
1996-10-26 00:10:53 +04:00
static BOOL api_TooSmall ( int cnum , uint16 vuid , char * param , char * data ,
1996-08-15 19:11:34 +04:00
int mdrcnt , int mprcnt ,
char * * rdata , char * * rparam ,
int * rdata_len , int * rparam_len ) ;
1996-05-04 11:50:46 +04:00
static int CopyExpanded ( int cnum , int snum , char * * dst , char * src , int * n )
{
pstring buf ;
int l ;
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 ;
}
static int CopyAndAdvance ( char * * dst , char * src , int * n )
{
int l ;
if ( ! src | | ! dst | | ! n | | ! ( * dst ) ) return ( 0 ) ;
StrnCpy ( * dst , src , * n ) ;
l = strlen ( * dst ) + 1 ;
( * dst ) + = l ;
( * n ) - = l ;
return l ;
}
static int StrlenExpanded ( int cnum , 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 ;
}
static char * Expand ( int cnum , 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 ] ;
}
/*******************************************************************
check a API string for validity when we only need to check the prefix
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL prefix_ok ( char * str , char * prefix )
{
return ( strncmp ( str , prefix , strlen ( prefix ) ) = = 0 ) ;
}
/****************************************************************************
send a trans reply
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void send_trans_reply ( char * outbuf , char * data , char * param , uint16 * setup ,
int ldata , int lparam , int lsetup )
{
int i ;
int this_ldata , this_lparam ;
int tot_data = 0 , tot_param = 0 ;
int align ;
1997-02-28 23:39:36 +03:00
this_lparam = MIN ( lparam , max_send - ( 500 + lsetup * SIZEOFWORD ) ) ; /* hack */
this_ldata = MIN ( ldata , max_send - ( 500 + lsetup * SIZEOFWORD + this_lparam ) ) ;
1996-05-04 11:50:46 +04:00
align = ( this_lparam % 4 ) ;
set_message ( outbuf , 10 + lsetup , align + this_ldata + this_lparam , True ) ;
if ( this_lparam )
memcpy ( smb_buf ( outbuf ) , param , this_lparam ) ;
if ( this_ldata )
memcpy ( smb_buf ( outbuf ) + this_lparam + align , data , 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_vwv5 , 0 ) ;
SSVAL ( outbuf , smb_vwv6 , this_ldata ) ;
SSVAL ( outbuf , smb_vwv7 , smb_offset ( smb_buf ( outbuf ) + 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 ] ) ;
show_msg ( outbuf ) ;
send_smb ( Client , outbuf ) ;
tot_data = this_ldata ;
tot_param = this_lparam ;
while ( tot_data < ldata | | tot_param < lparam )
{
1997-02-28 23:39:36 +03:00
this_lparam = MIN ( lparam - tot_param , max_send - 500 ) ; /* hack */
this_ldata = MIN ( ldata - tot_data , max_send - ( 500 + this_lparam ) ) ;
1996-05-04 11:50:46 +04:00
align = ( this_lparam % 4 ) ;
set_message ( outbuf , 10 , this_ldata + this_lparam + align , False ) ;
if ( this_lparam )
memcpy ( smb_buf ( outbuf ) , param + tot_param , this_lparam ) ;
if ( this_ldata )
memcpy ( smb_buf ( outbuf ) + this_lparam + align , data + tot_data , 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_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_vwv9 , 0 ) ;
show_msg ( outbuf ) ;
send_smb ( Client , outbuf ) ;
tot_data + = this_ldata ;
tot_param + = this_lparam ;
}
}
struct pack_desc {
char * format ; /* formatstring for structure */
char * subformat ; /* subformat for structure */
char * base ; /* baseaddress of buffer */
int buflen ; /* remaining size for fixed part; on init: length of base */
int subcount ; /* count of substructures */
char * structbuf ; /* pointer into buffer for remaining fixed part */
int stringlen ; /* remaining size for variable part */
char * stringbuf ; /* pointer into buffer for remaining variable part */
int neededlen ; /* total needed size */
int usedlen ; /* total used size (usedlen <= neededlen and usedlen <= buflen) */
char * curpos ; /* current position; pointer into format or subformat */
int errcode ;
} ;
static int get_counter ( char * * p )
{
int i , n ;
if ( ! p | | ! ( * p ) ) return ( 1 ) ;
if ( ! isdigit ( * * p ) ) return 1 ;
for ( n = 0 ; ; ) {
i = * * p ;
if ( isdigit ( i ) )
n = 10 * n + ( i - ' 0 ' ) ;
else
return n ;
( * p ) + + ;
}
}
static int getlen ( char * p )
{
int n = 0 ;
if ( ! p ) return ( 0 ) ;
while ( * p ) {
switch ( * p + + ) {
case ' W ' : /* word (2 byte) */
n + = 2 ;
break ;
case ' N ' : /* count of substructures (word) at end */
n + = 2 ;
break ;
case ' D ' : /* double word (4 byte) */
case ' z ' : /* offset to zero terminated string (4 byte) */
case ' l ' : /* offset to user data (4 byte) */
n + = 4 ;
break ;
case ' b ' : /* offset to data (with counter) (4 byte) */
n + = 4 ;
get_counter ( & p ) ;
break ;
case ' B ' : /* byte (with optional counter) */
n + = get_counter ( & p ) ;
break ;
}
}
return n ;
}
static BOOL init_package ( struct pack_desc * p , int count , int subcount )
{
int n = p - > buflen ;
int i ;
if ( ! p - > format | | ! p - > base ) return ( False ) ;
i = count * getlen ( p - > format ) ;
if ( p - > subformat ) i + = subcount * getlen ( p - > subformat ) ;
p - > structbuf = p - > base ;
p - > neededlen = 0 ;
p - > usedlen = 0 ;
p - > subcount = 0 ;
p - > curpos = p - > format ;
if ( i > n ) {
i = n = 0 ;
p - > errcode = NERR_BufTooSmall ;
}
p - > errcode = NERR_Success ;
p - > buflen = i ;
n - = i ;
p - > stringbuf = p - > base + i ;
p - > stringlen = n ;
return ( p - > errcode = = NERR_Success ) ;
}
# ifdef __STDC__
static int package ( struct pack_desc * p , . . . )
{
# else
static int package ( va_alist )
va_dcl
{
struct pack_desc * p ;
# endif
va_list args ;
int needed = 0 , stringneeded ;
char * str = NULL ;
int is_string = 0 , stringused ;
int32 temp ;
# ifdef __STDC__
va_start ( args , p ) ;
# else
va_start ( args ) ;
p = va_arg ( args , struct pack_desc * ) ;
# endif
if ( ! * p - > curpos ) {
if ( ! p - > subcount )
p - > curpos = p - > format ;
else {
p - > curpos = p - > subformat ;
p - > subcount - - ;
}
}
# 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 ;
}
# endif
stringneeded = - 1 ;
if ( ! p - > curpos ) return ( 0 ) ;
switch ( * p - > curpos + + ) {
case ' W ' : /* 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 ) ;
if ( p - > buflen > = needed ) SSVAL ( p - > structbuf , 0 , p - > subcount ) ;
break ;
case ' D ' : /* double word (4 byte) */
needed = 4 ;
temp = va_arg ( args , int ) ;
if ( p - > buflen > = needed ) SIVAL ( p - > structbuf , 0 , temp ) ;
break ;
case ' B ' : /* byte (with optional counter) */
needed = get_counter ( & p - > curpos ) ;
{
char * s = va_arg ( args , char * ) ;
if ( p - > buflen > = needed ) StrnCpy ( p - > structbuf , s ? s : " " , needed ) ;
}
break ;
case ' z ' : /* offset to zero terminated string (4 byte) */
str = va_arg ( args , char * ) ;
stringneeded = ( str ? strlen ( str ) + 1 : 0 ) ;
is_string = 1 ;
break ;
case ' l ' : /* offset to user data (4 byte) */
str = va_arg ( args , char * ) ;
stringneeded = va_arg ( args , int ) ;
is_string = 0 ;
break ;
case ' b ' : /* offset to data (with counter) (4 byte) */
str = va_arg ( args , char * ) ;
stringneeded = get_counter ( & p - > curpos ) ;
is_string = 0 ;
break ;
}
va_end ( args ) ;
if ( stringneeded > = 0 ) {
needed = 4 ;
if ( p - > buflen > = needed ) {
stringused = stringneeded ;
if ( stringused > p - > stringlen ) {
stringused = ( is_string ? p - > stringlen : 0 ) ;
if ( p - > errcode = = NERR_Success ) p - > errcode = ERROR_MORE_DATA ;
}
if ( ! stringused )
SIVAL ( p - > structbuf , 0 , 0 ) ;
else {
SIVAL ( p - > structbuf , 0 , PTR_DIFF ( p - > stringbuf , p - > base ) ) ;
memcpy ( p - > stringbuf , str ? str : " " , stringused ) ;
if ( is_string ) p - > stringbuf [ stringused - 1 ] = ' \0 ' ;
p - > stringbuf + = stringused ;
p - > stringlen - = stringused ;
p - > usedlen + = stringused ;
}
}
p - > neededlen + = stringneeded ;
}
p - > neededlen + = needed ;
if ( p - > buflen > = needed ) {
p - > structbuf + = needed ;
p - > buflen - = needed ;
p - > usedlen + = needed ;
}
else {
if ( p - > errcode = = NERR_Success ) p - > errcode = NERR_BufTooSmall ;
}
return 1 ;
}
# if CHECK_TYPES
# define PACK(desc,t,v) package(desc,t,v,0,0,0,0)
# define PACKl(desc,t,v,l) package(desc,t,v,l,0,0,0,0)
# else
# define PACK(desc,t,v) package(desc,v)
# define PACKl(desc,t,v,l) package(desc,v,l)
# endif
static void PACKI ( struct pack_desc * desc , char * t , int v )
{
PACK ( desc , t , v ) ;
}
static void PACKS ( struct pack_desc * desc , char * t , char * v )
{
PACK ( desc , t , v ) ;
}
1996-08-13 12:57:55 +04:00
/****************************************************************************
get a print queue
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-05-04 11:50:46 +04:00
static void PackDriverData ( struct pack_desc * desc )
{
char drivdata [ 4 + 4 + 32 ] ;
SIVAL ( drivdata , 0 , sizeof drivdata ) ; /* cb */
SIVAL ( drivdata , 4 , 1000 ) ; /* lVersion */
memset ( drivdata + 8 , 0 , 32 ) ; /* szDeviceName */
strcpy ( drivdata + 8 , " NULL " ) ;
PACKl ( desc , " l " , drivdata , sizeof drivdata ) ; /* pDriverData */
}
static int check_printq_info ( struct pack_desc * desc ,
1996-10-02 18:09:22 +04:00
int uLevel , char * id1 , const char * id2 )
1996-05-04 11:50:46 +04:00
{
desc - > subformat = NULL ;
switch ( uLevel ) {
case 0 :
desc - > format = " B13 " ;
break ;
case 1 :
desc - > format = " B13BWWWzzzzzWW " ;
break ;
case 2 :
desc - > format = " B13BWWWzzzzzWN " ;
desc - > subformat = " WB21BB16B10zWWzDDz " ;
break ;
case 3 :
desc - > format = " zWWWWzzzzWWzzl " ;
break ;
case 4 :
desc - > format = " zWWWWzzzzWNzzl " ;
desc - > subformat = " WWzWWDDzz " ;
break ;
case 5 :
desc - > format = " z " ;
break ;
default : return False ;
}
if ( strcmp ( desc - > format , id1 ) ! = 0 ) return False ;
if ( desc - > subformat & & strcmp ( desc - > subformat , id2 ) ! = 0 ) return False ;
return True ;
}
static void fill_printjob_info ( int cnum , int snum , int uLevel ,
struct pack_desc * desc ,
print_queue_struct * queue , int n )
{
time_t t = queue - > time ;
/* the client expects localtime */
1996-05-31 19:13:29 +04:00
t - = TimeDiff ( t ) ;
1996-05-04 11:50:46 +04:00
PACKI ( desc , " W " , ( ( snum % 0xFF ) < < 8 ) | ( queue - > job % 0xFF ) ) ; /* uJobId */
if ( uLevel = = 1 ) {
PACKS ( desc , " B21 " , queue - > user ) ; /* szUserName */
PACKS ( desc , " B " , " " ) ; /* pad */
PACKS ( desc , " B16 " , " " ) ; /* szNotifyName */
PACKS ( desc , " B10 " , " PM_Q_RAW " ) ; /* szDataType */
PACKS ( desc , " z " , " " ) ; /* pszParms */
PACKI ( desc , " W " , n + 1 ) ; /* uPosition */
PACKI ( desc , " W " , queue - > status ) ; /* fsStatus */
PACKS ( desc , " z " , " " ) ; /* pszStatus */
1996-05-31 19:13:29 +04:00
PACKI ( desc , " D " , t ) ; /* ulSubmitted */
1996-05-04 11:50:46 +04:00
PACKI ( desc , " D " , queue - > size ) ; /* ulSize */
PACKS ( desc , " z " , queue - > file ) ; /* pszComment */
}
if ( uLevel = = 2 | | uLevel = = 3 ) {
PACKI ( desc , " W " , queue - > priority ) ; /* uPriority */
PACKS ( desc , " z " , queue - > user ) ; /* pszUserName */
PACKI ( desc , " W " , n + 1 ) ; /* uPosition */
PACKI ( desc , " W " , queue - > status ) ; /* fsStatus */
1996-05-31 19:13:29 +04:00
PACKI ( desc , " D " , t ) ; /* ulSubmitted */
1996-05-04 11:50:46 +04:00
PACKI ( desc , " D " , queue - > size ) ; /* ulSize */
PACKS ( desc , " z " , " Samba " ) ; /* pszComment */
PACKS ( desc , " z " , queue - > file ) ; /* pszDocument */
if ( uLevel = = 3 ) {
PACKS ( desc , " z " , " " ) ; /* pszNotifyName */
PACKS ( desc , " z " , " PM_Q_RAW " ) ; /* pszDataType */
PACKS ( desc , " z " , " " ) ; /* pszParms */
PACKS ( desc , " z " , " " ) ; /* pszStatus */
PACKS ( desc , " z " , SERVICE ( snum ) ) ; /* pszQueue */
PACKS ( desc , " z " , " lpd " ) ; /* pszQProcName */
PACKS ( desc , " z " , " " ) ; /* pszQProcParms */
PACKS ( desc , " z " , " NULL " ) ; /* pszDriverName */
PackDriverData ( desc ) ; /* pDriverData */
PACKS ( desc , " z " , " " ) ; /* pszPrinterName */
}
}
}
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 )
{
if ( uLevel < 3 ) {
PACKS ( desc , " B13 " , SERVICE ( snum ) ) ;
} else {
PACKS ( desc , " z " , Expand ( cnum , snum , SERVICE ( snum ) ) ) ;
}
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 */
1996-08-13 12:57:55 +04:00
PACKS ( desc , " z " , " WinPrint " ) ; /* pszPrProc */
1996-05-04 11:50:46 +04:00
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 */
1996-08-13 12:57:55 +04:00
PACKS ( desc , " z " , lp_printerdriver ( snum ) ) ; /* pszDriverName */
1996-05-04 11:50:46 +04:00
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 ) ;
}
DEBUG ( 3 , ( " fill_printq_info on <%s> gave %d entries \n " , SERVICE ( snum ) , count ) ) ;
}
1996-10-26 00:10:53 +04:00
static BOOL api_DosPrintQGetInfo ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 ) ;
char * QueueName = p ;
int uLevel , cbBuf ;
int count = 0 ;
int snum ;
char * str3 ;
struct pack_desc desc ;
print_queue_struct * queue = NULL ;
print_status_struct status ;
bzero ( & status , sizeof ( status ) ) ;
bzero ( & desc , sizeof ( desc ) ) ;
p = skip_string ( p , 1 ) ;
uLevel = SVAL ( p , 0 ) ;
cbBuf = SVAL ( p , 2 ) ;
str3 = p + 4 ;
1996-08-13 12:57:55 +04:00
/* remove any trailing username */
1996-05-04 11:50:46 +04:00
if ( ( p = strchr ( QueueName , ' % ' ) ) ) * p = 0 ;
DEBUG ( 3 , ( " PrintQueue uLevel=%d name=%s \n " , uLevel , QueueName ) ) ;
/* check it's a supported varient */
if ( ! prefix_ok ( str1 , " zWrLh " ) ) return False ;
if ( ! check_printq_info ( & desc , uLevel , str2 , str3 ) ) return False ;
snum = lp_servicenumber ( QueueName ) ;
if ( snum < 0 & & pcap_printername_ok ( QueueName , NULL ) ) {
int pnum = lp_servicenumber ( PRINTERS_NAME ) ;
if ( pnum > = 0 ) {
lp_add_printer ( QueueName , pnum ) ;
snum = lp_servicenumber ( QueueName ) ;
}
}
if ( snum < 0 | | ! VALID_SNUM ( snum ) ) return ( False ) ;
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 ) ;
}
* rdata_len = desc . usedlen ;
* rparam_len = 6 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVALS ( * rparam , 0 , desc . errcode ) ;
SSVAL ( * rparam , 2 , 0 ) ;
SSVAL ( * rparam , 4 , desc . neededlen ) ;
DEBUG ( 4 , ( " printqgetinfo: errorcode %d \n " , desc . errcode ) ) ;
if ( queue ) free ( queue ) ;
return ( True ) ;
}
/****************************************************************************
view list of all print jobs on all queues
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_DosPrintQEnum ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
int mdrcnt , int mprcnt ,
char * * rdata , char * * rparam ,
int * rdata_len , int * rparam_len )
{
char * param_format = param + 2 ;
char * output_format1 = skip_string ( param_format , 1 ) ;
char * p = skip_string ( output_format1 , 1 ) ;
int uLevel = SVAL ( p , 0 ) ;
char * output_format2 = p + 4 ;
int services = lp_numservices ( ) ;
int i , n ;
struct pack_desc desc ;
print_queue_struct * * queue = NULL ;
print_status_struct * status = NULL ;
int * subcntarr = NULL ;
int queuecnt , subcnt = 0 , succnt = 0 ;
bzero ( & desc , sizeof ( desc ) ) ;
DEBUG ( 3 , ( " DosPrintQEnum uLevel=%d \n " , uLevel ) ) ;
1996-08-14 19:01:09 +04:00
if ( ! prefix_ok ( param_format , " WrLeh " ) ) return False ;
1996-05-04 11:50:46 +04:00
if ( ! check_printq_info ( & desc , uLevel , output_format1 , output_format2 ) )
return False ;
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 * ) ) ;
memset ( queue , 0 , queuecnt * sizeof ( print_queue_struct * ) ) ;
status = ( print_status_struct * ) malloc ( queuecnt * sizeof ( print_status_struct ) ) ;
memset ( status , 0 , queuecnt * sizeof ( print_status_struct ) ) ;
subcntarr = ( int * ) malloc ( queuecnt * sizeof ( int ) ) ;
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 ] ) ;
subcnt + = subcntarr [ n ] ;
n + + ;
}
}
if ( mdrcnt > 0 ) * rdata = REALLOC ( * rdata , mdrcnt ) ;
desc . base = * rdata ;
desc . buflen = mdrcnt ;
if ( init_package ( & desc , queuecnt , subcnt ) ) {
n = 0 ;
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 ] ) ;
n + + ;
if ( desc . errcode = = NERR_Success ) succnt = n ;
}
}
if ( subcntarr ) free ( subcntarr ) ;
* rdata_len = desc . usedlen ;
* rparam_len = 8 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVALS ( * rparam , 0 , desc . errcode ) ;
SSVAL ( * rparam , 2 , 0 ) ;
SSVAL ( * rparam , 4 , succnt ) ;
SSVAL ( * rparam , 6 , queuecnt ) ;
for ( i = 0 ; i < queuecnt ; i + + ) {
if ( queue & & queue [ i ] ) free ( queue [ i ] ) ;
}
if ( queue ) free ( queue ) ;
if ( status ) free ( status ) ;
return True ;
}
/****************************************************************************
get info level for a server list query
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL check_server_info ( int uLevel , char * id )
{
switch ( uLevel ) {
case 0 :
if ( strcmp ( id , " B16 " ) ! = 0 ) return False ;
break ;
case 1 :
if ( strcmp ( id , " B16BBDz " ) ! = 0 ) return False ;
break ;
default :
return False ;
}
return True ;
}
struct srv_info_struct
{
fstring name ;
uint32 type ;
fstring comment ;
1996-08-17 15:37:44 +04:00
fstring domain ;
BOOL server_added ;
1996-05-04 11:50:46 +04:00
} ;
/*******************************************************************
get server info lists from the files saved by nmbd . Return the
number of entries
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int get_server_info ( uint32 servertype ,
1996-08-17 15:37:44 +04:00
struct srv_info_struct * * servers ,
1996-06-06 15:43:09 +04:00
char * domain )
1996-05-04 11:50:46 +04:00
{
FILE * f ;
pstring fname ;
int count = 0 ;
int alloced = 0 ;
pstring line ;
strcpy ( fname , lp_lockdir ( ) ) ;
trim_string ( fname , NULL , " / " ) ;
strcat ( fname , " / " ) ;
strcat ( fname , SERVER_LIST ) ;
f = fopen ( fname , " r " ) ;
if ( ! f ) {
DEBUG ( 4 , ( " Can't open %s - %s \n " , fname , strerror ( errno ) ) ) ;
return ( 0 ) ;
}
1996-06-01 19:25:30 +04:00
/* request for everything is code for request all servers */
1996-05-04 11:50:46 +04:00
if ( servertype = = SV_TYPE_ALL ) servertype & = ~ SV_TYPE_DOMAIN_ENUM ;
1996-08-17 15:37:44 +04:00
DEBUG ( 4 , ( " Servertype search: %8x \n " , servertype ) ) ;
1996-06-01 19:25:30 +04:00
1996-05-04 11:50:46 +04:00
while ( ! feof ( f ) )
{
fstring stype ;
struct srv_info_struct * s ;
char * ptr = line ;
1996-06-01 19:25:30 +04:00
BOOL ok = True ;
1996-05-04 11:50:46 +04:00
* ptr = 0 ;
fgets ( line , sizeof ( line ) - 1 , f ) ;
if ( ! * line ) continue ;
1996-06-01 19:25:30 +04:00
1996-05-04 11:50:46 +04:00
if ( count = = alloced ) {
alloced + = 10 ;
( * servers ) = ( struct srv_info_struct * )
Realloc ( * servers , sizeof ( * * servers ) * alloced ) ;
if ( ! ( * servers ) ) return ( 0 ) ;
bzero ( ( char * ) ( ( * servers ) + count ) , sizeof ( * * servers ) * ( alloced - count ) ) ;
}
s = & ( * servers ) [ count ] ;
1996-06-01 19:25:30 +04:00
1996-05-04 11:50:46 +04:00
if ( ! next_token ( & ptr , s - > name , NULL ) ) continue ;
if ( ! next_token ( & ptr , stype , NULL ) ) continue ;
if ( ! next_token ( & ptr , s - > comment , NULL ) ) continue ;
1996-10-02 19:41:30 +04:00
if ( ! next_token ( & ptr , s - > domain , NULL ) ) {
/* this allows us to cope with an old nmbd */
1997-05-20 04:32:51 +04:00
strcpy ( s - > domain , myworkgroup ) ;
1996-10-02 19:41:30 +04:00
}
1996-06-01 19:25:30 +04:00
1996-06-06 15:43:09 +04:00
if ( sscanf ( stype , " %X " , & s - > type ) ! = 1 ) {
DEBUG ( 4 , ( " r:host file " ) ) ;
ok = False ;
}
1996-06-01 19:25:30 +04:00
1996-05-04 11:50:46 +04:00
/* doesn't match up: don't want it */
1996-06-06 15:43:09 +04:00
if ( ! ( servertype & s - > type ) ) {
DEBUG ( 4 , ( " r:serv type " ) ) ;
ok = False ;
}
1996-06-01 19:25:30 +04:00
1996-08-17 15:37:44 +04:00
if ( ( servertype & SV_TYPE_DOMAIN_ENUM ) ! =
1996-06-01 19:25:30 +04:00
( s - > type & SV_TYPE_DOMAIN_ENUM ) )
{
1996-08-17 15:37:44 +04:00
DEBUG ( 4 , ( " s: dom mismatch " ) ) ;
1996-06-01 19:25:30 +04:00
ok = False ;
}
1996-08-17 15:37:44 +04:00
if ( ! strequal ( domain , s - > domain ) & & ! ( servertype & SV_TYPE_DOMAIN_ENUM ) )
1996-06-01 19:25:30 +04:00
{
1996-08-17 15:37:44 +04:00
ok = False ;
1996-06-01 19:25:30 +04:00
}
if ( ok )
{
DEBUG ( 4 , ( " **SV** %20s %8x %25s %15s \n " ,
s - > name , s - > type , s - > comment , s - > domain ) ) ;
s - > server_added = True ;
count + + ;
}
else
{
DEBUG ( 4 , ( " %20s %8x %25s %15s \n " ,
s - > name , s - > type , s - > comment , s - > domain ) ) ;
}
1996-05-04 11:50:46 +04:00
}
1996-06-01 19:25:30 +04:00
1996-05-04 11:50:46 +04:00
fclose ( f ) ;
return ( count ) ;
}
1996-06-06 15:43:09 +04:00
1996-05-04 11:50:46 +04:00
/*******************************************************************
fill in a server info structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int fill_srv_info ( struct srv_info_struct * service ,
int uLevel , char * * buf , int * buflen ,
char * * stringbuf , int * stringspace , char * baseaddr )
{
int struct_len ;
char * p ;
char * p2 ;
int l2 ;
int len ;
switch ( uLevel ) {
case 0 : struct_len = 16 ; break ;
case 1 : struct_len = 26 ; break ;
default : return - 1 ;
}
if ( ! buf )
{
len = 0 ;
switch ( uLevel )
{
case 1 :
len = strlen ( service - > comment ) + 1 ;
break ;
}
if ( buflen ) * buflen = struct_len ;
if ( stringspace ) * stringspace = len ;
return struct_len + len ;
}
len = struct_len ;
p = * buf ;
if ( * buflen < struct_len ) return - 1 ;
if ( stringbuf )
{
p2 = * stringbuf ;
l2 = * stringspace ;
}
else
{
p2 = p + struct_len ;
l2 = * buflen - struct_len ;
}
if ( ! baseaddr ) baseaddr = p ;
switch ( uLevel )
{
case 0 :
StrnCpy ( p , service - > name , 15 ) ;
break ;
case 1 :
StrnCpy ( p , service - > name , 15 ) ;
SIVAL ( p , 18 , service - > type ) ;
SIVAL ( p , 22 , PTR_DIFF ( p2 , baseaddr ) ) ;
len + = CopyAndAdvance ( & p2 , service - > comment , & l2 ) ;
break ;
}
if ( stringbuf )
{
* buf = p + struct_len ;
* buflen - = struct_len ;
* stringbuf = p2 ;
* stringspace = l2 ;
}
else
{
* buf = p2 ;
* buflen - = len ;
}
return len ;
}
1996-06-06 15:43:09 +04:00
static BOOL srv_comp ( struct srv_info_struct * s1 , struct srv_info_struct * s2 )
{
return ( strcmp ( s1 - > name , s2 - > name ) ) ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
view list of servers available ( or possibly domains ) . The info is
extracted from lists saved by nmbd on the local host
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_RNetServerEnum ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 = SVAL ( p , 0 ) ;
int buf_len = SVAL ( p , 2 ) ;
uint32 servertype = IVAL ( p , 4 ) ;
char * p2 ;
int data_len , fixed_len , string_len ;
int f_len , s_len ;
struct srv_info_struct * servers = NULL ;
int counted = 0 , total = 0 ;
1996-08-20 19:45:16 +04:00
int i , missed ;
1996-05-04 11:50:46 +04:00
fstring domain ;
1996-06-01 19:25:30 +04:00
BOOL domain_request ;
BOOL local_request = servertype & SV_TYPE_LOCAL_LIST_ONLY ;
if ( servertype = = SV_TYPE_ALL ) servertype & = ~ SV_TYPE_DOMAIN_ENUM ;
1996-08-17 15:37:44 +04:00
domain_request = ( ( servertype & SV_TYPE_DOMAIN_ENUM ) ! = 0 ) ;
1996-05-04 11:50:46 +04:00
p + = 8 ;
if ( ! prefix_ok ( str1 , " WrLehD " ) ) return False ;
if ( ! check_server_info ( uLevel , str2 ) ) return False ;
1996-06-01 19:25:30 +04:00
DEBUG ( 4 , ( " server request level: %s %8x " , str2 , servertype ) ) ;
DEBUG ( 4 , ( " domains_req:%s " , BOOLSTR ( domain_request ) ) ) ;
DEBUG ( 4 , ( " local_only:%s \n " , BOOLSTR ( local_request ) ) ) ;
1996-05-04 11:50:46 +04:00
1996-08-17 15:37:44 +04:00
if ( strcmp ( str1 , " WrLehDz " ) = = 0 ) {
1996-05-04 11:50:46 +04:00
StrnCpy ( domain , p , sizeof ( fstring ) - 1 ) ;
1996-10-02 19:41:30 +04:00
} else {
1997-05-20 04:32:51 +04:00
StrnCpy ( domain , myworkgroup , sizeof ( fstring ) - 1 ) ;
1996-05-04 11:50:46 +04:00
}
if ( lp_browse_list ( ) )
1996-08-17 15:37:44 +04:00
total = get_server_info ( servertype , & servers , domain ) ;
1996-05-04 11:50:46 +04:00
data_len = fixed_len = string_len = 0 ;
1996-08-20 19:45:16 +04:00
missed = 0 ;
1996-05-04 11:50:46 +04:00
1996-06-06 15:43:09 +04:00
qsort ( servers , total , sizeof ( servers [ 0 ] ) , QSORT_CAST srv_comp ) ;
1996-06-01 19:25:30 +04:00
{
1996-06-06 15:43:09 +04:00
char * lastname = NULL ;
1996-06-01 19:25:30 +04:00
for ( i = 0 ; i < total ; i + + )
{
struct srv_info_struct * s = & servers [ i ] ;
1996-08-17 15:37:44 +04:00
if ( lastname & & strequal ( lastname , s - > name ) ) continue ;
lastname = s - > name ;
data_len + = fill_srv_info ( s , uLevel , 0 , & f_len , 0 , & s_len , 0 ) ;
DEBUG ( 4 , ( " fill_srv_info %20s %8x %25s %15s \n " ,
s - > name , s - > type , s - > comment , s - > domain ) ) ;
1996-08-20 19:45:16 +04:00
if ( data_len < = buf_len ) {
1996-08-17 15:37:44 +04:00
counted + + ;
fixed_len + = f_len ;
string_len + = s_len ;
1996-08-20 19:45:16 +04:00
} else {
missed + + ;
}
1996-05-04 11:50:46 +04:00
}
1996-06-01 19:25:30 +04:00
}
1996-05-04 11:50:46 +04:00
* rdata_len = fixed_len + string_len ;
* rdata = REALLOC ( * rdata , * rdata_len ) ;
bzero ( * rdata , * rdata_len ) ;
p2 = ( * rdata ) + fixed_len ; /* auxilliary data (strings) will go here */
p = * rdata ;
f_len = fixed_len ;
s_len = string_len ;
{
1996-06-06 15:43:09 +04:00
char * lastname = NULL ;
1996-05-04 11:50:46 +04:00
int count2 = counted ;
1996-06-01 19:25:30 +04:00
for ( i = 0 ; i < total & & count2 ; i + + )
{
1996-06-06 15:43:09 +04:00
struct srv_info_struct * s = & servers [ i ] ;
1996-08-17 15:37:44 +04:00
if ( lastname & & strequal ( lastname , s - > name ) ) continue ;
lastname = s - > name ;
fill_srv_info ( s , uLevel , & p , & f_len , & p2 , & s_len , * rdata ) ;
DEBUG ( 4 , ( " fill_srv_info %20s %8x %25s %15s \n " ,
s - > name , s - > type , s - > comment , s - > domain ) ) ;
count2 - - ;
1996-05-04 11:50:46 +04:00
}
}
* rparam_len = 8 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVAL ( * rparam , 0 , NERR_Success ) ;
SSVAL ( * rparam , 2 , 0 ) ;
SSVAL ( * rparam , 4 , counted ) ;
1996-08-20 19:45:16 +04:00
SSVAL ( * rparam , 6 , counted + missed ) ;
1996-05-04 11:50:46 +04:00
if ( servers ) free ( servers ) ;
DEBUG ( 3 , ( " NetServerEnum domain = %s uLevel=%d counted=%d total=%d \n " ,
1996-08-20 19:45:16 +04:00
domain , uLevel , counted , counted + missed ) ) ;
1996-05-04 11:50:46 +04:00
return ( True ) ;
}
/****************************************************************************
get info about a share
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL check_share_info ( int uLevel , char * id )
{
switch ( uLevel ) {
case 0 :
if ( strcmp ( id , " B13 " ) ! = 0 ) return False ;
break ;
case 1 :
if ( strcmp ( id , " B13BWz " ) ! = 0 ) return False ;
break ;
case 2 :
if ( strcmp ( id , " B13BWzWWWzB9B " ) ! = 0 ) return False ;
break ;
case 91 :
if ( strcmp ( id , " B13BWzWWWzB9BB9BWzWWzWW " ) ! = 0 ) return False ;
break ;
default : return False ;
}
return True ;
}
static int fill_share_info ( int cnum , int snum , int uLevel ,
char * * buf , int * buflen ,
char * * stringbuf , int * stringspace , char * baseaddr )
{
int struct_len ;
char * p ;
char * p2 ;
int l2 ;
int len ;
switch ( uLevel ) {
case 0 : struct_len = 13 ; break ;
case 1 : struct_len = 20 ; break ;
case 2 : struct_len = 40 ; break ;
case 91 : struct_len = 68 ; break ;
default : return - 1 ;
}
if ( ! buf )
{
len = 0 ;
if ( uLevel > 0 ) len + = StrlenExpanded ( cnum , snum , lp_comment ( snum ) ) ;
if ( uLevel > 1 ) len + = strlen ( lp_pathname ( snum ) ) + 1 ;
if ( buflen ) * buflen = struct_len ;
if ( stringspace ) * stringspace = len ;
return struct_len + len ;
}
len = struct_len ;
p = * buf ;
if ( ( * buflen ) < struct_len ) return - 1 ;
if ( stringbuf )
{
p2 = * stringbuf ;
l2 = * stringspace ;
}
else
{
p2 = p + struct_len ;
l2 = ( * buflen ) - struct_len ;
}
if ( ! baseaddr ) baseaddr = p ;
StrnCpy ( p , lp_servicename ( snum ) , 13 ) ;
if ( uLevel > 0 )
{
int type ;
CVAL ( p , 13 ) = 0 ;
type = STYPE_DISKTREE ;
if ( lp_print_ok ( snum ) ) type = STYPE_PRINTQ ;
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 ) ;
}
if ( uLevel > 1 )
{
SSVAL ( p , 20 , ACCESS_READ | ACCESS_WRITE | ACCESS_CREATE ) ; /* permissions */
SSVALS ( p , 22 , - 1 ) ; /* max uses */
SSVAL ( p , 24 , 1 ) ; /* current uses */
SIVAL ( p , 26 , PTR_DIFF ( p2 , baseaddr ) ) ; /* local pathname */
len + = CopyAndAdvance ( & p2 , lp_pathname ( snum ) , & l2 ) ;
memset ( p + 30 , 0 , SHPWLEN + 2 ) ; /* passwd (reserved), pad field */
}
if ( uLevel > 2 )
{
memset ( p + 40 , 0 , SHPWLEN + 2 ) ;
SSVAL ( p , 50 , 0 ) ;
SIVAL ( p , 52 , 0 ) ;
SSVAL ( p , 56 , 0 ) ;
SSVAL ( p , 58 , 0 ) ;
SIVAL ( p , 60 , 0 ) ;
SSVAL ( p , 64 , 0 ) ;
SSVAL ( p , 66 , 0 ) ;
}
if ( stringbuf )
{
( * buf ) = p + struct_len ;
( * buflen ) - = struct_len ;
( * stringbuf ) = p2 ;
( * stringspace ) = l2 ;
}
else
{
( * buf ) = p2 ;
( * buflen ) - = len ;
}
return len ;
}
1996-10-26 00:10:53 +04:00
static BOOL api_RNetShareGetInfo ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 * netname = skip_string ( str2 , 1 ) ;
char * p = skip_string ( netname , 1 ) ;
int uLevel = SVAL ( p , 0 ) ;
int snum = find_service ( netname ) ;
if ( snum < 0 ) return False ;
/* check it's a supported varient */
if ( ! prefix_ok ( str1 , " zWrLh " ) ) return False ;
if ( ! check_share_info ( uLevel , str2 ) ) return False ;
* rdata = REALLOC ( * rdata , mdrcnt ) ;
p = * rdata ;
* rdata_len = fill_share_info ( cnum , snum , uLevel , & p , & mdrcnt , 0 , 0 , 0 ) ;
if ( * rdata_len < 0 ) return False ;
* rparam_len = 6 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVAL ( * rparam , 0 , NERR_Success ) ;
SSVAL ( * rparam , 2 , 0 ) ; /* converter word */
SSVAL ( * rparam , 4 , * rdata_len ) ;
return ( True ) ;
}
/****************************************************************************
view list of shares available
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_RNetShareEnum ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 = SVAL ( p , 0 ) ;
int buf_len = SVAL ( p , 2 ) ;
char * p2 ;
int count = lp_numservices ( ) ;
int total = 0 , counted = 0 ;
int i ;
int data_len , fixed_len , string_len ;
int f_len , s_len ;
if ( ! prefix_ok ( str1 , " WrLeh " ) ) return False ;
if ( ! check_share_info ( uLevel , str2 ) ) return False ;
data_len = fixed_len = string_len = 0 ;
for ( i = 0 ; i < count ; i + + )
if ( lp_browseable ( i ) & & lp_snum_ok ( i ) )
{
total + + ;
data_len + = fill_share_info ( cnum , i , uLevel , 0 , & f_len , 0 , & s_len , 0 ) ;
if ( data_len < = buf_len )
{
counted + + ;
fixed_len + = f_len ;
string_len + = s_len ;
}
}
* rdata_len = fixed_len + string_len ;
* rdata = REALLOC ( * rdata , * rdata_len ) ;
memset ( * rdata , 0 , * rdata_len ) ;
p2 = ( * rdata ) + fixed_len ; /* auxillery data (strings) will go here */
p = * rdata ;
f_len = fixed_len ;
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 )
break ;
* rparam_len = 8 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVAL ( * rparam , 0 , NERR_Success ) ;
SSVAL ( * rparam , 2 , 0 ) ;
SSVAL ( * rparam , 4 , counted ) ;
SSVAL ( * rparam , 6 , total ) ;
DEBUG ( 3 , ( " RNetShareEnum gave %d entries of %d (%d %d %d %d) \n " ,
counted , total , uLevel ,
buf_len , * rdata_len , mdrcnt ) ) ;
return ( True ) ;
}
/****************************************************************************
get the time of day info
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_NetRemoteTOD ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
int mdrcnt , int mprcnt ,
char * * rdata , char * * rparam ,
int * rdata_len , int * rparam_len )
{
char * p ;
* rparam_len = 4 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
* rdata_len = 21 ;
* rdata = REALLOC ( * rdata , * rdata_len ) ;
SSVAL ( * rparam , 0 , NERR_Success ) ;
SSVAL ( * rparam , 2 , 0 ) ; /* converter word */
p = * rdata ;
{
struct tm * t ;
time_t unixdate = time ( NULL ) ;
put_dos_date3 ( p , 0 , unixdate ) ; /* this is the time that is looked at
by NT in a " net time " operation ,
it seems to ignore the one below */
/* the client expects to get localtime, not GMT, in this bit
( I think , this needs testing ) */
1996-05-31 19:13:29 +04:00
t = LocalTime ( & unixdate ) ;
1996-05-04 11:50:46 +04:00
SIVAL ( p , 4 , 0 ) ; /* msecs ? */
CVAL ( p , 8 ) = t - > tm_hour ;
CVAL ( p , 9 ) = t - > tm_min ;
CVAL ( p , 10 ) = t - > tm_sec ;
CVAL ( p , 11 ) = 0 ; /* hundredths of seconds */
SSVALS ( p , 12 , TimeDiff ( unixdate ) / 60 ) ; /* timezone in minutes from GMT */
SSVAL ( p , 14 , 10000 ) ; /* timer interval in 0.0001 of sec */
CVAL ( p , 16 ) = t - > tm_mday ;
CVAL ( p , 17 ) = t - > tm_mon + 1 ;
SSVAL ( p , 18 , 1900 + t - > tm_year ) ;
CVAL ( p , 20 ) = t - > tm_wday ;
}
return ( True ) ;
}
/****************************************************************************
set the user password
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_SetUserPassword ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
int mdrcnt , int mprcnt ,
char * * rdata , char * * rparam ,
int * rdata_len , int * rparam_len )
{
char * p = skip_string ( param + 2 , 2 ) ;
fstring user ;
fstring pass1 , pass2 ;
strcpy ( user , p ) ;
p = skip_string ( p , 1 ) ;
StrnCpy ( pass1 , p , 16 ) ;
StrnCpy ( pass2 , p + 16 , 16 ) ;
* rparam_len = 4 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
* rdata_len = 0 ;
1996-08-09 22:05:34 +04:00
SSVAL ( * rparam , 0 , NERR_badpass ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( * rparam , 2 , 0 ) ; /* converter word */
DEBUG ( 3 , ( " Set password for <%s> \n " , user ) ) ;
1996-10-02 18:09:22 +04:00
if ( password_ok ( user , pass1 , strlen ( pass1 ) , NULL ) & &
1996-08-09 22:05:34 +04:00
chgpasswd ( user , pass1 , pass2 ) )
{
SSVAL ( * rparam , 0 , NERR_Success ) ;
}
1996-05-04 11:50:46 +04:00
bzero ( pass1 , sizeof ( fstring ) ) ;
bzero ( pass2 , sizeof ( fstring ) ) ;
return ( True ) ;
}
/****************************************************************************
delete a print job
Form : < W > < >
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_RDosPrintJobDel ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 = ( SVAL ( p , 0 ) & 0xFF ) ; /* the snum and jobid are encoded
by the print queue api */
int snum = ( SVAL ( p , 0 ) > > 8 ) ;
int i , count ;
/* check it's a supported varient */
if ( ! ( strcsequal ( str1 , " W " ) & & strcsequal ( str2 , " " ) ) )
return ( False ) ;
* rparam_len = 4 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
* rdata_len = 0 ;
SSVAL ( * rparam , 0 , NERR_Success ) ;
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 ) ;
if ( queue ) free ( queue ) ;
}
SSVAL ( * rparam , 2 , 0 ) ; /* converter word */
return ( True ) ;
}
1996-10-26 00:10:53 +04:00
static BOOL api_WPrintQueuePurge ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 * QueueName = skip_string ( str2 , 1 ) ;
int snum ;
/* check it's a supported varient */
if ( ! ( strcsequal ( str1 , " z " ) & & strcsequal ( str2 , " " ) ) )
return ( False ) ;
* rparam_len = 4 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
* rdata_len = 0 ;
SSVAL ( * rparam , 0 , NERR_Success ) ;
SSVAL ( * rparam , 2 , 0 ) ; /* converter word */
snum = lp_servicenumber ( QueueName ) ;
if ( snum < 0 & & pcap_printername_ok ( QueueName , NULL ) ) {
int pnum = lp_servicenumber ( PRINTERS_NAME ) ;
if ( pnum > = 0 ) {
lp_add_printer ( QueueName , pnum ) ;
snum = lp_servicenumber ( QueueName ) ;
}
}
if ( snum > = 0 & & VALID_SNUM ( snum ) ) {
print_queue_struct * queue = NULL ;
int i , count ;
lpq_reset ( snum ) ;
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 ) ) ;
return ( True ) ;
}
/****************************************************************************
set the property of a print job ( undocumented ? )
? function = 0xb - > set name of print job
? function = 0x6 - > move print job up / down
Form : < WWsTP > < WWzWWDDzzzzzzzzzzlz >
or < WWsTP > < WB21BB16B10zWWzDDz >
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 ;
}
1996-10-26 00:10:53 +04:00
static BOOL api_PrintJobInfo ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 = ( SVAL ( p , 0 ) & 0xFF ) ; /* the snum and jobid are encoded
by the print queue api */
int snum = ( SVAL ( p , 0 ) > > 8 ) ;
int uLevel = SVAL ( p , 2 ) ;
int function = SVAL ( p , 4 ) ; /* what is this ?? */
int i ;
char * s = data ;
* 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 ;
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 )
{
1996-05-04 14:43:29 +04:00
if ( issafe ( * s ) ) name [ l + + ] = * s ;
1996-05-04 11:50:46 +04:00
s + + ;
}
name [ l ] = 0 ;
DEBUG ( 3 , ( " Setting print name to %s \n " , name ) ) ;
for ( i = 0 ; i < MAX_OPEN_FILES ; i + + )
if ( Files [ i ] . open & & Files [ i ] . print_file )
{
pstring wd ;
GetWd ( wd ) ;
unbecome_user ( ) ;
1996-10-26 00:10:53 +04:00
if ( ! become_user ( Files [ i ] . cnum , vuid ) | |
1996-05-04 11:50:46 +04:00
! become_service ( Files [ i ] . cnum , True ) )
break ;
if ( sys_rename ( Files [ i ] . name , name ) = = 0 )
string_set ( & Files [ i ] . name , name ) ;
break ;
}
}
desc . errcode = NERR_Success ;
break ;
default : /* not implemented */
return False ;
}
SSVALS ( * rparam , 0 , desc . errcode ) ;
SSVAL ( * rparam , 2 , 0 ) ; /* converter word */
return ( True ) ;
}
/****************************************************************************
get info about the server
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_RNetServerGetInfo ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 = SVAL ( p , 0 ) ;
char * p2 ;
int struct_len ;
DEBUG ( 4 , ( " NetServerGetInfo level %d \n " , uLevel ) ) ;
/* check it's a supported varient */
if ( ! prefix_ok ( str1 , " WrLh " ) ) return False ;
switch ( uLevel ) {
case 0 :
if ( strcmp ( str2 , " B16 " ) ! = 0 ) return False ;
struct_len = 16 ;
break ;
case 1 :
if ( strcmp ( str2 , " B16BBDz " ) ! = 0 ) return False ;
struct_len = 26 ;
break ;
case 2 :
if ( strcmp ( str2 , " B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWz " )
! = 0 ) return False ;
struct_len = 134 ;
break ;
case 3 :
if ( strcmp ( str2 , " B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWzDWz " )
! = 0 ) return False ;
struct_len = 144 ;
break ;
case 20 :
if ( strcmp ( str2 , " DN " ) ! = 0 ) return False ;
struct_len = 6 ;
break ;
case 50 :
if ( strcmp ( str2 , " B16BBDzWWzzz " ) ! = 0 ) return False ;
struct_len = 42 ;
break ;
default : return False ;
}
* rdata_len = mdrcnt ;
* rdata = REALLOC ( * rdata , * rdata_len ) ;
p = * rdata ;
p2 = p + struct_len ;
if ( uLevel ! = 20 ) {
StrnCpy ( p , local_machine , 16 ) ;
strupper ( p ) ;
}
p + = 16 ;
if ( uLevel > 0 )
{
struct srv_info_struct * servers = NULL ;
int i , count ;
pstring comment ;
1996-08-21 10:09:00 +04:00
uint32 servertype = DFLT_SERVER_TYPE ;
1996-05-04 11:50:46 +04:00
strcpy ( comment , lp_serverstring ( ) ) ;
1997-05-20 04:32:51 +04:00
if ( ( count = get_server_info ( SV_TYPE_ALL , & servers , myworkgroup ) ) > 0 ) {
1996-05-04 11:50:46 +04:00
for ( i = 0 ; i < count ; i + + )
1997-03-09 17:58:22 +03:00
if ( strequal ( servers [ i ] . name , local_machine ) )
{
1996-05-04 11:50:46 +04:00
servertype = servers [ i ] . type ;
strcpy ( comment , servers [ i ] . comment ) ;
}
}
if ( servers ) free ( servers ) ;
1996-08-09 22:05:34 +04:00
SCVAL ( p , 0 , MAJOR_VERSION ) ;
SCVAL ( p , 1 , MINOR_VERSION ) ;
1996-05-04 11:50:46 +04:00
SIVAL ( p , 2 , servertype ) ;
1996-08-09 22:05:34 +04:00
1996-05-04 11:50:46 +04:00
if ( mdrcnt = = struct_len ) {
SIVAL ( p , 6 , 0 ) ;
} else {
SIVAL ( p , 6 , PTR_DIFF ( p2 , * rdata ) ) ;
standard_sub ( cnum , comment ) ;
StrnCpy ( p2 , comment , MAX ( mdrcnt - struct_len , 0 ) ) ;
p2 = skip_string ( p2 , 1 ) ;
}
}
if ( uLevel > 1 )
{
return False ; /* not yet implemented */
}
* rdata_len = PTR_DIFF ( p2 , * rdata ) ;
* rparam_len = 6 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVAL ( * rparam , 0 , NERR_Success ) ;
SSVAL ( * rparam , 2 , 0 ) ; /* converter word */
SSVAL ( * rparam , 4 , * rdata_len ) ;
return ( True ) ;
}
/****************************************************************************
get info about the server
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_NetWkstaGetInfo ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 ) ;
char * p2 ;
extern pstring sesssetup_user ;
int level = SVAL ( p , 0 ) ;
DEBUG ( 4 , ( " NetWkstaGetInfo level %d \n " , level ) ) ;
* rparam_len = 6 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
/* check it's a supported varient */
if ( ! ( level = = 10 & & strcsequal ( str1 , " WrLh " ) & & strcsequal ( str2 , " zzzBBzz " ) ) )
return ( False ) ;
* rdata_len = mdrcnt + 1024 ;
* rdata = REALLOC ( * rdata , * rdata_len ) ;
SSVAL ( * rparam , 0 , NERR_Success ) ;
SSVAL ( * rparam , 2 , 0 ) ; /* converter word */
p = * rdata ;
p2 = p + 22 ;
1997-03-09 17:58:22 +03:00
SIVAL ( p , 0 , PTR_DIFF ( p2 , * rdata ) ) ; /* host name */
1996-05-04 11:50:46 +04:00
strcpy ( p2 , local_machine ) ;
1997-03-09 17:58:22 +03:00
strupper ( p2 ) ;
1996-05-04 11:50:46 +04:00
p2 = skip_string ( p2 , 1 ) ;
p + = 4 ;
SIVAL ( p , 0 , PTR_DIFF ( p2 , * rdata ) ) ;
strcpy ( p2 , sesssetup_user ) ;
p2 = skip_string ( p2 , 1 ) ;
p + = 4 ;
1997-03-09 17:58:22 +03:00
SIVAL ( p , 0 , PTR_DIFF ( p2 , * rdata ) ) ; /* login domain */
1997-05-20 04:32:51 +04:00
strcpy ( p2 , myworkgroup ) ;
1997-03-09 17:58:22 +03:00
strupper ( p2 ) ;
1996-05-04 11:50:46 +04:00
p2 = skip_string ( p2 , 1 ) ;
p + = 4 ;
1997-03-09 17:58:22 +03:00
SCVAL ( p , 0 , MAJOR_VERSION ) ; /* system version - e.g 4 in 4.1 */
SCVAL ( p , 1 , MINOR_VERSION ) ; /* system version - e.g .1 in 4.1 */
1996-05-04 11:50:46 +04:00
p + = 2 ;
SIVAL ( p , 0 , PTR_DIFF ( p2 , * rdata ) ) ;
1997-05-20 04:32:51 +04:00
strcpy ( p2 , myworkgroup ) ; /* don't know. login domain?? */
1996-05-04 11:50:46 +04:00
p2 = skip_string ( p2 , 1 ) ;
p + = 4 ;
1997-03-09 17:58:22 +03:00
SIVAL ( p , 0 , PTR_DIFF ( p2 , * rdata ) ) ; /* don't know */
1996-05-04 11:50:46 +04:00
strcpy ( p2 , " " ) ;
p2 = skip_string ( p2 , 1 ) ;
p + = 4 ;
* rdata_len = PTR_DIFF ( p2 , * rdata ) ;
SSVAL ( * rparam , 4 , * rdata_len ) ;
return ( True ) ;
}
/****************************************************************************
get info about a user
1997-03-09 17:58:22 +03:00
struct user_info_11 {
char usri11_name [ 21 ] ; 0 - 20
char usri11_pad ; 21
char * usri11_comment ; 22 - 25
char * usri11_usr_comment ; 26 - 29
unsigned short usri11_priv ; 30 - 31
unsigned long usri11_auth_flags ; 32 - 35
long usri11_password_age ; 36 - 39
char * usri11_homedir ; 40 - 43
char * usri11_parms ; 44 - 47
long usri11_last_logon ; 48 - 51
long usri11_last_logoff ; 52 - 55
unsigned short usri11_bad_pw_count ; 56 - 57
unsigned short usri11_num_logons ; 58 - 59
char * usri11_logon_server ; 60 - 63
unsigned short usri11_country_code ; 64 - 65
char * usri11_workstations ; 66 - 69
unsigned long usri11_max_storage ; 70 - 73
unsigned short usri11_units_per_week ; 74 - 75
unsigned char * usri11_logon_hours ; 76 - 79
unsigned short usri11_code_page ; 80 - 81
} ;
where :
usri11_name specifies the user name for which information is retireved
usri11_pad aligns the next data structure element to a word boundary
usri11_comment is a null terminated ASCII comment
usri11_user_comment is a null terminated ASCII comment about the user
usri11_priv specifies the level of the privilege assigned to the user .
The possible values are :
Name Value Description
USER_PRIV_GUEST 0 Guest privilege
USER_PRIV_USER 1 User privilege
USER_PRV_ADMIN 2 Administrator privilege
usri11_auth_flags specifies the account operator privileges . The
possible values are :
Name Value Description
AF_OP_PRINT 0 Print operator
Leach , Naik [ Page 28 ]
INTERNET - DRAFT CIFS Remote Admin Protocol January 10 , 1997
AF_OP_COMM 1 Communications operator
AF_OP_SERVER 2 Server operator
AF_OP_ACCOUNTS 3 Accounts operator
usri11_password_age specifies how many seconds have elapsed since the
password was last changed .
usri11_home_dir points to a null terminated ASCII string that contains
the path name of the user ' s home directory .
usri11_parms points to a null terminated ASCII string that is set
aside for use by applications .
usri11_last_logon specifies the time when the user last logged on .
This value is stored as the number of seconds elapsed since
00 : 00 : 00 , January 1 , 1970.
usri11_last_logoff specifies the time when the user last logged off .
This value is stored as the number of seconds elapsed since
00 : 00 : 00 , January 1 , 1970. A value of 0 means the last logoff
time is unknown .
usri11_bad_pw_count specifies the number of incorrect passwords
entered since the last successful logon .
usri11_log1_num_logons specifies the number of times this user has
logged on . A value of - 1 means the number of logons is unknown .
usri11_logon_server points to a null terminated ASCII string that
contains the name of the server to which logon requests are sent .
A null string indicates logon requests should be sent to the
domain controller .
usri11_country_code specifies the country code for the user ' s language
of choice .
usri11_workstations points to a null terminated ASCII string that
contains the names of workstations the user may log on from .
There may be up to 8 workstations , with the names separated by
commas . A null strings indicates there are no restrictions .
usri11_max_storage specifies the maximum amount of disk space the user
can occupy . A value of 0xffffffff indicates there are no
restrictions .
usri11_units_per_week specifies the equal number of time units into
which a week is divided . This value must be equal to 168.
usri11_logon_hours points to a 21 byte ( 168 bits ) string that
specifies the time during which the user can log on . Each bit
represents one unique hour in a week . The first bit ( bit 0 , word
0 ) is Sunday , 0 : 00 to 0 : 59 , the second bit ( bit 1 , word 0 ) is
Leach , Naik [ Page 29 ]
INTERNET - DRAFT CIFS Remote Admin Protocol January 10 , 1997
Sunday , 1 : 00 to 1 : 59 and so on . A null pointer indicates there
are no restrictions .
usri11_code_page specifies the code page for the user ' s language of
choice
All of the pointers in this data structure need to be treated
specially . The pointer is a 32 bit pointer . The higher 16 bits need
to be ignored . The converter word returned in the parameters section
needs to be subtracted from the lower 16 bits to calculate an offset
into the return buffer where this ASCII string resides .
There is no auxiliary data in the response .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-03-09 17:58:22 +03:00
# define usri11_name 0
# define usri11_pad 21
# define usri11_comment 22
# define usri11_usr_comment 26
# define usri11_full_name 30
# define usri11_priv 34
# define usri11_auth_flags 36
# define usri11_password_age 40
# define usri11_homedir 44
# define usri11_parms 48
# define usri11_last_logon 52
# define usri11_last_logoff 56
# define usri11_bad_pw_count 60
# define usri11_num_logons 62
# define usri11_logon_server 64
# define usri11_country_code 68
# define usri11_workstations 70
# define usri11_max_storage 74
# define usri11_units_per_week 78
# define usri11_logon_hours 80
# define usri11_code_page 84
# define usri11_end 86
1996-05-04 11:50:46 +04:00
# define USER_PRIV_GUEST 0
# define USER_PRIV_USER 1
# define USER_PRIV_ADMIN 2
1997-03-09 17:58:22 +03:00
# define AF_OP_PRINT 0
# define AF_OP_COMM 1
# define AF_OP_SERVER 2
# define AF_OP_ACCOUNTS 3
1997-05-07 21:56:46 +04:00
1996-10-26 00:10:53 +04:00
static BOOL api_RNetUserGetInfo ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
int mdrcnt , int mprcnt ,
char * * rdata , char * * rparam ,
int * rdata_len , int * rparam_len )
{
1997-03-09 17:58:22 +03:00
char * str1 = param + 2 ;
char * str2 = skip_string ( str1 , 1 ) ;
char * UserName = skip_string ( str2 , 1 ) ;
char * p = skip_string ( UserName , 1 ) ;
int uLevel = SVAL ( p , 0 ) ;
char * p2 ;
1997-05-07 21:56:46 +04:00
/* get NIS home of a previously validated user - simeon */
user_struct * vuser = get_valid_user_struct ( vuid ) ;
DEBUG ( 3 , ( " Username of UID %d is %s \n " , vuser - > uid , vuser - > name ) ) ;
1997-06-11 05:03:06 +04:00
# if (defined(NETGROUP) && defined(AUTOMOUNT))
1997-05-07 21:56:46 +04:00
DEBUG ( 3 , ( " HOMESHR for %s is %s \n " , vuser - > name , vuser - > home_share ) ) ;
1997-06-11 05:03:06 +04:00
# endif
1997-03-09 17:58:22 +03:00
1997-05-07 21:56:46 +04:00
* rparam_len = 6 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
/* check it's a supported variant */
1997-03-09 17:58:22 +03:00
if ( strcmp ( str1 , " zWrLh " ) ! = 0 ) return False ;
switch ( uLevel )
{
case 0 : p2 = " B21 " ; break ;
case 1 : p2 = " B21BB16DWzzWz " ; break ;
case 2 : p2 = " B21BB16DWzzWzDzzzzDDDDWb21WWzWW " ; break ;
case 10 : p2 = " B21Bzzz " ; break ;
case 11 : p2 = " B21BzzzWDDzzDDWWzWzDWb21W " ; break ;
default : return False ;
}
1996-05-04 11:50:46 +04:00
1997-03-09 17:58:22 +03:00
if ( strcmp ( p2 , str2 ) ! = 0 ) return False ;
1996-05-04 11:50:46 +04:00
1997-03-09 17:58:22 +03:00
* rdata_len = mdrcnt + 1024 ;
* rdata = REALLOC ( * rdata , * rdata_len ) ;
1996-05-04 11:50:46 +04:00
1997-03-09 17:58:22 +03:00
SSVAL ( * rparam , 0 , NERR_Success ) ;
SSVAL ( * rparam , 2 , 0 ) ; /* converter word */
1996-05-04 11:50:46 +04:00
1997-03-09 17:58:22 +03:00
p = * rdata ;
p2 = p + usri11_end ;
1996-05-04 11:50:46 +04:00
1997-03-09 17:58:22 +03:00
memset ( p , 0 , 21 ) ;
strcpy ( p + usri11_name , UserName ) ; /* 21 bytes - user name */
1996-05-04 11:50:46 +04:00
1997-03-09 17:58:22 +03:00
if ( uLevel > 0 )
{
SCVAL ( p , usri11_pad , 0 ) ; /* padding - 1 byte */
* p2 = 0 ;
}
if ( uLevel > = 10 )
{
SIVAL ( p , usri11_comment , PTR_DIFF ( p2 , p ) ) ; /* comment */
strcpy ( p2 , " Comment " ) ;
p2 = skip_string ( p2 , 1 ) ;
SIVAL ( p , usri11_usr_comment , PTR_DIFF ( p2 , p ) ) ; /* user_comment */
strcpy ( p2 , " UserComment " ) ;
p2 = skip_string ( p2 , 1 ) ;
/* EEK! the cifsrap.txt doesn't have this in!!!! */
SIVAL ( p , usri11_full_name , PTR_DIFF ( p2 , p ) ) ; /* full name */
1997-05-07 21:56:46 +04:00
strcpy ( p2 , vuser - > real_name ) ; /* simeon */
1997-03-09 17:58:22 +03:00
p2 = skip_string ( p2 , 1 ) ;
}
1997-05-07 21:56:46 +04:00
1997-03-09 17:58:22 +03:00
if ( uLevel = = 11 ) /* modelled after NTAS 3.51 reply */
{
SSVAL ( p , usri11_priv , Connections [ cnum ] . admin_user ? USER_PRIV_ADMIN : USER_PRIV_USER ) ;
SIVAL ( p , usri11_auth_flags , AF_OP_PRINT ) ; /* auth flags */
SIVALS ( p , usri11_password_age , 0xffffffff ) ; /* password age */
SIVAL ( p , usri11_homedir , PTR_DIFF ( p2 , p ) ) ; /* home dir */
if ( * lp_logon_path ( ) )
{
strcpy ( p2 , lp_logon_path ( ) ) ;
}
else
{
1997-05-07 21:56:46 +04:00
# if (defined(NETGROUP) && defined(AUTOMOUNT))
strcpy ( p2 , vuser - > home_share ) ;
# else
1997-03-09 17:58:22 +03:00
strcpy ( p2 , " \\ \\ %L \\ %U " ) ;
1997-05-07 21:56:46 +04:00
# endif
1997-03-09 17:58:22 +03:00
}
standard_sub_basic ( p2 ) ;
p2 = skip_string ( p2 , 1 ) ;
SIVAL ( p , usri11_parms , PTR_DIFF ( p2 , p ) ) ; /* parms */
strcpy ( p2 , " " ) ;
p2 = skip_string ( p2 , 1 ) ;
SIVAL ( p , usri11_last_logon , 0 ) ; /* last logon */
SIVAL ( p , usri11_last_logoff , 0 ) ; /* last logoff */
SSVALS ( p , usri11_bad_pw_count , 0xffffffff ) ; /* bad pw counts */
SSVALS ( p , usri11_num_logons , 0xffffffff ) ; /* num logons */
SIVAL ( p , usri11_logon_server , PTR_DIFF ( p2 , p ) ) ; /* logon server */
strcpy ( p2 , " \\ \\ * " ) ;
p2 = skip_string ( p2 , 1 ) ;
SSVAL ( p , usri11_country_code , 0 ) ; /* country code */
SIVAL ( p , usri11_workstations , PTR_DIFF ( p2 , p ) ) ; /* workstations */
strcpy ( p2 , " " ) ;
p2 = skip_string ( p2 , 1 ) ;
SIVALS ( p , usri11_max_storage , 0xffffffff ) ; /* max storage */
SSVAL ( p , usri11_units_per_week , 168 ) ; /* units per week */
SIVAL ( p , usri11_logon_hours , PTR_DIFF ( p2 , p ) ) ; /* logon hours */
/* a simple way to get logon hours at all times. */
memset ( p2 , 0xff , 21 ) ;
SCVAL ( p2 , 21 , 0 ) ; /* fix zero termination */
p2 = skip_string ( p2 , 1 ) ;
SSVAL ( p , usri11_code_page , 0 ) ; /* code page */
}
if ( uLevel = = 1 | | uLevel = = 2 )
{
memset ( p + 22 , ' ' , 16 ) ; /* password */
SIVALS ( p , 38 , - 1 ) ; /* password age */
SSVAL ( p , 42 ,
Connections [ cnum ] . admin_user ? USER_PRIV_ADMIN : USER_PRIV_USER ) ;
SIVAL ( p , 44 , PTR_DIFF ( p2 , * rdata ) ) ; /* home dir */
if ( * lp_logon_path ( ) )
{
strcpy ( p2 , lp_logon_path ( ) ) ;
}
else
{
1997-05-07 21:56:46 +04:00
# if (defined(NETGROUP) && defined(AUTOMOUNT))
strcpy ( p2 , vuser - > home_share ) ;
# else
1997-03-09 17:58:22 +03:00
strcpy ( p2 , " \\ \\ %L \\ %U " ) ;
1997-05-07 21:56:46 +04:00
# endif
1997-03-09 17:58:22 +03:00
}
standard_sub_basic ( p2 ) ;
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 */
if ( uLevel = = 2 )
{
SIVAL ( p , 60 , 0 ) ; /* auth_flags */
SIVAL ( p , 64 , PTR_DIFF ( p2 , * rdata ) ) ; /* full_name */
1997-05-07 21:56:46 +04:00
strcpy ( p2 , vuser - > real_name ) ; /* simeon */
1997-03-09 17:58:22 +03:00
p2 = skip_string ( p2 , 1 ) ;
SIVAL ( p , 68 , 0 ) ; /* urs_comment */
SIVAL ( p , 72 , PTR_DIFF ( p2 , * rdata ) ) ; /* parms */
strcpy ( p2 , " " ) ;
p2 = skip_string ( p2 , 1 ) ;
SIVAL ( p , 76 , 0 ) ; /* workstations */
SIVAL ( p , 80 , 0 ) ; /* last_logon */
SIVAL ( p , 84 , 0 ) ; /* last_logoff */
SIVALS ( p , 88 , - 1 ) ; /* acct_expires */
SIVALS ( p , 92 , - 1 ) ; /* max_storage */
SSVAL ( p , 96 , 168 ) ; /* units_per_week */
SIVAL ( p , 98 , PTR_DIFF ( p2 , * rdata ) ) ; /* logon_hours */
memset ( p2 , - 1 , 21 ) ;
p2 + = 21 ;
SSVALS ( p , 102 , - 1 ) ; /* bad_pw_count */
SSVALS ( p , 104 , - 1 ) ; /* num_logons */
SIVAL ( p , 106 , PTR_DIFF ( p2 , * rdata ) ) ; /* logon_server */
strcpy ( p2 , " \\ \\ %L " ) ;
standard_sub_basic ( p2 ) ;
p2 = skip_string ( p2 , 1 ) ;
SSVAL ( p , 110 , 49 ) ; /* country_code */
SSVAL ( p , 112 , 860 ) ; /* code page */
}
}
1996-05-04 11:50:46 +04:00
1997-03-09 17:58:22 +03:00
* rdata_len = PTR_DIFF ( p2 , * rdata ) ;
1996-05-04 11:50:46 +04:00
1997-03-09 17:58:22 +03:00
SSVAL ( * rparam , 4 , * rdata_len ) ; /* is this right?? */
1996-05-04 11:50:46 +04:00
1997-03-09 17:58:22 +03:00
return ( True ) ;
1996-05-04 11:50:46 +04:00
}
/*******************************************************************
get groups that a user is a member of
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_NetUserGetGroups ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 * UserName = skip_string ( str2 , 1 ) ;
char * p = skip_string ( UserName , 1 ) ;
int uLevel = SVAL ( p , 0 ) ;
char * p2 ;
int count = 0 ;
* rparam_len = 8 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
/* check it's a supported varient */
if ( strcmp ( str1 , " zWrLeh " ) ! = 0 ) return False ;
switch ( uLevel ) {
case 0 : p2 = " B21 " ; break ;
default : return False ;
}
if ( strcmp ( p2 , str2 ) ! = 0 ) return False ;
* rdata_len = mdrcnt + 1024 ;
* rdata = REALLOC ( * rdata , * rdata_len ) ;
SSVAL ( * rparam , 0 , NERR_Success ) ;
SSVAL ( * rparam , 2 , 0 ) ; /* converter word */
p = * rdata ;
/* XXXX we need a real SAM database some day */
strcpy ( p , " Users " ) ; p + = 21 ; count + + ;
strcpy ( p , " Domain Users " ) ; p + = 21 ; count + + ;
strcpy ( p , " Guests " ) ; p + = 21 ; count + + ;
strcpy ( p , " Domain Guests " ) ; p + = 21 ; count + + ;
* rdata_len = PTR_DIFF ( p , * rdata ) ;
SSVAL ( * rparam , 4 , count ) ; /* is this right?? */
SSVAL ( * rparam , 6 , count ) ; /* is this right?? */
return ( True ) ;
}
1996-10-26 00:10:53 +04:00
static BOOL api_WWkstaUserLogon ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 ;
struct pack_desc desc ;
char * name ;
uLevel = SVAL ( p , 0 ) ;
name = p + 2 ;
bzero ( & desc , sizeof ( desc ) ) ;
DEBUG ( 3 , ( " WWkstaUserLogon uLevel=%d name=%s \n " , uLevel , name ) ) ;
/* check it's a supported varient */
if ( strcmp ( str1 , " OOWb54WrLh " ) ! = 0 ) return False ;
if ( uLevel ! = 1 | | strcmp ( str2 , " WB21BWDWWDDDDDDDzzzD " ) ! = 0 ) return False ;
if ( mdrcnt > 0 ) * rdata = REALLOC ( * rdata , mdrcnt ) ;
desc . base = * rdata ;
desc . buflen = mdrcnt ;
desc . subformat = NULL ;
desc . format = str2 ;
1997-03-09 17:58:22 +03:00
if ( init_package ( & desc , 1 , 0 ) )
{
1996-05-04 11:50:46 +04:00
PACKI ( & desc , " W " , 0 ) ; /* code */
PACKS ( & desc , " B21 " , name ) ; /* eff. name */
PACKS ( & desc , " B " , " " ) ; /* pad */
PACKI ( & desc , " W " ,
Connections [ cnum ] . 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 */
1997-03-09 17:58:22 +03:00
PACKI ( & desc , " D " , 0 ) ; /* last logon */
1996-05-04 11:50:46 +04:00
PACKI ( & desc , " D " , - 1 ) ; /* last logoff */
PACKI ( & desc , " D " , - 1 ) ; /* logoff time */
PACKI ( & desc , " D " , - 1 ) ; /* kickoff time */
PACKI ( & desc , " D " , 0 ) ; /* password age */
PACKI ( & desc , " D " , 0 ) ; /* password can change */
PACKI ( & desc , " D " , - 1 ) ; /* password must change */
{
fstring mypath ;
strcpy ( mypath , " \\ \\ " ) ;
strcat ( mypath , local_machine ) ;
strupper ( mypath ) ;
PACKS ( & desc , " z " , mypath ) ; /* computer */
}
1997-05-20 04:32:51 +04:00
PACKS ( & desc , " z " , myworkgroup ) ; /* domain */
1996-05-04 11:50:46 +04:00
PACKS ( & desc , " z " , lp_logon_script ( ) ) ; /* script path */
1997-03-09 17:58:22 +03:00
PACKI ( & desc , " D " , 0x00000000 ) ; /* reserved */
1996-05-04 11:50:46 +04:00
}
* rdata_len = desc . usedlen ;
* rparam_len = 6 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVALS ( * rparam , 0 , desc . errcode ) ;
SSVAL ( * rparam , 2 , 0 ) ;
SSVAL ( * rparam , 4 , desc . neededlen ) ;
DEBUG ( 4 , ( " WWkstaUserLogon: errorcode %d \n " , desc . errcode ) ) ;
return ( True ) ;
}
/****************************************************************************
api_WAccessGetUserPerms
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_WAccessGetUserPerms ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 * user = skip_string ( str2 , 1 ) ;
char * resource = skip_string ( user , 1 ) ;
DEBUG ( 3 , ( " WAccessGetUserPerms user=%s resource=%s \n " , user , resource ) ) ;
/* check it's a supported varient */
if ( strcmp ( str1 , " zzh " ) ! = 0 ) return False ;
if ( strcmp ( str2 , " " ) ! = 0 ) return False ;
* rparam_len = 6 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVALS ( * rparam , 0 , 0 ) ; /* errorcode */
SSVAL ( * rparam , 2 , 0 ) ; /* converter word */
SSVAL ( * rparam , 4 , 0x7f ) ; /* permission flags */
return ( True ) ;
}
/****************************************************************************
api_WPrintJobEnumerate
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_WPrintJobGetInfo ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 uJobId = SVAL ( p , 0 ) ;
int uLevel , cbBuf ;
int count ;
int i ;
int snum ;
int job ;
struct pack_desc desc ;
print_queue_struct * queue = NULL ;
print_status_struct status ;
uLevel = SVAL ( p , 2 ) ;
cbBuf = SVAL ( p , 4 ) ;
bzero ( & desc , sizeof ( desc ) ) ;
bzero ( & status , sizeof ( status ) ) ;
DEBUG ( 3 , ( " WPrintJobGetInfo uLevel=%d uJobId=0x%X \n " , uLevel , uJobId ) ) ;
/* check it's a supported varient */
if ( strcmp ( str1 , " WWrLh " ) ! = 0 ) return False ;
if ( ! check_printjob_info ( & desc , uLevel , str2 ) ) return False ;
snum = ( unsigned int ) uJobId > > 8 ; /*## valid serice number??*/
job = uJobId & 0xFF ;
if ( snum < 0 | | ! VALID_SNUM ( snum ) ) return ( False ) ;
count = get_printqueue ( snum , cnum , & queue , & status ) ;
for ( i = 0 ; i < count ; i + + ) {
if ( ( queue [ i ] . job % 0xFF ) = = job ) break ;
}
if ( mdrcnt > 0 ) * rdata = REALLOC ( * rdata , mdrcnt ) ;
desc . base = * rdata ;
desc . buflen = mdrcnt ;
if ( init_package ( & desc , 1 , 0 ) ) {
if ( i < count ) {
fill_printjob_info ( cnum , snum , uLevel , & desc , & queue [ i ] , i ) ;
* rdata_len = desc . usedlen ;
}
else {
desc . errcode = NERR_JobNotFound ;
* rdata_len = 0 ;
}
}
* rparam_len = 6 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVALS ( * rparam , 0 , desc . errcode ) ;
SSVAL ( * rparam , 2 , 0 ) ;
SSVAL ( * rparam , 4 , desc . neededlen ) ;
if ( queue ) free ( queue ) ;
DEBUG ( 4 , ( " WPrintJobGetInfo: errorcode %d \n " , desc . errcode ) ) ;
return ( True ) ;
}
1996-10-26 00:10:53 +04:00
static BOOL api_WPrintJobEnumerate ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 ) ;
char * name = p ;
int uLevel , cbBuf ;
int count ;
int i , succnt = 0 ;
int snum ;
struct pack_desc desc ;
print_queue_struct * queue = NULL ;
print_status_struct status ;
bzero ( & desc , sizeof ( desc ) ) ;
bzero ( & status , 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 ) ) ;
/* check it's a supported varient */
if ( strcmp ( str1 , " zWrLeh " ) ! = 0 ) return False ;
if ( uLevel > 2 ) return False ; /* defined only for uLevel 0,1,2 */
if ( ! check_printjob_info ( & desc , uLevel , str2 ) ) return False ;
snum = lp_servicenumber ( name ) ;
if ( snum < 0 & & pcap_printername_ok ( name , NULL ) ) {
int pnum = lp_servicenumber ( PRINTERS_NAME ) ;
if ( pnum > = 0 ) {
lp_add_printer ( name , pnum ) ;
snum = lp_servicenumber ( name ) ;
}
}
if ( snum < 0 | | ! VALID_SNUM ( snum ) ) return ( False ) ;
count = get_printqueue ( snum , cnum , & 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 ) ;
if ( desc . errcode = = NERR_Success ) succnt = i + 1 ;
}
}
* rdata_len = desc . usedlen ;
* rparam_len = 8 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVALS ( * rparam , 0 , desc . errcode ) ;
SSVAL ( * rparam , 2 , 0 ) ;
SSVAL ( * rparam , 4 , succnt ) ;
SSVAL ( * rparam , 6 , count ) ;
if ( queue ) free ( queue ) ;
DEBUG ( 4 , ( " WPrintJobEnumerate: errorcode %d \n " , desc . errcode ) ) ;
return ( True ) ;
}
static int check_printdest_info ( struct pack_desc * desc ,
int uLevel , char * id )
{
desc - > subformat = NULL ;
switch ( uLevel ) {
case 0 : desc - > format = " B9 " ; break ;
case 1 : desc - > format = " B9B21WWzW " ; break ;
case 2 : desc - > format = " z " ; break ;
case 3 : desc - > format = " zzzWWzzzWW " ; break ;
default : return False ;
}
if ( strcmp ( desc - > format , id ) ! = 0 ) return False ;
return True ;
}
static void fill_printdest_info ( int cnum , int snum , int uLevel ,
struct pack_desc * desc )
{
char buf [ 100 ] ;
strcpy ( buf , SERVICE ( snum ) ) ;
strupper ( buf ) ;
if ( uLevel < = 1 ) {
PACKS ( desc , " B9 " , buf ) ; /* szName */
if ( uLevel = = 1 ) {
PACKS ( desc , " B21 " , " " ) ; /* szUserName */
PACKI ( desc , " W " , 0 ) ; /* uJobId */
PACKI ( desc , " W " , 0 ) ; /* fsStatus */
PACKS ( desc , " z " , " " ) ; /* pszStatus */
PACKI ( desc , " W " , 0 ) ; /* time */
}
}
if ( uLevel = = 2 | | uLevel = = 3 ) {
PACKS ( desc , " z " , buf ) ; /* pszPrinterName */
if ( uLevel = = 3 ) {
PACKS ( desc , " z " , " " ) ; /* pszUserName */
PACKS ( desc , " z " , " " ) ; /* pszLogAddr */
PACKI ( desc , " W " , 0 ) ; /* uJobId */
PACKI ( desc , " W " , 0 ) ; /* fsStatus */
PACKS ( desc , " z " , " " ) ; /* pszStatus */
PACKS ( desc , " z " , " " ) ; /* pszComment */
PACKS ( desc , " z " , " NULL " ) ; /* pszDrivers */
PACKI ( desc , " W " , 0 ) ; /* time */
PACKI ( desc , " W " , 0 ) ; /* pad1 */
}
}
}
1996-10-26 00:10:53 +04:00
static BOOL api_WPrintDestGetInfo ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 ) ;
char * PrinterName = p ;
int uLevel , cbBuf ;
struct pack_desc desc ;
int snum ;
bzero ( & desc , 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 ) ) ;
/* check it's a supported varient */
if ( strcmp ( str1 , " zWrLh " ) ! = 0 ) return False ;
if ( ! check_printdest_info ( & desc , uLevel , str2 ) ) return False ;
snum = lp_servicenumber ( PrinterName ) ;
if ( snum < 0 & & pcap_printername_ok ( PrinterName , NULL ) ) {
int pnum = lp_servicenumber ( PRINTERS_NAME ) ;
if ( pnum > = 0 ) {
lp_add_printer ( PrinterName , pnum ) ;
snum = lp_servicenumber ( PrinterName ) ;
}
}
if ( snum < 0 ) {
* rdata_len = 0 ;
desc . errcode = NERR_DestNotFound ;
desc . neededlen = 0 ;
}
else {
if ( mdrcnt > 0 ) * rdata = REALLOC ( * rdata , mdrcnt ) ;
desc . base = * rdata ;
desc . buflen = mdrcnt ;
if ( init_package ( & desc , 1 , 0 ) ) {
fill_printdest_info ( cnum , snum , uLevel , & desc ) ;
}
* rdata_len = desc . usedlen ;
}
* rparam_len = 6 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVALS ( * rparam , 0 , desc . errcode ) ;
SSVAL ( * rparam , 2 , 0 ) ;
SSVAL ( * rparam , 4 , desc . neededlen ) ;
DEBUG ( 4 , ( " WPrintDestGetInfo: errorcode %d \n " , desc . errcode ) ) ;
return ( True ) ;
}
1996-10-26 00:10:53 +04:00
static BOOL api_WPrintDestEnum ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 queuecnt ;
int i , n , succnt = 0 ;
struct pack_desc desc ;
int services = lp_numservices ( ) ;
bzero ( & desc , sizeof ( desc ) ) ;
uLevel = SVAL ( p , 0 ) ;
cbBuf = SVAL ( p , 2 ) ;
DEBUG ( 3 , ( " WPrintDestEnum uLevel=%d \n " , uLevel ) ) ;
/* check it's a supported varient */
if ( strcmp ( str1 , " WrLeh " ) ! = 0 ) return False ;
if ( ! check_printdest_info ( & desc , uLevel , str2 ) ) return False ;
queuecnt = 0 ;
for ( i = 0 ; i < services ; i + + )
if ( lp_snum_ok ( i ) & & lp_print_ok ( i ) & & lp_browseable ( i ) )
queuecnt + + ;
if ( mdrcnt > 0 ) * rdata = REALLOC ( * rdata , mdrcnt ) ;
desc . base = * rdata ;
desc . buflen = mdrcnt ;
if ( init_package ( & desc , queuecnt , 0 ) ) {
succnt = 0 ;
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 ) ;
n + + ;
if ( desc . errcode = = NERR_Success ) succnt = n ;
}
}
}
* rdata_len = desc . usedlen ;
* rparam_len = 8 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVALS ( * rparam , 0 , desc . errcode ) ;
SSVAL ( * rparam , 2 , 0 ) ;
SSVAL ( * rparam , 4 , succnt ) ;
SSVAL ( * rparam , 6 , queuecnt ) ;
DEBUG ( 4 , ( " WPrintDestEnumerate: errorcode %d \n " , desc . errcode ) ) ;
return ( True ) ;
}
1996-10-26 00:10:53 +04:00
static BOOL api_WPrintDriverEnum ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 succnt ;
struct pack_desc desc ;
bzero ( & desc , sizeof ( desc ) ) ;
uLevel = SVAL ( p , 0 ) ;
cbBuf = SVAL ( p , 2 ) ;
DEBUG ( 3 , ( " WPrintDriverEnum uLevel=%d \n " , uLevel ) ) ;
/* check it's a supported varient */
if ( strcmp ( str1 , " WrLeh " ) ! = 0 ) return False ;
if ( uLevel ! = 0 | | strcmp ( str2 , " B41 " ) ! = 0 ) return False ;
if ( mdrcnt > 0 ) * rdata = REALLOC ( * rdata , mdrcnt ) ;
desc . base = * rdata ;
desc . buflen = mdrcnt ;
if ( init_package ( & desc , 1 , 0 ) ) {
PACKS ( & desc , " B41 " , " NULL " ) ;
}
succnt = ( desc . errcode = = NERR_Success ? 1 : 0 ) ;
* rdata_len = desc . usedlen ;
* rparam_len = 8 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVALS ( * rparam , 0 , desc . errcode ) ;
SSVAL ( * rparam , 2 , 0 ) ;
SSVAL ( * rparam , 4 , succnt ) ;
SSVAL ( * rparam , 6 , 1 ) ;
DEBUG ( 4 , ( " WPrintDriverEnum: errorcode %d \n " , desc . errcode ) ) ;
return ( True ) ;
}
1996-10-26 00:10:53 +04:00
static BOOL api_WPrintQProcEnum ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 succnt ;
struct pack_desc desc ;
bzero ( & desc , sizeof ( desc ) ) ;
uLevel = SVAL ( p , 0 ) ;
cbBuf = SVAL ( p , 2 ) ;
DEBUG ( 3 , ( " WPrintQProcEnum uLevel=%d \n " , uLevel ) ) ;
/* check it's a supported varient */
if ( strcmp ( str1 , " WrLeh " ) ! = 0 ) return False ;
if ( uLevel ! = 0 | | strcmp ( str2 , " B13 " ) ! = 0 ) return False ;
if ( mdrcnt > 0 ) * rdata = REALLOC ( * rdata , mdrcnt ) ;
desc . base = * rdata ;
desc . buflen = mdrcnt ;
desc . format = str2 ;
if ( init_package ( & desc , 1 , 0 ) ) {
PACKS ( & desc , " B13 " , " lpd " ) ;
}
succnt = ( desc . errcode = = NERR_Success ? 1 : 0 ) ;
* rdata_len = desc . usedlen ;
* rparam_len = 8 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVALS ( * rparam , 0 , desc . errcode ) ;
SSVAL ( * rparam , 2 , 0 ) ;
SSVAL ( * rparam , 4 , succnt ) ;
SSVAL ( * rparam , 6 , 1 ) ;
DEBUG ( 4 , ( " WPrintQProcEnum: errorcode %d \n " , desc . errcode ) ) ;
return ( True ) ;
}
1996-10-26 00:10:53 +04:00
static BOOL api_WPrintPortEnum ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
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 succnt ;
struct pack_desc desc ;
bzero ( & desc , sizeof ( desc ) ) ;
uLevel = SVAL ( p , 0 ) ;
cbBuf = SVAL ( p , 2 ) ;
DEBUG ( 3 , ( " WPrintPortEnum uLevel=%d \n " , uLevel ) ) ;
/* check it's a supported varient */
if ( strcmp ( str1 , " WrLeh " ) ! = 0 ) return False ;
if ( uLevel ! = 0 | | strcmp ( str2 , " B9 " ) ! = 0 ) return False ;
if ( mdrcnt > 0 ) * rdata = REALLOC ( * rdata , mdrcnt ) ;
bzero ( & desc , sizeof ( desc ) ) ;
desc . base = * rdata ;
desc . buflen = mdrcnt ;
desc . format = str2 ;
if ( init_package ( & desc , 1 , 0 ) ) {
PACKS ( & desc , " B13 " , " lp0 " ) ;
}
succnt = ( desc . errcode = = NERR_Success ? 1 : 0 ) ;
* rdata_len = desc . usedlen ;
* rparam_len = 8 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
SSVALS ( * rparam , 0 , desc . errcode ) ;
SSVAL ( * rparam , 2 , 0 ) ;
SSVAL ( * rparam , 4 , succnt ) ;
SSVAL ( * rparam , 6 , 1 ) ;
DEBUG ( 4 , ( " WPrintPortEnum: errorcode %d \n " , desc . errcode ) ) ;
return ( True ) ;
}
1996-08-15 19:11:34 +04:00
struct
{
char * name ;
char * pipename ;
int subcommand ;
BOOL ( * fn ) ( ) ;
} api_fd_commands [ ] =
{
{ " SetNmdPpHndState " , " lsarpc " , 1 , api_LsarpcSNPHS } ,
{ " TransactNmPipe " , " lsarpc " , 0x26 , api_LsarpcTNP } ,
1996-10-26 00:10:53 +04:00
{ NULL , NULL , - 1 , ( BOOL ( * ) ( ) ) api_Unsupported }
1996-08-15 19:11:34 +04:00
} ;
/****************************************************************************
handle remote api calls delivered to a named pipe already opened .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static int api_fd_reply ( int cnum , uint16 vuid , char * outbuf ,
1996-08-15 19:11:34 +04:00
uint16 * setup , char * data , char * params ,
int suwcnt , int tdscnt , int tpscnt , int mdrcnt , int mprcnt )
{
char * rdata = NULL ;
char * rparam = NULL ;
int rdata_len = 0 ;
int rparam_len = 0 ;
BOOL reply = False ;
int i ;
int fd ;
int subcommand ;
/* First find out the name of this file. */
if ( suwcnt ! = 2 )
{
DEBUG ( 0 , ( " Unexpected named pipe transaction. \n " ) ) ;
return ( - 1 ) ;
}
/* Get the file handle and hence the file name. */
fd = setup [ 1 ] ;
subcommand = setup [ 0 ] ;
DEBUG ( 3 , ( " Got API command %d on pipe %s " , subcommand , Files [ fd ] . name ) ) ;
DEBUG ( 3 , ( " (tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d) \n " ,
tdscnt , tpscnt , mdrcnt , mprcnt ) ) ;
for ( i = 0 ; api_fd_commands [ i ] . name ; i + + )
if ( strequal ( api_fd_commands [ i ] . pipename , Files [ fd ] . name ) & &
api_fd_commands [ i ] . subcommand = = subcommand & &
api_fd_commands [ i ] . fn )
{
DEBUG ( 3 , ( " Doing %s \n " , api_fd_commands [ i ] . name ) ) ;
break ;
}
rdata = ( char * ) malloc ( 1024 ) ; if ( rdata ) bzero ( rdata , 1024 ) ;
rparam = ( char * ) malloc ( 1024 ) ; if ( rparam ) bzero ( rparam , 1024 ) ;
1996-10-26 00:10:53 +04:00
reply = api_fd_commands [ i ] . fn ( cnum , vuid , params , data , mdrcnt , mprcnt ,
1996-08-15 19:11:34 +04:00
& rdata , & rparam , & rdata_len , & rparam_len ) ;
if ( rdata_len > mdrcnt | |
rparam_len > mprcnt )
{
1996-10-26 00:10:53 +04:00
reply = api_TooSmall ( cnum , vuid , params , data , mdrcnt , mprcnt ,
1996-08-15 19:11:34 +04:00
& rdata , & rparam , & rdata_len , & rparam_len ) ;
}
/* if we get False back then it's actually unsupported */
if ( ! reply )
1996-10-26 00:10:53 +04:00
api_Unsupported ( cnum , vuid , params , data , mdrcnt , mprcnt ,
1996-08-15 19:11:34 +04:00
& rdata , & rparam , & rdata_len , & rparam_len ) ;
/* now send the reply */
send_trans_reply ( outbuf , rdata , rparam , NULL , rdata_len , rparam_len , 0 ) ;
if ( rdata )
free ( rdata ) ;
if ( rparam )
free ( rparam ) ;
return ( - 1 ) ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
the buffer was too small
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_TooSmall ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
int mdrcnt , int mprcnt ,
char * * rdata , char * * rparam ,
int * rdata_len , int * rparam_len )
{
* rparam_len = MIN ( * rparam_len , mprcnt ) ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
* rdata_len = 0 ;
SSVAL ( * rparam , 0 , NERR_BufTooSmall ) ;
DEBUG ( 3 , ( " Supplied buffer too small in API command \n " ) ) ;
return ( True ) ;
}
/****************************************************************************
the request is not supported
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static BOOL api_Unsupported ( int cnum , uint16 vuid , char * param , char * data ,
1996-05-04 11:50:46 +04:00
int mdrcnt , int mprcnt ,
char * * rdata , char * * rparam ,
int * rdata_len , int * rparam_len )
{
* rparam_len = 4 ;
* rparam = REALLOC ( * rparam , * rparam_len ) ;
* rdata_len = 0 ;
SSVAL ( * rparam , 0 , NERR_notsupported ) ;
SSVAL ( * rparam , 2 , 0 ) ; /* converter word */
DEBUG ( 3 , ( " Unsupported API command \n " ) ) ;
return ( True ) ;
}
struct
{
char * name ;
int id ;
BOOL ( * fn ) ( ) ;
int flags ;
} api_commands [ ] = {
1996-10-26 00:10:53 +04:00
{ " RNetShareEnum " , 0 , ( BOOL ( * ) ( ) ) api_RNetShareEnum , 0 } ,
{ " RNetShareGetInfo " , 1 , ( BOOL ( * ) ( ) ) api_RNetShareGetInfo , 0 } ,
{ " RNetServerGetInfo " , 13 , ( BOOL ( * ) ( ) ) api_RNetServerGetInfo , 0 } ,
{ " RNetUserGetInfo " , 56 , ( BOOL ( * ) ( ) ) api_RNetUserGetInfo , 0 } ,
{ " NetUserGetGroups " , 59 , ( BOOL ( * ) ( ) ) api_NetUserGetGroups , 0 } ,
{ " NetWkstaGetInfo " , 63 , ( BOOL ( * ) ( ) ) api_NetWkstaGetInfo , 0 } ,
{ " DosPrintQEnum " , 69 , ( BOOL ( * ) ( ) ) api_DosPrintQEnum , 0 } ,
{ " DosPrintQGetInfo " , 70 , ( BOOL ( * ) ( ) ) api_DosPrintQGetInfo , 0 } ,
{ " WPrintJobEnumerate " , 76 , ( BOOL ( * ) ( ) ) api_WPrintJobEnumerate , 0 } ,
{ " WPrintJobGetInfo " , 77 , ( BOOL ( * ) ( ) ) api_WPrintJobGetInfo , 0 } ,
{ " RDosPrintJobDel " , 81 , ( BOOL ( * ) ( ) ) api_RDosPrintJobDel , 0 } ,
{ " RDosPrintJobPause " , 82 , ( BOOL ( * ) ( ) ) api_RDosPrintJobDel , 0 } ,
{ " RDosPrintJobResume " , 83 , ( BOOL ( * ) ( ) ) api_RDosPrintJobDel , 0 } ,
{ " WPrintDestEnum " , 84 , ( BOOL ( * ) ( ) ) api_WPrintDestEnum , 0 } ,
{ " WPrintDestGetInfo " , 85 , ( BOOL ( * ) ( ) ) api_WPrintDestGetInfo , 0 } ,
{ " NetRemoteTOD " , 91 , ( BOOL ( * ) ( ) ) api_NetRemoteTOD , 0 } ,
{ " WPrintQueuePurge " , 103 , ( BOOL ( * ) ( ) ) api_WPrintQueuePurge , 0 } ,
{ " NetServerEnum " , 104 , ( BOOL ( * ) ( ) ) api_RNetServerEnum , 0 } ,
{ " WAccessGetUserPerms " , 105 , ( BOOL ( * ) ( ) ) api_WAccessGetUserPerms , 0 } ,
{ " SetUserPassword " , 115 , ( BOOL ( * ) ( ) ) api_SetUserPassword , 0 } ,
{ " WWkstaUserLogon " , 132 , ( BOOL ( * ) ( ) ) api_WWkstaUserLogon , 0 } ,
{ " PrintJobInfo " , 147 , ( BOOL ( * ) ( ) ) api_PrintJobInfo , 0 } ,
{ " WPrintDriverEnum " , 205 , ( BOOL ( * ) ( ) ) api_WPrintDriverEnum , 0 } ,
{ " WPrintQProcEnum " , 206 , ( BOOL ( * ) ( ) ) api_WPrintQProcEnum , 0 } ,
{ " WPrintPortEnum " , 207 , ( BOOL ( * ) ( ) ) api_WPrintPortEnum , 0 } ,
{ NULL , - 1 , ( BOOL ( * ) ( ) ) api_Unsupported , 0 } } ;
1996-05-04 11:50:46 +04:00
/****************************************************************************
handle remote api calls
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static int api_reply ( int cnum , uint16 vuid , char * outbuf , char * data , char * params ,
1996-05-04 11:50:46 +04:00
int tdscnt , int tpscnt , int mdrcnt , int mprcnt )
{
int api_command = SVAL ( params , 0 ) ;
char * rdata = NULL ;
char * rparam = NULL ;
int rdata_len = 0 ;
int rparam_len = 0 ;
BOOL reply = False ;
int i ;
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 ) ,
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 ;
}
rdata = ( char * ) malloc ( 1024 ) ; if ( rdata ) bzero ( rdata , 1024 ) ;
rparam = ( char * ) malloc ( 1024 ) ; if ( rparam ) bzero ( rparam , 1024 ) ;
1996-10-26 00:10:53 +04:00
reply = api_commands [ i ] . fn ( cnum , vuid , params , data , mdrcnt , mprcnt ,
1996-05-04 11:50:46 +04:00
& rdata , & rparam , & rdata_len , & rparam_len ) ;
if ( rdata_len > mdrcnt | |
rparam_len > mprcnt )
{
1996-10-26 00:10:53 +04:00
reply = api_TooSmall ( cnum , vuid , params , data , mdrcnt , mprcnt ,
1996-05-04 11:50:46 +04:00
& rdata , & rparam , & rdata_len , & rparam_len ) ;
}
/* if we get False back then it's actually unsupported */
if ( ! reply )
1996-10-26 00:10:53 +04:00
api_Unsupported ( cnum , vuid , params , data , mdrcnt , mprcnt ,
1996-05-04 11:50:46 +04:00
& rdata , & rparam , & rdata_len , & rparam_len ) ;
/* now send the reply */
send_trans_reply ( outbuf , rdata , rparam , NULL , rdata_len , rparam_len , 0 ) ;
if ( rdata )
free ( rdata ) ;
if ( rparam )
free ( rparam ) ;
return ( - 1 ) ;
}
/****************************************************************************
handle named pipe commands
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-10-26 00:10:53 +04:00
static int named_pipe ( int cnum , uint16 vuid , char * outbuf , char * name ,
1996-05-04 11:50:46 +04:00
uint16 * setup , char * data , char * params ,
int suwcnt , int tdscnt , int tpscnt ,
int msrcnt , int mdrcnt , int mprcnt )
{
if ( strequal ( name , " LANMAN " ) )
1996-10-26 00:10:53 +04:00
return ( api_reply ( cnum , vuid , outbuf , data , params , tdscnt , tpscnt , mdrcnt , mprcnt ) ) ;
1996-05-04 11:50:46 +04:00
1996-08-15 19:11:34 +04:00
if ( strlen ( name ) < 1 )
1996-10-26 00:10:53 +04:00
return ( api_fd_reply ( cnum , vuid , outbuf , setup , data , params , suwcnt , tdscnt , tpscnt , mdrcnt , mprcnt ) ) ;
1996-08-15 19:11:34 +04:00
1996-05-04 11:50:46 +04:00
DEBUG ( 3 , ( " named pipe command on <%s> 0x%X setup1=%d \n " ,
name , ( int ) setup [ 0 ] , ( int ) setup [ 1 ] ) ) ;
return ( 0 ) ;
}
/****************************************************************************
reply to a SMBtrans
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int reply_trans ( char * inbuf , char * outbuf )
{
fstring name ;
char * data = NULL , * params = NULL ;
uint16 * setup = NULL ;
int outsize = 0 ;
int cnum = SVAL ( inbuf , smb_tid ) ;
1996-10-26 00:10:53 +04:00
uint16 vuid = SVAL ( inbuf , smb_uid ) ;
1996-05-04 11:50:46 +04:00
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 ) ;
StrnCpy ( name , smb_buf ( inbuf ) , sizeof ( name ) - 1 ) ;
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 ( 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 ) ;
}
/* receive the rest of the trans packet */
while ( pscnt < tpscnt | | dscnt < tdscnt )
{
int pcnt , poff , dcnt , doff , pdisp , ddisp ;
1996-06-10 09:16:19 +04:00
1996-08-21 18:15:09 +04:00
if ( ! receive_smb ( Client , inbuf , SMB_SECONDARY_WAIT ) | |
1996-06-10 09:16:19 +04:00
CVAL ( inbuf , smb_com ) ! = SMBtrans )
1996-05-04 11:50:46 +04:00
{
DEBUG ( 2 , ( " Invalid secondary trans2 packet \n " ) ) ;
if ( params ) free ( params ) ;
if ( data ) free ( data ) ;
if ( setup ) free ( setup ) ;
return ( ERROR ( ERRSRV , ERRerror ) ) ;
}
1996-06-10 09:16:19 +04:00
show_msg ( inbuf ) ;
1996-05-04 11:50:46 +04:00
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 ( 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 )
1996-10-26 00:10:53 +04:00
outsize = named_pipe ( cnum , vuid , outbuf , name + strlen ( " \\ PIPE \\ " ) , setup , data , params ,
1996-05-04 11:50:46 +04:00
suwcnt , tdscnt , tpscnt , msrcnt , mdrcnt , mprcnt ) ;
if ( data ) free ( data ) ;
if ( params ) free ( params ) ;
if ( setup ) free ( setup ) ;
if ( close_on_completion )
1996-10-26 00:10:53 +04:00
close_cnum ( cnum , vuid ) ;
1996-05-04 11:50:46 +04:00
if ( one_way )
return ( - 1 ) ;
if ( outsize = = 0 )
return ( ERROR ( ERRSRV , ERRnosupport ) ) ;
return ( outsize ) ;
}