mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
a huge pile of changes :-)
The biggest thing is the integration of Lukes new nmbd. Its still largely untested, so we will really need some feedback I've also added auto prototype generation and cleaned up a lot of minor things as a result (This used to be commit 0d8dcfa13c527ec2c8aca39ba49c09e4e694b26c)
This commit is contained in:
parent
81e398963d
commit
a2c1623827
@ -24,7 +24,6 @@
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
#include "nameserv.h"
|
||||
|
||||
#ifndef REGISTER
|
||||
#define REGISTER 0
|
||||
@ -44,6 +43,7 @@ BOOL connect_as_printer = False;
|
||||
BOOL connect_as_ipc = False;
|
||||
extern struct in_addr bcast_ip;
|
||||
static BOOL got_bcast=False;
|
||||
struct in_addr ipzero;
|
||||
|
||||
char cryptkey[8];
|
||||
BOOL doencrypt=False;
|
||||
@ -72,16 +72,29 @@ extern int DEBUGLEVEL;
|
||||
|
||||
BOOL translation = False;
|
||||
|
||||
|
||||
static BOOL send_trans_request(char *outbuf,int trans,
|
||||
char *name,int fid,int flags,
|
||||
char *data,char *param,uint16 *setup,
|
||||
int ldata,int lparam,int lsetup,
|
||||
int mdata,int mparam,int msetup);
|
||||
static BOOL receive_trans_response(char *inbuf,int trans,
|
||||
int *data_len,int *param_len,
|
||||
char **data,char **param);
|
||||
static int interpret_long_filename(int level,char *p,file_info *finfo);
|
||||
static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir);
|
||||
static int interpret_short_filename(char *p,file_info *finfo);
|
||||
static BOOL call_api(int prcnt,int drcnt,
|
||||
int mprcnt,int mdrcnt,
|
||||
int *rprcnt,int *rdrcnt,
|
||||
char *param,char *data,
|
||||
char **rparam,char **rdata);
|
||||
|
||||
|
||||
/* clitar bits insert */
|
||||
extern void cmd_tar();
|
||||
extern void cmd_block();
|
||||
extern void cmd_tarmode();
|
||||
extern void cmd_setmode();
|
||||
extern int blocksize;
|
||||
extern BOOL tar_inc;
|
||||
extern BOOL tar_reset;
|
||||
extern int process_tar();
|
||||
extern int tar_parseargs();
|
||||
/* clitar bits end */
|
||||
|
||||
|
||||
@ -151,20 +164,6 @@ setup_term_code (char *code)
|
||||
#define CNV_INPUT(s) unix2dos_format(s,True)
|
||||
#endif
|
||||
|
||||
static void send_logout(void );
|
||||
BOOL reopen_connection(char *inbuf,char *outbuf);
|
||||
static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
|
||||
static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
|
||||
static BOOL call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,
|
||||
int *rprcnt,int *rdrcnt,char *param,char *data,
|
||||
char **rparam,char **rdata);
|
||||
static BOOL send_trans_request(char *outbuf,int trans,
|
||||
char *name,int fid,int flags,
|
||||
char *data,char *param,uint16 *setup,
|
||||
int ldata,int lparam,int lsetup,
|
||||
int mdata,int mparam,int msetup);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
setup basics in a outgoing packet
|
||||
****************************************************************************/
|
||||
@ -486,6 +485,319 @@ static void display_finfo(file_info *finfo)
|
||||
asctime(LocalTime(&t))));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
do a directory listing, calling fn on each file found. Use the TRANSACT2
|
||||
call for long filenames
|
||||
****************************************************************************/
|
||||
static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
|
||||
{
|
||||
int max_matches = 512;
|
||||
int info_level = Protocol<PROTOCOL_NT1?1:260; /* NT uses 260, OS/2 uses 2. Both accept 1. */
|
||||
char *p;
|
||||
pstring mask;
|
||||
file_info finfo;
|
||||
int i;
|
||||
char *dirlist = NULL;
|
||||
int dirlist_len = 0;
|
||||
int total_received = 0;
|
||||
BOOL First = True;
|
||||
char *resp_data=NULL;
|
||||
char *resp_param=NULL;
|
||||
int resp_data_len = 0;
|
||||
int resp_param_len=0;
|
||||
|
||||
int ff_resume_key = 0;
|
||||
int ff_searchcount=0;
|
||||
int ff_eos=0;
|
||||
int ff_lastname=0;
|
||||
int ff_dir_handle=0;
|
||||
int loop_count = 0;
|
||||
|
||||
uint16 setup;
|
||||
pstring param;
|
||||
|
||||
strcpy(mask,Mask);
|
||||
|
||||
while (ff_eos == 0)
|
||||
{
|
||||
loop_count++;
|
||||
if (loop_count > 200)
|
||||
{
|
||||
DEBUG(0,("ERROR: Looping in FIND_NEXT??\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (First)
|
||||
{
|
||||
setup = TRANSACT2_FINDFIRST;
|
||||
SSVAL(param,0,attribute); /* attribute */
|
||||
SSVAL(param,2,max_matches); /* max count */
|
||||
SSVAL(param,4,8+4+2); /* resume required + close on end + continue */
|
||||
SSVAL(param,6,info_level);
|
||||
SIVAL(param,8,0);
|
||||
strcpy(param+12,mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
setup = TRANSACT2_FINDNEXT;
|
||||
SSVAL(param,0,ff_dir_handle);
|
||||
SSVAL(param,2,max_matches); /* max count */
|
||||
SSVAL(param,4,info_level);
|
||||
SIVAL(param,6,ff_resume_key); /* ff_resume_key */
|
||||
SSVAL(param,10,8+4+2); /* resume required + close on end + continue */
|
||||
strcpy(param+12,mask);
|
||||
|
||||
DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
|
||||
ff_dir_handle,ff_resume_key,ff_lastname,mask));
|
||||
}
|
||||
/* ??? original code added 1 pad byte after param */
|
||||
|
||||
send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0,
|
||||
NULL,param,&setup,
|
||||
0,12+strlen(mask)+1,1,
|
||||
BUFFER_SIZE,10,0);
|
||||
|
||||
if (!receive_trans_response(inbuf,SMBtrans2,
|
||||
&resp_data_len,&resp_param_len,
|
||||
&resp_data,&resp_param))
|
||||
{
|
||||
DEBUG(3,("FIND%s gave %s\n",First?"FIRST":"NEXT",smb_errstr(inbuf)));
|
||||
break;
|
||||
}
|
||||
|
||||
/* parse out some important return info */
|
||||
p = resp_param;
|
||||
if (First)
|
||||
{
|
||||
ff_dir_handle = SVAL(p,0);
|
||||
ff_searchcount = SVAL(p,2);
|
||||
ff_eos = SVAL(p,4);
|
||||
ff_lastname = SVAL(p,8);
|
||||
}
|
||||
else
|
||||
{
|
||||
ff_searchcount = SVAL(p,0);
|
||||
ff_eos = SVAL(p,2);
|
||||
ff_lastname = SVAL(p,6);
|
||||
}
|
||||
|
||||
if (ff_searchcount == 0)
|
||||
break;
|
||||
|
||||
/* point to the data bytes */
|
||||
p = resp_data;
|
||||
|
||||
/* we might need the lastname for continuations */
|
||||
if (ff_lastname > 0)
|
||||
{
|
||||
switch(info_level)
|
||||
{
|
||||
case 260:
|
||||
ff_resume_key =0;
|
||||
StrnCpy(mask,p+ff_lastname,resp_data_len-ff_lastname);
|
||||
/* strcpy(mask,p+ff_lastname+94); */
|
||||
break;
|
||||
case 1:
|
||||
strcpy(mask,p + ff_lastname + 1);
|
||||
ff_resume_key = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
strcpy(mask,"");
|
||||
|
||||
/* and add them to the dirlist pool */
|
||||
dirlist = Realloc(dirlist,dirlist_len + resp_data_len);
|
||||
|
||||
if (!dirlist)
|
||||
{
|
||||
DEBUG(0,("Failed to expand dirlist\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
/* put in a length for the last entry, to ensure we can chain entries
|
||||
into the next packet */
|
||||
{
|
||||
char *p2;
|
||||
for (p2=p,i=0;i<(ff_searchcount-1);i++)
|
||||
p2 += interpret_long_filename(info_level,p2,NULL);
|
||||
SSVAL(p2,0,resp_data_len - PTR_DIFF(p2,p));
|
||||
}
|
||||
|
||||
/* grab the data for later use */
|
||||
memcpy(dirlist+dirlist_len,p,resp_data_len);
|
||||
dirlist_len += resp_data_len;
|
||||
|
||||
total_received += ff_searchcount;
|
||||
|
||||
if (resp_data) free(resp_data); resp_data = NULL;
|
||||
if (resp_param) free(resp_param); resp_param = NULL;
|
||||
|
||||
DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
|
||||
ff_searchcount,ff_eos,ff_resume_key));
|
||||
|
||||
First = False;
|
||||
}
|
||||
|
||||
if (!fn)
|
||||
for (p=dirlist,i=0;i<total_received;i++)
|
||||
{
|
||||
p += interpret_long_filename(info_level,p,&finfo);
|
||||
display_finfo(&finfo);
|
||||
}
|
||||
|
||||
for (p=dirlist,i=0;i<total_received;i++)
|
||||
{
|
||||
p += interpret_long_filename(info_level,p,&finfo);
|
||||
dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,True);
|
||||
}
|
||||
|
||||
/* free up the dirlist buffer */
|
||||
if (dirlist) free(dirlist);
|
||||
return(total_received);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
do a directory listing, calling fn on each file found
|
||||
****************************************************************************/
|
||||
static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
|
||||
{
|
||||
char *p;
|
||||
int received = 0;
|
||||
BOOL first = True;
|
||||
char status[21];
|
||||
int num_asked = (max_xmit - 100)/DIR_STRUCT_SIZE;
|
||||
int num_received = 0;
|
||||
int i;
|
||||
char *dirlist = NULL;
|
||||
pstring mask;
|
||||
file_info finfo;
|
||||
|
||||
finfo = def_finfo;
|
||||
|
||||
bzero(status,21);
|
||||
|
||||
strcpy(mask,Mask);
|
||||
|
||||
while (1)
|
||||
{
|
||||
bzero(outbuf,smb_size);
|
||||
if (first)
|
||||
set_message(outbuf,2,5 + strlen(mask),True);
|
||||
else
|
||||
set_message(outbuf,2,5 + 21,True);
|
||||
|
||||
#if FFIRST
|
||||
if (Protocol >= PROTOCOL_LANMAN1)
|
||||
CVAL(outbuf,smb_com) = SMBffirst;
|
||||
else
|
||||
#endif
|
||||
CVAL(outbuf,smb_com) = SMBsearch;
|
||||
|
||||
SSVAL(outbuf,smb_tid,cnum);
|
||||
setup_pkt(outbuf);
|
||||
|
||||
SSVAL(outbuf,smb_vwv0,num_asked);
|
||||
SSVAL(outbuf,smb_vwv1,attribute);
|
||||
|
||||
p = smb_buf(outbuf);
|
||||
*p++ = 4;
|
||||
|
||||
if (first)
|
||||
strcpy(p,mask);
|
||||
else
|
||||
strcpy(p,"");
|
||||
p += strlen(p) + 1;
|
||||
|
||||
*p++ = 5;
|
||||
if (first)
|
||||
SSVAL(p,0,0);
|
||||
else
|
||||
{
|
||||
SSVAL(p,0,21);
|
||||
p += 2;
|
||||
memcpy(p,status,21);
|
||||
}
|
||||
|
||||
send_smb(Client,outbuf);
|
||||
receive_smb(Client,inbuf,CLIENT_TIMEOUT);
|
||||
|
||||
received = SVAL(inbuf,smb_vwv0);
|
||||
|
||||
DEBUG(5,("dir received %d\n",received));
|
||||
|
||||
DEBUG(6,("errstr=%s\n",smb_errstr(inbuf)));
|
||||
|
||||
if (received <= 0) break;
|
||||
|
||||
first = False;
|
||||
|
||||
dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE);
|
||||
|
||||
if (!dirlist)
|
||||
return 0;
|
||||
|
||||
p = smb_buf(inbuf) + 3;
|
||||
|
||||
memcpy(dirlist+num_received*DIR_STRUCT_SIZE,
|
||||
p,received*DIR_STRUCT_SIZE);
|
||||
|
||||
memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21);
|
||||
|
||||
num_received += received;
|
||||
|
||||
if (CVAL(inbuf,smb_rcls) != 0) break;
|
||||
}
|
||||
|
||||
#if FFIRST
|
||||
if (!first && Protocol >= PROTOCOL_LANMAN1)
|
||||
{
|
||||
bzero(outbuf,smb_size);
|
||||
CVAL(outbuf,smb_com) = SMBfclose;
|
||||
|
||||
SSVAL(outbuf,smb_tid,cnum);
|
||||
setup_pkt(outbuf);
|
||||
|
||||
p = smb_buf(outbuf);
|
||||
*p++ = 4;
|
||||
|
||||
strcpy(p,"");
|
||||
p += strlen(p) + 1;
|
||||
|
||||
*p++ = 5;
|
||||
SSVAL(p,0,21);
|
||||
p += 2;
|
||||
memcpy(p,status,21);
|
||||
|
||||
send_smb(Client,outbuf);
|
||||
receive_smb(Client,inbuf,CLIENT_TIMEOUT,False);
|
||||
|
||||
if (CVAL(inbuf,smb_rcls) != 0)
|
||||
DEBUG(0,("Error closing search: %s\n",smb_errstr(inbuf)));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!fn)
|
||||
for (p=dirlist,i=0;i<num_received;i++)
|
||||
{
|
||||
p += interpret_short_filename(p,&finfo);
|
||||
display_finfo(&finfo);
|
||||
}
|
||||
|
||||
for (p=dirlist,i=0;i<num_received;i++)
|
||||
{
|
||||
p += interpret_short_filename(p,&finfo);
|
||||
dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,False);
|
||||
}
|
||||
|
||||
if (dirlist) free(dirlist);
|
||||
return(num_received);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
do a directory listing, calling fn on each file found
|
||||
****************************************************************************/
|
||||
@ -684,149 +996,12 @@ static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,B
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
do a directory listing, calling fn on each file found
|
||||
****************************************************************************/
|
||||
static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
|
||||
{
|
||||
char *p;
|
||||
int received = 0;
|
||||
BOOL first = True;
|
||||
char status[21];
|
||||
int num_asked = (max_xmit - 100)/DIR_STRUCT_SIZE;
|
||||
int num_received = 0;
|
||||
int i;
|
||||
char *dirlist = NULL;
|
||||
pstring mask;
|
||||
file_info finfo;
|
||||
|
||||
finfo = def_finfo;
|
||||
|
||||
bzero(status,21);
|
||||
|
||||
strcpy(mask,Mask);
|
||||
|
||||
while (1)
|
||||
{
|
||||
bzero(outbuf,smb_size);
|
||||
if (first)
|
||||
set_message(outbuf,2,5 + strlen(mask),True);
|
||||
else
|
||||
set_message(outbuf,2,5 + 21,True);
|
||||
|
||||
#if FFIRST
|
||||
if (Protocol >= PROTOCOL_LANMAN1)
|
||||
CVAL(outbuf,smb_com) = SMBffirst;
|
||||
else
|
||||
#endif
|
||||
CVAL(outbuf,smb_com) = SMBsearch;
|
||||
|
||||
SSVAL(outbuf,smb_tid,cnum);
|
||||
setup_pkt(outbuf);
|
||||
|
||||
SSVAL(outbuf,smb_vwv0,num_asked);
|
||||
SSVAL(outbuf,smb_vwv1,attribute);
|
||||
|
||||
p = smb_buf(outbuf);
|
||||
*p++ = 4;
|
||||
|
||||
if (first)
|
||||
strcpy(p,mask);
|
||||
else
|
||||
strcpy(p,"");
|
||||
p += strlen(p) + 1;
|
||||
|
||||
*p++ = 5;
|
||||
if (first)
|
||||
SSVAL(p,0,0);
|
||||
else
|
||||
{
|
||||
SSVAL(p,0,21);
|
||||
p += 2;
|
||||
memcpy(p,status,21);
|
||||
}
|
||||
|
||||
send_smb(Client,outbuf);
|
||||
receive_smb(Client,inbuf,CLIENT_TIMEOUT);
|
||||
|
||||
received = SVAL(inbuf,smb_vwv0);
|
||||
|
||||
DEBUG(5,("dir received %d\n",received));
|
||||
|
||||
DEBUG(6,("errstr=%s\n",smb_errstr(inbuf)));
|
||||
|
||||
if (received <= 0) break;
|
||||
|
||||
first = False;
|
||||
|
||||
dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE);
|
||||
|
||||
if (!dirlist)
|
||||
return 0;
|
||||
|
||||
p = smb_buf(inbuf) + 3;
|
||||
|
||||
memcpy(dirlist+num_received*DIR_STRUCT_SIZE,
|
||||
p,received*DIR_STRUCT_SIZE);
|
||||
|
||||
memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21);
|
||||
|
||||
num_received += received;
|
||||
|
||||
if (CVAL(inbuf,smb_rcls) != 0) break;
|
||||
}
|
||||
|
||||
#if FFIRST
|
||||
if (!first && Protocol >= PROTOCOL_LANMAN1)
|
||||
{
|
||||
bzero(outbuf,smb_size);
|
||||
CVAL(outbuf,smb_com) = SMBfclose;
|
||||
|
||||
SSVAL(outbuf,smb_tid,cnum);
|
||||
setup_pkt(outbuf);
|
||||
|
||||
p = smb_buf(outbuf);
|
||||
*p++ = 4;
|
||||
|
||||
strcpy(p,"");
|
||||
p += strlen(p) + 1;
|
||||
|
||||
*p++ = 5;
|
||||
SSVAL(p,0,21);
|
||||
p += 2;
|
||||
memcpy(p,status,21);
|
||||
|
||||
send_smb(Client,outbuf);
|
||||
receive_smb(Client,inbuf,CLIENT_TIMEOUT,False);
|
||||
|
||||
if (CVAL(inbuf,smb_rcls) != 0)
|
||||
DEBUG(0,("Error closing search: %s\n",smb_errstr(inbuf)));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!fn)
|
||||
for (p=dirlist,i=0;i<num_received;i++)
|
||||
{
|
||||
p += interpret_short_filename(p,&finfo);
|
||||
display_finfo(&finfo);
|
||||
}
|
||||
|
||||
for (p=dirlist,i=0;i<num_received;i++)
|
||||
{
|
||||
p += interpret_short_filename(p,&finfo);
|
||||
dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,False);
|
||||
}
|
||||
|
||||
if (dirlist) free(dirlist);
|
||||
return(num_received);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
receive a SMB trans or trans2 response allocating the necessary memory
|
||||
****************************************************************************/
|
||||
static BOOL receive_trans_response(char *inbuf,int trans,
|
||||
int *data_len,int *param_len,
|
||||
char **data,char **param)
|
||||
char **data,char **param)
|
||||
{
|
||||
int total_data=0;
|
||||
int total_param=0;
|
||||
@ -894,178 +1069,6 @@ static BOOL receive_trans_response(char *inbuf,int trans,
|
||||
return(True);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
do a directory listing, calling fn on each file found. Use the TRANSACT2
|
||||
call for long filenames
|
||||
****************************************************************************/
|
||||
static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
|
||||
{
|
||||
int max_matches = 512;
|
||||
int info_level = Protocol<PROTOCOL_NT1?1:260; /* NT uses 260, OS/2 uses 2. Both accept 1. */
|
||||
char *p;
|
||||
pstring mask;
|
||||
file_info finfo;
|
||||
int i;
|
||||
char *dirlist = NULL;
|
||||
int dirlist_len = 0;
|
||||
int total_received = 0;
|
||||
BOOL First = True;
|
||||
char *resp_data=NULL;
|
||||
char *resp_param=NULL;
|
||||
int resp_data_len = 0;
|
||||
int resp_param_len=0;
|
||||
|
||||
int ff_resume_key = 0;
|
||||
int ff_searchcount=0;
|
||||
int ff_eos=0;
|
||||
int ff_lastname=0;
|
||||
int ff_dir_handle=0;
|
||||
int loop_count = 0;
|
||||
|
||||
uint16 setup;
|
||||
pstring param;
|
||||
|
||||
strcpy(mask,Mask);
|
||||
|
||||
while (ff_eos == 0)
|
||||
{
|
||||
loop_count++;
|
||||
if (loop_count > 200)
|
||||
{
|
||||
DEBUG(0,("ERROR: Looping in FIND_NEXT??\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (First)
|
||||
{
|
||||
setup = TRANSACT2_FINDFIRST;
|
||||
SSVAL(param,0,attribute); /* attribute */
|
||||
SSVAL(param,2,max_matches); /* max count */
|
||||
SSVAL(param,4,8+4+2); /* resume required + close on end + continue */
|
||||
SSVAL(param,6,info_level);
|
||||
SIVAL(param,8,0);
|
||||
strcpy(param+12,mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
setup = TRANSACT2_FINDNEXT;
|
||||
SSVAL(param,0,ff_dir_handle);
|
||||
SSVAL(param,2,max_matches); /* max count */
|
||||
SSVAL(param,4,info_level);
|
||||
SIVAL(param,6,ff_resume_key); /* ff_resume_key */
|
||||
SSVAL(param,10,8+4+2); /* resume required + close on end + continue */
|
||||
strcpy(param+12,mask);
|
||||
|
||||
DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
|
||||
ff_dir_handle,ff_resume_key,ff_lastname,mask));
|
||||
}
|
||||
/* ??? original code added 1 pad byte after param */
|
||||
|
||||
send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0,
|
||||
NULL,param,&setup,
|
||||
0,12+strlen(mask)+1,1,
|
||||
BUFFER_SIZE,10,0);
|
||||
|
||||
if (!receive_trans_response(inbuf,SMBtrans2,
|
||||
&resp_data_len,&resp_param_len,
|
||||
&resp_data,&resp_param))
|
||||
{
|
||||
DEBUG(3,("FIND%s gave %s\n",First?"FIRST":"NEXT",smb_errstr(inbuf)));
|
||||
break;
|
||||
}
|
||||
|
||||
/* parse out some important return info */
|
||||
p = resp_param;
|
||||
if (First)
|
||||
{
|
||||
ff_dir_handle = SVAL(p,0);
|
||||
ff_searchcount = SVAL(p,2);
|
||||
ff_eos = SVAL(p,4);
|
||||
ff_lastname = SVAL(p,8);
|
||||
}
|
||||
else
|
||||
{
|
||||
ff_searchcount = SVAL(p,0);
|
||||
ff_eos = SVAL(p,2);
|
||||
ff_lastname = SVAL(p,6);
|
||||
}
|
||||
|
||||
if (ff_searchcount == 0)
|
||||
break;
|
||||
|
||||
/* point to the data bytes */
|
||||
p = resp_data;
|
||||
|
||||
/* we might need the lastname for continuations */
|
||||
if (ff_lastname > 0)
|
||||
{
|
||||
switch(info_level)
|
||||
{
|
||||
case 260:
|
||||
ff_resume_key =0;
|
||||
StrnCpy(mask,p+ff_lastname,resp_data_len-ff_lastname);
|
||||
/* strcpy(mask,p+ff_lastname+94); */
|
||||
break;
|
||||
case 1:
|
||||
strcpy(mask,p + ff_lastname + 1);
|
||||
ff_resume_key = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
strcpy(mask,"");
|
||||
|
||||
/* and add them to the dirlist pool */
|
||||
dirlist = Realloc(dirlist,dirlist_len + resp_data_len);
|
||||
|
||||
if (!dirlist)
|
||||
{
|
||||
DEBUG(0,("Failed to expand dirlist\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
/* put in a length for the last entry, to ensure we can chain entries
|
||||
into the next packet */
|
||||
{
|
||||
char *p2;
|
||||
for (p2=p,i=0;i<(ff_searchcount-1);i++)
|
||||
p2 += interpret_long_filename(info_level,p2,NULL);
|
||||
SSVAL(p2,0,resp_data_len - PTR_DIFF(p2,p));
|
||||
}
|
||||
|
||||
/* grab the data for later use */
|
||||
memcpy(dirlist+dirlist_len,p,resp_data_len);
|
||||
dirlist_len += resp_data_len;
|
||||
|
||||
total_received += ff_searchcount;
|
||||
|
||||
if (resp_data) free(resp_data); resp_data = NULL;
|
||||
if (resp_param) free(resp_param); resp_param = NULL;
|
||||
|
||||
DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
|
||||
ff_searchcount,ff_eos,ff_resume_key));
|
||||
|
||||
First = False;
|
||||
}
|
||||
|
||||
if (!fn)
|
||||
for (p=dirlist,i=0;i<total_received;i++)
|
||||
{
|
||||
p += interpret_long_filename(info_level,p,&finfo);
|
||||
display_finfo(&finfo);
|
||||
}
|
||||
|
||||
for (p=dirlist,i=0;i<total_received;i++)
|
||||
{
|
||||
p += interpret_long_filename(info_level,p,&finfo);
|
||||
dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,True);
|
||||
}
|
||||
|
||||
/* free up the dirlist buffer */
|
||||
if (dirlist) free(dirlist);
|
||||
return(total_received);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
get a directory listing
|
||||
@ -3999,7 +4002,7 @@ BOOL reopen_connection(char *inbuf,char *outbuf)
|
||||
/****************************************************************************
|
||||
process commands from the client
|
||||
****************************************************************************/
|
||||
BOOL process(char *base_directory)
|
||||
static BOOL process(char *base_directory)
|
||||
{
|
||||
extern FILE *dbf;
|
||||
pstring line;
|
||||
@ -4115,7 +4118,7 @@ BOOL process(char *base_directory)
|
||||
/****************************************************************************
|
||||
usage on the program
|
||||
****************************************************************************/
|
||||
void usage(char *pname)
|
||||
static void usage(char *pname)
|
||||
{
|
||||
DEBUG(0,("Usage: %s service <password> [-p port] [-d debuglevel] [-l log] ",
|
||||
pname));
|
||||
@ -4152,11 +4155,11 @@ void usage(char *pname)
|
||||
/****************************************************************************
|
||||
main program
|
||||
****************************************************************************/
|
||||
int main(int argc,char *argv[])
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
fstring base_directory;
|
||||
char *pname = argv[0];
|
||||
int port = 139;
|
||||
int port = SMB_PORT;
|
||||
int opt;
|
||||
extern FILE *dbf;
|
||||
extern char *optarg;
|
||||
@ -4175,6 +4178,8 @@ int main(int argc,char *argv[])
|
||||
TimeInit();
|
||||
charset_initialise();
|
||||
|
||||
ipzero = *interpret_addr2("0.0.0.0");
|
||||
|
||||
pid = getpid();
|
||||
uid = getuid();
|
||||
gid = getgid();
|
||||
|
1029
source3/client/clientutil.c
Normal file
1029
source3/client/clientutil.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,12 +23,6 @@
|
||||
#include "includes.h"
|
||||
#include "clitar.h"
|
||||
|
||||
extern void setup_pkt(char *outbuf);
|
||||
extern BOOL reopen_connection(char *inbuf,char *outbuf);
|
||||
extern void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
|
||||
|
||||
int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
|
||||
|
||||
extern BOOL recurse;
|
||||
|
||||
#define SEPARATORS " \t\n\r"
|
||||
|
@ -983,6 +983,8 @@ extern char *sys_errlist[];
|
||||
|
||||
#include "version.h"
|
||||
#include "smb.h"
|
||||
#include "nameserv.h"
|
||||
#include "proto.h"
|
||||
#include "byteorder.h"
|
||||
#ifdef SMB_PASSWD
|
||||
#include "smbpass.h"
|
||||
|
@ -130,7 +130,7 @@
|
||||
#define IDLE_CLOSED_TIMEOUT (60)
|
||||
#define DPTR_IDLE_TIMEOUT (120)
|
||||
#define SMBD_SELECT_LOOP (10)
|
||||
#define NMBD_SELECT_LOOP (10)
|
||||
#define NMBD_SELECT_LOOP (2)
|
||||
#define BROWSE_INTERVAL (60)
|
||||
#define REGISTRATION_INTERVAL (10*60)
|
||||
#define NMBD_INETD_TIMEOUT (120)
|
||||
|
@ -20,16 +20,51 @@
|
||||
|
||||
*/
|
||||
|
||||
#define MAX_DGRAM_SIZE 576
|
||||
#define MAX_DGRAM_SIZE (80*18+64)
|
||||
#define MIN_DGRAM_SIZE 12
|
||||
|
||||
#define NMB_PORT 137
|
||||
#define DGRAM_PORT 138
|
||||
#define SMB_PORT 139
|
||||
#define NMB_QUERY 0x20
|
||||
#define NMB_STATUS 0x21
|
||||
#define NMB_REG 0x05
|
||||
#define NMB_REL 0x06
|
||||
|
||||
enum name_source {LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
|
||||
#define NB_GROUP 0x80
|
||||
#define NB_PERM 0x02
|
||||
#define NB_ACTIVE 0x04
|
||||
#define NB_CONFL 0x08
|
||||
#define NB_DEREG 0x10
|
||||
#define NB_BFLAG 0x00
|
||||
#define NB_PFLAG 0x20
|
||||
#define NB_MFLAG 0x40
|
||||
#define NB__FLAG 0x60
|
||||
#define NB_FLGMSK 0x60
|
||||
|
||||
#define NAME_PERMANENT(p) ((p) & NB_PERM)
|
||||
#define NAME_ACTIVE(p) ((p) & NB_ACTIVE)
|
||||
#define NAME_CONFLICT(p) ((p) & NB_CONFL)
|
||||
#define NAME_DEREG(p) ((p) & NB_DEREG)
|
||||
#define NAME_GROUP(p) ((p) & NB_GROUP)
|
||||
|
||||
#define NAME_BFLAG(p) (((p) & NB_FLGMSK) == NB_BFLAG)
|
||||
#define NAME_PFLAG(p) (((p) & NB_FLGMSK) == NB_PFLAG)
|
||||
#define NAME_MFLAG(p) (((p) & NB_FLGMSK) == NB_MFLAG)
|
||||
#define NAME__FLAG(p) (((p) & NB_FLGMSK) == NB__FLAG)
|
||||
|
||||
enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
|
||||
enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
|
||||
enum packet_type {NMB_PACKET, DGRAM_PACKET};
|
||||
enum cmd_type
|
||||
{
|
||||
NAME_STATUS_MASTER_CHECK,
|
||||
NAME_STATUS_CHECK,
|
||||
MASTER_SERVER_CHECK,
|
||||
SERVER_CHECK,
|
||||
FIND_MASTER,
|
||||
CHECK_MASTER,
|
||||
NAME_REGISTER,
|
||||
NAME_RELEASE,
|
||||
NAME_CONFIRM_QUERY
|
||||
};
|
||||
|
||||
/* a netbios name structure */
|
||||
struct nmb_name {
|
||||
@ -46,32 +81,73 @@ struct name_record
|
||||
struct nmb_name name;
|
||||
time_t death_time;
|
||||
struct in_addr ip;
|
||||
BOOL unique;
|
||||
int nb_flags;
|
||||
enum name_source source;
|
||||
};
|
||||
|
||||
/* this is used by the list of domains */
|
||||
struct domain_record
|
||||
/* browse and backup server cache for synchronising browse list */
|
||||
struct browse_cache_record
|
||||
{
|
||||
struct domain_record *next;
|
||||
struct domain_record *prev;
|
||||
fstring name;
|
||||
time_t lastannounce_time;
|
||||
int announce_interval;
|
||||
struct in_addr bcast_ip;
|
||||
struct browse_cache_record *next;
|
||||
struct browse_cache_record *prev;
|
||||
|
||||
pstring name;
|
||||
int type;
|
||||
pstring group;
|
||||
struct in_addr ip;
|
||||
time_t sync_time;
|
||||
BOOL synced;
|
||||
};
|
||||
|
||||
/* this is used to hold the list of servers in my domain */
|
||||
/* this is used to hold the list of servers in my domain, and is */
|
||||
/* contained within lists of domains */
|
||||
struct server_record
|
||||
{
|
||||
struct server_record *next;
|
||||
struct server_record *prev;
|
||||
fstring name;
|
||||
fstring comment;
|
||||
uint32 servertype;
|
||||
|
||||
struct server_info_struct serv;
|
||||
time_t death_time;
|
||||
};
|
||||
|
||||
/* a workgroup structure. it contains a list of servers */
|
||||
struct work_record
|
||||
{
|
||||
struct work_record *next;
|
||||
struct work_record *prev;
|
||||
|
||||
struct server_record *serverlist;
|
||||
|
||||
/* work group info */
|
||||
fstring work_group;
|
||||
int token; /* used when communicating with backup browsers */
|
||||
int ServerType;
|
||||
|
||||
/* announce info */
|
||||
time_t lastannounce_time;
|
||||
int announce_interval;
|
||||
BOOL needannounce;
|
||||
|
||||
/* election info */
|
||||
BOOL RunningElection;
|
||||
BOOL needelection;
|
||||
int ElectionCount;
|
||||
uint32 ElectionCriterion;
|
||||
};
|
||||
|
||||
/* a domain structure. it contains a list of workgroups */
|
||||
struct domain_record
|
||||
{
|
||||
struct domain_record *next;
|
||||
struct domain_record *prev;
|
||||
|
||||
struct work_record *workgrouplist;
|
||||
|
||||
struct in_addr bcast_ip;
|
||||
struct in_addr mask_ip;
|
||||
struct in_addr myip;
|
||||
};
|
||||
|
||||
/* a resource record */
|
||||
struct res_rec {
|
||||
struct nmb_name rr_name;
|
||||
@ -115,6 +191,25 @@ struct nmb_packet
|
||||
};
|
||||
|
||||
|
||||
/* initiated name queries recorded in this list to track any responses... */
|
||||
struct name_response_record
|
||||
{
|
||||
struct name_response_record *next;
|
||||
struct name_response_record *prev;
|
||||
|
||||
uint16 response_id;
|
||||
enum cmd_type cmd_type;
|
||||
|
||||
int fd;
|
||||
struct nmb_name name;
|
||||
BOOL bcast;
|
||||
BOOL recurse;
|
||||
struct in_addr to_ip;
|
||||
|
||||
time_t start_time;
|
||||
int num_msgs;
|
||||
};
|
||||
|
||||
/* a datagram - this normally contains SMB data in the data[] array */
|
||||
struct dgram_packet {
|
||||
struct {
|
||||
@ -154,31 +249,3 @@ struct packet_struct
|
||||
};
|
||||
|
||||
|
||||
/* this defines a list of network interfaces */
|
||||
struct net_interface {
|
||||
struct net_interface *next;
|
||||
struct in_addr ip;
|
||||
struct in_addr bcast;
|
||||
struct in_addr netmask;
|
||||
};
|
||||
|
||||
|
||||
/* prototypes */
|
||||
void free_nmb_packet(struct nmb_packet *nmb);
|
||||
void free_packet(struct packet_struct *packet);
|
||||
struct packet_struct *read_packet(int fd,enum packet_type packet_type);
|
||||
BOOL send_packet(struct packet_struct *p);
|
||||
struct packet_struct *receive_packet(int fd,enum packet_type type,int timeout);
|
||||
void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
|
||||
BOOL name_query(int fd,char *name,int name_type,
|
||||
BOOL bcast,BOOL recurse,
|
||||
struct in_addr to_ip, struct in_addr *ip,void (*fn)());
|
||||
BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
struct in_addr to_ip,char *master,char *rname,
|
||||
void (*fn)());
|
||||
BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,
|
||||
char *srcname,char *dstname,
|
||||
int src_type,int dest_type,
|
||||
struct in_addr dest_ip,
|
||||
struct in_addr src_ip);
|
||||
char *namestr(struct nmb_name *n);
|
||||
|
506
source3/include/proto.h
Normal file
506
source3/include/proto.h
Normal file
@ -0,0 +1,506 @@
|
||||
BOOL check_access(int snum);
|
||||
BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client);
|
||||
BOOL fromhost(int sock,struct from_host *f);
|
||||
char *unix2dos_format(char *str,BOOL overwrite);
|
||||
char *dos2unix_format(char *str, BOOL overwrite);
|
||||
int interpret_character_set(char *str, int def);
|
||||
void charset_initialise(void);
|
||||
void add_char_string(char *s);
|
||||
BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence);
|
||||
BOOL chgpasswd(char *name,char *oldpass,char *newpass);
|
||||
BOOL chgpasswd(char *name,char *oldpass,char *newpass);
|
||||
void setup_pkt(char *outbuf);
|
||||
void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
|
||||
void cmd_help(void);
|
||||
BOOL reopen_connection(char *inbuf,char *outbuf);
|
||||
char *smb_errstr(char *inbuf);
|
||||
void cli_setup_pkt(char *outbuf);
|
||||
BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len,
|
||||
int *param_len, char **data,char **param);
|
||||
BOOL cli_send_session_request(char *inbuf, char *outbuf);
|
||||
BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setup);
|
||||
void cli_send_logout(void);
|
||||
BOOL cli_call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt,
|
||||
int *rdrcnt, char *param,char *data, char **rparam,char **rdata);
|
||||
BOOL cli_send_trans_request(char *outbuf, int trans, char *name, int fid, int flags,
|
||||
char *data,char *param,uint16 *setup, int ldata,int lparam,
|
||||
int lsetup,int mdata,int mparam,int msetup);
|
||||
BOOL cli_open_sockets(int port);
|
||||
BOOL cli_reopen_connection(char *inbuf,char *outbuf);
|
||||
char *smb_errstr(char *inbuf);
|
||||
int strslashcmp(const char *s1, const char *s2);
|
||||
void cmd_block(void);
|
||||
void cmd_tarmode(void);
|
||||
void cmd_setmode(void);
|
||||
void cmd_tar(char *inbuf, char *outbuf);
|
||||
int process_tar(char *inbuf, char *outbuf);
|
||||
int clipfind(char **aret, int ret, char *tok);
|
||||
int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
|
||||
void init_dptrs(void);
|
||||
char *dptr_path(int key);
|
||||
char *dptr_wcard(int key);
|
||||
BOOL dptr_set_wcard(int key, char *wcard);
|
||||
BOOL dptr_set_attr(int key, uint16 attr);
|
||||
uint16 dptr_attr(int key);
|
||||
void dptr_close(int key);
|
||||
void dptr_closecnum(int cnum);
|
||||
void dptr_idlecnum(int cnum);
|
||||
void dptr_closepath(char *path,int pid);
|
||||
int dptr_create(int cnum,char *path, BOOL expect_close,int pid);
|
||||
BOOL dptr_fill(char *buf1,unsigned int key);
|
||||
BOOL dptr_zero(char *buf);
|
||||
void *dptr_fetch(char *buf,int *num);
|
||||
void *dptr_fetch_lanman2(char *params,int dptr_num);
|
||||
BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend);
|
||||
void *OpenDir(char *name);
|
||||
void CloseDir(void *p);
|
||||
char *ReadDirName(void *p);
|
||||
BOOL SeekDir(void *p,int pos);
|
||||
int TellDir(void *p);
|
||||
void DirCacheAdd(char *path,char *name,char *dname,int snum);
|
||||
char *DirCacheCheck(char *path,char *name,int snum);
|
||||
void DirCacheFlush(int snum);
|
||||
void fault_setup(void (*fn)());
|
||||
char *getsmbpass(char *prompt) ;
|
||||
int reply_trans(char *inbuf,char *outbuf);
|
||||
int interpret_coding_system(char *str, int def);
|
||||
char *lp_string(char *s);
|
||||
BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir);
|
||||
int lp_add_service(char *pszService, int iDefaultService);
|
||||
BOOL lp_add_printer(char *pszPrintername, int iDefaultService);
|
||||
BOOL lp_file_list_changed(void);
|
||||
BOOL lp_snum_ok(int iService);
|
||||
BOOL lp_loaded(void);
|
||||
void lp_killunused(BOOL (*snumused)(int ));
|
||||
BOOL lp_load(char *pszFname,BOOL global_only);
|
||||
int lp_numservices(void);
|
||||
void lp_dump(void);
|
||||
int lp_servicenumber(char *pszServiceName);
|
||||
char *my_workgroup(void);
|
||||
char *volume_label(int snum);
|
||||
BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset);
|
||||
BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
|
||||
BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
|
||||
int get_share_mode_by_fnum(int cnum,int fnum,int *pid);
|
||||
int get_share_mode_byname(int cnum,char *fname,int *pid);
|
||||
int get_share_mode(int cnum,struct stat *sbuf,int *pid);
|
||||
void del_share_mode(int fnum);
|
||||
BOOL set_share_mode(int fnum,int mode);
|
||||
void clean_share_files(void);
|
||||
int str_checksum(char *s);
|
||||
BOOL is_8_3(char *fname);
|
||||
void create_mangled_stack(int size);
|
||||
BOOL check_mangled_stack(char *s);
|
||||
BOOL is_mangled(char *s);
|
||||
void mangle_name_83(char *s);
|
||||
BOOL name_map_mangle(char *OutName,BOOL need83,int snum);
|
||||
int reply_sends(char *inbuf,char *outbuf);
|
||||
int reply_sendstrt(char *inbuf,char *outbuf);
|
||||
int reply_sendtxt(char *inbuf,char *outbuf);
|
||||
int reply_sendend(char *inbuf,char *outbuf);
|
||||
void announce_request(struct work_record *work, struct in_addr ip);
|
||||
void do_announce_request(char *info, char *to_name, int announce_type, int from,
|
||||
int to, struct in_addr dest_ip);
|
||||
void announce_backup(void);
|
||||
void announce_host(void);
|
||||
void announce_master(void);
|
||||
struct work_record *remove_workgroup(struct domain_record *d, struct work_record *work);
|
||||
void expire_browse_cache(time_t t);
|
||||
struct work_record *find_workgroupstruct(struct domain_record *d, fstring name, BOOL add);
|
||||
struct domain_record *find_domain(struct in_addr source_ip);
|
||||
struct domain_record *add_domain_entry(struct in_addr source_ip, struct in_addr source_mask,
|
||||
char *name, BOOL add);
|
||||
struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
|
||||
time_t ttl, struct in_addr ip);
|
||||
struct server_record *add_server_entry(struct domain_record *d, struct work_record *work,
|
||||
char *name,int servertype, int ttl,char *comment,
|
||||
BOOL replace);
|
||||
void write_browse_list(void);
|
||||
void expire_servers(time_t t);
|
||||
void check_master_browser(void);
|
||||
void browser_gone(char *work_name, struct in_addr ip);
|
||||
void send_election(struct domain_record *d, char *group,uint32 criterion,
|
||||
int timeup,char *name);
|
||||
void become_nonmaster(struct domain_record *d, struct work_record *work);
|
||||
void run_elections(void);
|
||||
void process_election(struct packet_struct *p,char *buf);
|
||||
BOOL check_elections(void);
|
||||
BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
struct in_addr to_ip,char *master,char *rname,
|
||||
void (*fn)());
|
||||
BOOL name_query(int fd,char *name,int name_type,
|
||||
BOOL bcast,BOOL recurse,
|
||||
struct in_addr to_ip, struct in_addr *ip,void (*fn)());
|
||||
void expire_netbios_response_entries(time_t t);
|
||||
void reply_netbios_packet(struct packet_struct *p1,int trn_id,int rcode,int opcode,
|
||||
struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
|
||||
char *data,int len);
|
||||
uint16 initiate_netbios_packet(int fd,int quest_type,char *name,int name_type,
|
||||
int nb_flags,BOOL bcast,BOOL recurse,struct in_addr to_ip);
|
||||
void send_name_reg(void);
|
||||
void queue_netbios_pkt_wins(int fd,int quest_type,enum cmd_type cmd,
|
||||
char *name,int name_type,int nb_flags,
|
||||
BOOL bcast,BOOL recurse,struct in_addr to_ip);
|
||||
void queue_netbios_packet(int fd,int quest_type,enum cmd_type cmd,char *name,
|
||||
int name_type,int nb_flags,BOOL bcast,BOOL recurse,
|
||||
struct in_addr to_ip);
|
||||
struct name_response_record *find_name_query(uint16 id);
|
||||
void queue_packet(struct packet_struct *packet);
|
||||
void run_packet_queue();
|
||||
void listen_for_packets(BOOL run_election);
|
||||
BOOL interpret_node_status(char *p, struct nmb_name *name,int t,
|
||||
char *serv_name, struct in_addr ip);
|
||||
BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
|
||||
char *dstname,int src_type,int dest_type,
|
||||
struct in_addr dest_ip,struct in_addr src_ip);
|
||||
void remove_name(struct name_record *n);
|
||||
void dump_names(void);
|
||||
void remove_netbios_name(char *name,int type, enum name_source source,
|
||||
struct in_addr ip);
|
||||
struct name_record *add_netbios_entry(char *name, int type, int nb_flags, int ttl,
|
||||
enum name_source source, struct in_addr ip);
|
||||
void remove_name_entry(char *name,int type);
|
||||
void add_name_entry(char *name,int type,int nb_flags);
|
||||
void add_my_names(void);
|
||||
void expire_names(time_t t);
|
||||
void response_name_release(struct packet_struct *p);
|
||||
void reply_name_release(struct packet_struct *p);
|
||||
void response_name_reg(struct packet_struct *p);
|
||||
void reply_name_reg(struct packet_struct *p);
|
||||
void reply_name_status(struct packet_struct *p);
|
||||
struct name_record *search_for_name(struct nmb_name *question,
|
||||
struct in_addr ip, int Time, int search);
|
||||
void process_nmb(struct packet_struct *p);
|
||||
void reset_server(char *name, int state, struct in_addr ip);
|
||||
void tell_become_backup(void);
|
||||
void do_browser_lists(void);
|
||||
void sync_server(enum cmd_type cmd, char *serv_name, char *work_name, int name_type,
|
||||
struct in_addr ip);
|
||||
void update_from_reg(char *name, int type, struct in_addr ip);
|
||||
void add_my_domains(void);
|
||||
BOOL same_context(struct dgram_packet *dgram);
|
||||
BOOL listening_name(struct work_record *work, struct nmb_name *n);
|
||||
void process_logon_packet(struct packet_struct *p,char *buf,int len);
|
||||
BOOL listening_type(struct packet_struct *p, int command);
|
||||
void process_browse_packet(struct packet_struct *p,char *buf,int len);
|
||||
void process_dgram(struct packet_struct *p);
|
||||
BOOL reload_services(BOOL test);
|
||||
void debug_nmb_packet(struct packet_struct *p);
|
||||
char *namestr(struct nmb_name *n);
|
||||
void free_nmb_packet(struct nmb_packet *nmb);
|
||||
void free_packet(struct packet_struct *packet);
|
||||
struct packet_struct *read_packet(int fd,enum packet_type packet_type);
|
||||
void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
|
||||
BOOL send_packet(struct packet_struct *p);
|
||||
struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
|
||||
int main(int argc,char *argv[]);
|
||||
char *getsmbpass(char *pass);
|
||||
void sync_browse_lists(struct work_record *work, char *name, int nm_type,
|
||||
struct in_addr ip);
|
||||
BOOL pm_process(char *pszFileName,BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *));
|
||||
void generate_next_challenge(char *challenge);
|
||||
BOOL set_challenge(char *challenge);
|
||||
BOOL last_challenge(char *challenge);
|
||||
int valid_uid(int uid);
|
||||
user_struct *get_valid_user_struct(int uid);
|
||||
void invalidate_uid(int uid);
|
||||
char *validated_username(int vuid);
|
||||
void register_uid(int uid,int gid, char *name,BOOL guest);
|
||||
void add_session_user(char *user);
|
||||
void dfs_unlogin(void);
|
||||
BOOL password_check(char *password);
|
||||
BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8);
|
||||
BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL is_nt_password);
|
||||
BOOL user_ok(char *user,int snum);
|
||||
BOOL authorise_login(int snum,char *user,char *password, int pwlen,
|
||||
BOOL *guest,BOOL *force,int vuid);
|
||||
BOOL check_hosts_equiv(char *user);
|
||||
BOOL server_cryptkey(char *buf);
|
||||
BOOL server_validate(char *buf);
|
||||
BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname);
|
||||
void pcap_printer_fn(void (*fn)());
|
||||
void lpq_reset(int snum);
|
||||
void print_file(int fnum);
|
||||
int get_printqueue(int snum,int cnum,print_queue_struct **queue,
|
||||
print_status_struct *status);
|
||||
void del_printqueue(int cnum,int snum,int jobid);
|
||||
void status_printjob(int cnum,int snum,int jobid,int status);
|
||||
int reply_special(char *inbuf,char *outbuf);
|
||||
int reply_tcon(char *inbuf,char *outbuf);
|
||||
int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_unknown(char *inbuf,char *outbuf);
|
||||
int reply_ioctl(char *inbuf,char *outbuf);
|
||||
int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_chkpth(char *inbuf,char *outbuf);
|
||||
int reply_getatr(char *inbuf,char *outbuf);
|
||||
int reply_setatr(char *inbuf,char *outbuf);
|
||||
int reply_dskattr(char *inbuf,char *outbuf);
|
||||
int reply_search(char *inbuf,char *outbuf);
|
||||
int reply_fclose(char *inbuf,char *outbuf);
|
||||
int reply_open(char *inbuf,char *outbuf);
|
||||
int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_mknew(char *inbuf,char *outbuf);
|
||||
int reply_ctemp(char *inbuf,char *outbuf);
|
||||
int reply_unlink(char *inbuf,char *outbuf);
|
||||
int reply_readbraw(char *inbuf, char *outbuf);
|
||||
int reply_lockread(char *inbuf,char *outbuf);
|
||||
int reply_read(char *inbuf,char *outbuf);
|
||||
int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_writebraw(char *inbuf,char *outbuf);
|
||||
int reply_writeunlock(char *inbuf,char *outbuf);
|
||||
int reply_write(char *inbuf,char *outbuf,int dum1,int dum2);
|
||||
int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_lseek(char *inbuf,char *outbuf);
|
||||
int reply_flush(char *inbuf,char *outbuf);
|
||||
int reply_exit(char *inbuf,char *outbuf);
|
||||
int reply_close(char *inbuf,char *outbuf);
|
||||
int reply_writeclose(char *inbuf,char *outbuf);
|
||||
int reply_lock(char *inbuf,char *outbuf);
|
||||
int reply_unlock(char *inbuf,char *outbuf);
|
||||
int reply_tdis(char *inbuf,char *outbuf);
|
||||
int reply_echo(char *inbuf,char *outbuf);
|
||||
int reply_printopen(char *inbuf,char *outbuf);
|
||||
int reply_printclose(char *inbuf,char *outbuf);
|
||||
int reply_printqueue(char *inbuf,char *outbuf);
|
||||
int reply_printwrite(char *inbuf,char *outbuf);
|
||||
int reply_mkdir(char *inbuf,char *outbuf);
|
||||
int reply_rmdir(char *inbuf,char *outbuf);
|
||||
int reply_mv(char *inbuf,char *outbuf);
|
||||
int reply_copy(char *inbuf,char *outbuf);
|
||||
int reply_setdir(char *inbuf,char *outbuf);
|
||||
int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_readbmpx(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_writebmpx(char *inbuf,char *outbuf);
|
||||
int reply_writebs(char *inbuf,char *outbuf);
|
||||
int reply_setattrE(char *inbuf,char *outbuf);
|
||||
int reply_getattrE(char *inbuf,char *outbuf);
|
||||
mode_t unix_mode(int cnum,int dosmode);
|
||||
int dos_mode(int cnum,char *path,struct stat *sbuf);
|
||||
int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st);
|
||||
BOOL unix_convert(char *name,int cnum);
|
||||
int disk_free(char *path,int *bsize,int *dfree,int *dsize);
|
||||
int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize);
|
||||
BOOL check_name(char *name,int cnum);
|
||||
void open_file(int fnum,int cnum,char *fname1,int flags,int mode);
|
||||
void sync_file(int fnum);
|
||||
void close_file(int fnum);
|
||||
BOOL check_file_sharing(int cnum,char *fname);
|
||||
void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
|
||||
int mode,int *Access,int *action);
|
||||
int seek_file(int fnum,int pos);
|
||||
int read_file(int fnum,char *data,int pos,int mincnt,int maxcnt,int timeout,BOOL exact);
|
||||
int write_file(int fnum,char *data,int n);
|
||||
BOOL become_service(int cnum,BOOL do_chdir);
|
||||
int find_service(char *service);
|
||||
int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line);
|
||||
int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line);
|
||||
int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line);
|
||||
BOOL snum_used(int snum);
|
||||
BOOL reload_services(BOOL test);
|
||||
int setup_groups(char *user, int uid, int gid, int *p_ngroups,
|
||||
int **p_igroups, gid_t **p_groups);
|
||||
int make_connection(char *service,char *user,char *password, int pwlen, char *dev,int vuid);
|
||||
int find_free_file(void );
|
||||
int reply_corep(char *outbuf);
|
||||
int reply_coreplus(char *outbuf);
|
||||
int reply_lanman1(char *outbuf);
|
||||
int reply_lanman2(char *outbuf);
|
||||
int reply_nt1(char *outbuf);
|
||||
void parse_connect(char *buf,char *service,char *user,char *password,int *pwlen,char *dev);
|
||||
void close_cnum(int cnum, int uid);
|
||||
BOOL yield_connection(int cnum,char *name,int max_connections);
|
||||
BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear);
|
||||
void exit_server(char *reason);
|
||||
void standard_sub(int cnum,char *s);
|
||||
char *smb_fn_name(int type);
|
||||
int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize);
|
||||
int construct_reply(char *inbuf,char *outbuf,int size,int bufsize);
|
||||
void str_to_key(uchar *str,uchar *key);
|
||||
void D1(uchar *k, uchar *d, uchar *out);
|
||||
void E1(uchar *k, uchar *d, uchar *out);
|
||||
void E_P16(uchar *p14,uchar *p16);
|
||||
void E_P24(uchar *p21, uchar *c8, uchar *p24);
|
||||
void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
|
||||
void E_md4hash(uchar *passwd, uchar *p16);
|
||||
void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
|
||||
void Ucrit_addUsername(pstring username);
|
||||
unsigned int Ucrit_checkUsername(pstring username);
|
||||
void Ucrit_addPid(int pid);
|
||||
unsigned int Ucrit_checkPid(int pid);
|
||||
int sys_select(fd_set *fds,struct timeval *tval);
|
||||
int sys_select(fd_set *fds,struct timeval *tval);
|
||||
int sys_unlink(char *fname);
|
||||
int sys_open(char *fname,int flags,int mode);
|
||||
DIR *sys_opendir(char *dname);
|
||||
int sys_stat(char *fname,struct stat *sbuf);
|
||||
int sys_lstat(char *fname,struct stat *sbuf);
|
||||
int sys_mkdir(char *dname,int mode);
|
||||
int sys_rmdir(char *dname);
|
||||
int sys_chdir(char *dname);
|
||||
int sys_utime(char *fname,struct utimbuf *times);
|
||||
int sys_rename(char *from, char *to);
|
||||
int sys_chown(char *fname,int uid,int gid);
|
||||
int sys_chroot(char *dname);
|
||||
int main(int argc, char *argv[]);
|
||||
void GetTimeOfDay(struct timeval *tval);
|
||||
void TimeInit(void);
|
||||
int TimeDiff(time_t t);
|
||||
struct tm *LocalTime(time_t *t);
|
||||
time_t interpret_long_date(char *p);
|
||||
void put_long_date(char *p,time_t t);
|
||||
void put_dos_date(char *buf,int offset,time_t unixdate);
|
||||
void put_dos_date2(char *buf,int offset,time_t unixdate);
|
||||
void put_dos_date3(char *buf,int offset,time_t unixdate);
|
||||
time_t make_unix_date(void *date_ptr);
|
||||
time_t make_unix_date2(void *date_ptr);
|
||||
time_t make_unix_date3(void *date_ptr);
|
||||
BOOL set_filetime(char *fname,time_t mtime);
|
||||
char *timestring(void );
|
||||
int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
char *ufc_crypt(char *key,char *salt);
|
||||
void init_uid(void);
|
||||
BOOL become_guest(void);
|
||||
BOOL become_user(int cnum, int uid);
|
||||
BOOL unbecome_user(void );
|
||||
int smbrun(char *cmd,char *outfile);
|
||||
char *get_home_dir(char *user);
|
||||
void map_username(char *user);
|
||||
struct passwd *Get_Pwnam(char *user,BOOL allow_change);
|
||||
BOOL user_in_list(char *user,char *list);
|
||||
void setup_logging(char *pname,BOOL interactive);
|
||||
void reopen_logs(void);
|
||||
BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type);
|
||||
int file_lock(char *name,int timeout);
|
||||
void file_unlock(int fd);
|
||||
BOOL is_a_socket(int fd);
|
||||
BOOL next_token(char **ptr,char *buff,char *sep);
|
||||
char **toktocliplist(int *ctok, char *sep);
|
||||
void *MemMove(void *dest,void *src,int size);
|
||||
void array_promote(char *array,int elsize,int element);
|
||||
void set_socket_options(int fd, char *options);
|
||||
void close_sockets(void );
|
||||
BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups);
|
||||
char *StrCpy(char *dest,char *src);
|
||||
char *StrnCpy(char *dest,const char *src,int n);
|
||||
void putip(void *dest,void *src);
|
||||
int name_mangle(char *In,char *Out,char name_type);
|
||||
BOOL file_exist(char *fname,struct stat *sbuf);
|
||||
time_t file_modtime(char *fname);
|
||||
BOOL directory_exist(char *dname,struct stat *st);
|
||||
uint32 file_size(char *file_name);
|
||||
char *attrib_string(int mode);
|
||||
int StrCaseCmp(char *s, char *t);
|
||||
int StrnCaseCmp(char *s, char *t, int n);
|
||||
BOOL strequal(char *s1,char *s2);
|
||||
BOOL strnequal(char *s1,char *s2,int n);
|
||||
BOOL strcsequal(char *s1,char *s2);
|
||||
void strlower(char *s);
|
||||
void strupper(char *s);
|
||||
void strnorm(char *s);
|
||||
BOOL strisnormal(char *s);
|
||||
void string_replace(char *s,char oldc,char newc);
|
||||
void unix_format(char *fname);
|
||||
void dos_format(char *fname);
|
||||
void show_msg(char *buf);
|
||||
int smb_len(char *buf);
|
||||
void _smb_setlen(char *buf,int len);
|
||||
void smb_setlen(char *buf,int len);
|
||||
int set_message(char *buf,int num_words,int num_bytes,BOOL zero);
|
||||
int smb_numwords(char *buf);
|
||||
int smb_buflen(char *buf);
|
||||
int smb_buf_ofs(char *buf);
|
||||
char *smb_buf(char *buf);
|
||||
int smb_offset(char *p,char *buf);
|
||||
char *skip_string(char *buf,int n);
|
||||
BOOL trim_string(char *s,char *front,char *back);
|
||||
void dos_clean_name(char *s);
|
||||
void unix_clean_name(char *s);
|
||||
int ChDir(char *path);
|
||||
char *GetWd(char *str);
|
||||
BOOL reduce_name(char *s,char *dir,BOOL widelinks);
|
||||
void expand_mask(char *Mask,BOOL doext);
|
||||
BOOL strhasupper(char *s);
|
||||
BOOL strhaslower(char *s);
|
||||
int count_chars(char *s,char c);
|
||||
void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date);
|
||||
void close_low_fds(void);
|
||||
int write_socket(int fd,char *buf,int len);
|
||||
int read_udp_socket(int fd,char *buf,int len);
|
||||
int set_blocking(int fd, BOOL set);
|
||||
int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL exact);
|
||||
int read_max_udp(int fd,char *buffer,int bufsize,int maxtime);
|
||||
int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew);
|
||||
BOOL send_keepalive(int client);
|
||||
int read_data(int fd,char *buffer,int N);
|
||||
int write_data(int fd,char *buffer,int N);
|
||||
int read_predict(int fd,int offset,char *buf,char **ptr,int num);
|
||||
void do_read_prediction();
|
||||
void invalidate_read_prediction(int fd);
|
||||
int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align);
|
||||
int read_smb_length(int fd,char *inbuf,int timeout);
|
||||
BOOL receive_smb(int fd,char *buffer,int timeout);
|
||||
BOOL send_smb(int fd,char *buffer);
|
||||
char *name_ptr(char *buf,int ofs);
|
||||
int name_extract(char *buf,int ofs,char *name);
|
||||
int name_len(char *s);
|
||||
BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type);
|
||||
void msleep(int t);
|
||||
BOOL in_list(char *s,char *list,BOOL casesensitive);
|
||||
BOOL string_init(char **dest,char *src);
|
||||
void string_free(char **s);
|
||||
BOOL string_set(char **dest,char *src);
|
||||
BOOL string_sub(char *s,char *pattern,char *insert);
|
||||
BOOL do_match(char *str, char *regexp, int case_sig);
|
||||
BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2);
|
||||
void become_daemon(void);
|
||||
void get_broadcast(struct in_addr *if_ipaddr,
|
||||
struct in_addr *if_bcast,
|
||||
struct in_addr *if_nmask);
|
||||
BOOL yesno(char *p);
|
||||
char *fgets_slash(char *s2,int maxlen,FILE *f);
|
||||
int set_filelen(int fd, long len);
|
||||
int byte_checksum(char *buf,int len);
|
||||
void setbuffer(FILE *f,char *buf,int bufsize);
|
||||
char *dirname_dos(char *path,char *buf);
|
||||
void *Realloc(void *p,int size);
|
||||
void Abort(void );
|
||||
BOOL get_myname(char *myname,struct in_addr *ip);
|
||||
BOOL ip_equal(struct in_addr ip1,struct in_addr ip2);
|
||||
int open_socket_in(int type, int port, int dlevel);
|
||||
int open_socket_out(int type, struct in_addr *addr, int port );
|
||||
int interpret_protocol(char *str,int def);
|
||||
int interpret_security(char *str,int def);
|
||||
unsigned long interpret_addr(char *str);
|
||||
struct in_addr *interpret_addr2(char *str);
|
||||
BOOL zero_ip(struct in_addr ip);
|
||||
void standard_sub_basic(char *s);
|
||||
BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
|
||||
int PutUniCode(char *dst,char *src);
|
||||
struct hostent *Get_Hostbyname(char *name);
|
||||
BOOL process_exists(int pid);
|
||||
char *uidtoname(int uid);
|
||||
char *gidtoname(int gid);
|
||||
void BlockSignals(BOOL block);
|
||||
void ajt_panic(void);
|
||||
char *readdirname(void *p);
|
||||
void *malloc_wrapped(int size,char *file,int line);
|
||||
void *realloc_wrapped(void *ptr,int size,char *file,int line);
|
||||
void free_wrapped(void *ptr,char *file,int line);
|
||||
char *Strstr(char *s, char *p);
|
||||
time_t Mktime(struct tm *t);
|
||||
int InNetGr(char *group,char *host,char *user,char *dom);
|
||||
void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line);
|
||||
int VT_Check(char *buffer);
|
||||
int VT_Start_utmp(void);
|
||||
int VT_Stop_utmp(void);
|
||||
void VT_AtExit(void);
|
||||
void VT_SigCLD(int sig);
|
||||
void VT_SigEXIT(int sig);
|
||||
int VT_Start(void);
|
||||
int VT_Output(char *Buffer);
|
||||
int VT_Input(char *Buffer,int Size);
|
||||
void VT_Process(void);
|
@ -40,6 +40,10 @@
|
||||
# define EXTERN extern
|
||||
#endif
|
||||
|
||||
#define NMB_PORT 137
|
||||
#define DGRAM_PORT 138
|
||||
#define SMB_PORT 139
|
||||
|
||||
#define False (0)
|
||||
#define True (1)
|
||||
#define BOOLSTR(b) ((b) ? "Yes" : "No")
|
||||
@ -72,6 +76,19 @@ typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
#endif
|
||||
|
||||
#ifndef uchar
|
||||
#define uchar unsigned char
|
||||
#endif
|
||||
#ifndef int16
|
||||
#define int16 short
|
||||
#endif
|
||||
#ifndef uint16
|
||||
#define uint16 unsigned short
|
||||
#endif
|
||||
#ifndef uint32
|
||||
#define uint32 unsigned int
|
||||
#endif
|
||||
|
||||
#define SIZEOFWORD 2
|
||||
|
||||
#ifndef DEF_CREATE_MASK
|
||||
@ -216,6 +233,15 @@ typedef char pstring[1024];
|
||||
typedef char fstring[128];
|
||||
typedef fstring string;
|
||||
|
||||
|
||||
struct current_user {
|
||||
int cnum, id;
|
||||
int uid, gid;
|
||||
int ngroups;
|
||||
gid_t *groups;
|
||||
int *igroups;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int size;
|
||||
@ -332,6 +358,16 @@ typedef struct
|
||||
int status;
|
||||
} print_status_struct;
|
||||
|
||||
/* used for server information: client, nameserv and ipc */
|
||||
struct server_info_struct
|
||||
{
|
||||
fstring name;
|
||||
uint32 type;
|
||||
fstring comment;
|
||||
fstring domain; /* used ONLY in ipc.c NOT namework.c */
|
||||
BOOL server_added; /* used ONLY in ipc.c NOT namework.c */
|
||||
};
|
||||
|
||||
|
||||
/* this is used for smbstatus */
|
||||
struct connect_record
|
||||
@ -582,281 +618,29 @@ struct from_host {
|
||||
struct sockaddr_in *sin; /* their side of the link */
|
||||
};
|
||||
|
||||
/* and a few prototypes */
|
||||
BOOL become_guest(void);
|
||||
void init_uid(void);
|
||||
BOOL user_ok(char *user,int snum);
|
||||
int sys_rename(char *from, char *to);
|
||||
int sys_select(fd_set *fds,struct timeval *tval);
|
||||
int sys_unlink(char *fname);
|
||||
int sys_open(char *fname,int flags,int mode);
|
||||
DIR *sys_opendir(char *dname);
|
||||
int sys_stat(char *fname,struct stat *sbuf);
|
||||
int sys_lstat(char *fname,struct stat *sbuf);
|
||||
int sys_mkdir(char *dname,int mode);
|
||||
int sys_rmdir(char *dname);
|
||||
int sys_chdir(char *dname);
|
||||
int sys_utime(char *fname,struct utimbuf *times);
|
||||
int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize);
|
||||
void lpq_reset(int);
|
||||
void status_printjob(int cnum,int snum,int jobid,int status);
|
||||
void DirCacheAdd(char *path,char *name,char *dname,int snum);
|
||||
char *DirCacheCheck(char *path,char *name,int snum);
|
||||
void DirCacheFlush(int snum);
|
||||
int interpret_character_set(char *str, int def);
|
||||
char *dos2unix_format(char *, BOOL);
|
||||
char *unix2dos_format(char *, BOOL);
|
||||
BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type);
|
||||
void BlockSignals(BOOL block);
|
||||
void msleep(int t);
|
||||
int file_lock(char *name,int timeout);
|
||||
void file_unlock(int fd);
|
||||
int find_service(char *service);
|
||||
int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew);
|
||||
int smb_offset(char *p,char *buf);
|
||||
void sync_file(int fnum);
|
||||
int PutUniCode(char *dst,char *src);
|
||||
void map_username(char *user);
|
||||
void close_low_fds(void);
|
||||
void clean_share_files(void);
|
||||
int write_socket(int fd,char *buf,int len);
|
||||
char *readdirname(void *p);
|
||||
int dos_chmod(int cnum,char *fname,int mode,struct stat *st);
|
||||
int smb_numwords(char *buf);
|
||||
int get_share_mode(int cnum,struct stat *sbuf,int *pid);
|
||||
void del_share_mode(int fnum);
|
||||
BOOL set_share_mode(int fnum,int mode);
|
||||
void TimeInit(void);
|
||||
void put_long_date(char *p,time_t t);
|
||||
time_t interpret_long_date(char *p);
|
||||
void dptr_idlecnum(int cnum);
|
||||
void dptr_closecnum(int cnum);
|
||||
void init_dptrs(void);
|
||||
void fault_setup();
|
||||
void set_socket_options(int fd, char *options);
|
||||
void putip(void *dest,void *src);
|
||||
void standard_sub_basic(char *s);
|
||||
void *OpenDir(char *name);
|
||||
void CloseDir(void *p);
|
||||
char *ReadDirName(void *p);
|
||||
BOOL SeekDir(void *p,int pos);
|
||||
int TellDir(void *p);
|
||||
int write_data(int fd,char *buffer,int N);
|
||||
BOOL server_cryptkey(char *buf);
|
||||
BOOL server_validate(char *buf);
|
||||
BOOL become_service(int cnum,BOOL do_chdir);
|
||||
BOOL snum_used(int snum);
|
||||
BOOL reload_services(BOOL test);
|
||||
void reopen_logs(void);
|
||||
int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align);
|
||||
int str_checksum(char *s);
|
||||
time_t file_modtime(char *fname);
|
||||
BOOL do_match(char *str, char *regexp, int case_sig);
|
||||
BOOL is_a_socket(int fd);
|
||||
void _smb_setlen(char *buf,int len);
|
||||
void valid_initialise(void);
|
||||
BOOL is_8_3(char *fname);
|
||||
BOOL is_mangled(char *s);
|
||||
void standard_sub(int cnum,char *s);
|
||||
void del_printqueue(int cnum,int snum,int jobid);
|
||||
BOOL strisnormal(char *s);
|
||||
BOOL check_mangled_stack(char *s);
|
||||
int sys_chown(char *fname,int uid,int gid);
|
||||
int sys_chroot(char *dname);
|
||||
BOOL next_token(char **ptr,char *buff,char *sep);
|
||||
void invalidate_uid(int uid);
|
||||
char *fgets_slash(char *s,int maxlen,FILE *f);
|
||||
int read_udp_socket(int fd,char *buf,int len);
|
||||
void exit_server(char *reason);
|
||||
BOOL process_exists(int pid);
|
||||
BOOL chgpasswd(char *name,char *oldpass,char *newpass);
|
||||
void array_promote(char *array,int elsize,int element);
|
||||
void string_replace(char *s,char oldc,char newc);
|
||||
BOOL user_in_list(char *user,char *list);
|
||||
BOOL string_sub(char *s,char *pattern,char *insert);
|
||||
char *StrnCpy(char *dest,const char *src,int n);
|
||||
char *validated_username(int vuid);
|
||||
BOOL set_user_password(char *user,char *oldpass,char *newpass);
|
||||
int smb_buf_ofs(char *buf);
|
||||
char *skip_string(char *buf,int n);
|
||||
BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset);
|
||||
int read_file(int fnum,char *data,int pos,int mincnt,int maxcnt,int timeout,BOOL exact);
|
||||
int write_file(int fnum,char *data,int n);
|
||||
BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
|
||||
int seek_file(int fnum,int pos);
|
||||
BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
|
||||
int get_printqueue(int snum,int cnum,print_queue_struct **queue,print_status_struct *status);
|
||||
void parse_connect(char *buf,char *service,char *user,char *password,int *pwlen,char *dev);
|
||||
int setup_groups(char *user,int uid, int gid, int *p_ngroups,
|
||||
int **p_igroups, gid_t **p_groups);
|
||||
int make_connection(char *service,char *user,char *password, int pwlen, char *dev,int vuid);
|
||||
char *dptr_path(int key);
|
||||
char *dptr_wcard(int key);
|
||||
BOOL dptr_set_wcard(int key, char *wcard);
|
||||
BOOL dptr_set_attr(int key, uint16 attr);
|
||||
uint16 dptr_attr(int key);
|
||||
void dptr_close(int key);
|
||||
void dptr_closepath(char *path,int pid);
|
||||
int dptr_create(int cnum,char *path, BOOL expect_close,int pid);
|
||||
BOOL dptr_fill(char *buf,unsigned int key);
|
||||
BOOL dptr_zero(char *buf);
|
||||
void *dptr_fetch(char *buf,int *num);
|
||||
void *dptr_fetch_lanman2(char *params,int dptr_num);
|
||||
BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend);
|
||||
void open_file(int fnum,int cnum,char *fname,int flags,int mode);
|
||||
void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,int mode,int *Access,int *action);
|
||||
void close_file(int fnum);
|
||||
int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_trans(char *inbuf,char *outbuf);
|
||||
char *ufc_crypt(char *key,char *salt);
|
||||
BOOL authorise_login(int snum,char *user,char *password, int pwlen,
|
||||
BOOL *guest,BOOL *force,int vuid);
|
||||
void add_session_user(char *user);
|
||||
int valid_uid(int uid);
|
||||
user_struct *get_valid_user_struct(int uid);
|
||||
BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL nt_password);
|
||||
void register_uid(int uid,int gid,char *name,BOOL guest);
|
||||
BOOL fromhost(int sock,struct from_host *f);
|
||||
BOOL strhasupper(char *s);
|
||||
BOOL strhaslower(char *s);
|
||||
int disk_free(char *path,int *bsize,int *dfree,int *dsize);
|
||||
char *uidtoname(int uid);
|
||||
char *gidtoname(int gid);
|
||||
int get_share_mode_byname(int cnum,char *fname,int *pid);
|
||||
int get_share_mode_by_fnum(int cnum,int fnum,int *pid);
|
||||
BOOL check_file_sharing(int cnum,char *fname);
|
||||
char *StrCpy(char *dest,char *src);
|
||||
int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line);
|
||||
time_t make_unix_date2(void *date_ptr);
|
||||
int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line);
|
||||
mode_t unix_mode(int cnum,int dosmode);
|
||||
BOOL check_name(char *name,int cnum);
|
||||
int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line);
|
||||
int find_free_file(void );
|
||||
BOOL unix_convert(char *name,int cnum);
|
||||
void unix_convert_lanman2(char *s,char *home,BOOL case_is_sig);
|
||||
void print_file(int fnum);
|
||||
int read_smb_length(int fd,char *inbuf,int timeout);
|
||||
int read_predict(int fd,int offset,char *buf,char **ptr,int num);
|
||||
void invalidate_read_prediction(int fd);
|
||||
void do_read_prediction();
|
||||
BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear);
|
||||
BOOL yield_connection(int cnum,char *name,int max_connections);
|
||||
int count_chars(char *s,char c);
|
||||
int smbrun(char *,char *);
|
||||
BOOL name_map_mangle(char *OutName,BOOL need83,int snum);
|
||||
struct hostent *Get_Hostbyname(char *name);
|
||||
struct passwd *Get_Pwnam(char *user,BOOL allow_change);
|
||||
void Abort(void);
|
||||
void *Realloc(void *p,int size);
|
||||
void smb_setlen(char *buf,int len);
|
||||
int set_message(char *buf,int num_words,int num_bytes,BOOL zero);
|
||||
BOOL check_access(int snum);
|
||||
BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups);
|
||||
BOOL string_set(char **dest,char *src);
|
||||
BOOL string_init(char **dest,char *src);
|
||||
void string_free(char **s);
|
||||
char *attrib_string(int mode);
|
||||
void unix_format(char *fname);
|
||||
BOOL directory_exist(char *dname,struct stat *st);
|
||||
time_t make_unix_date3(void *date_ptr);
|
||||
void put_dos_date3(char *buf,int offset,time_t unixdate);
|
||||
void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date);
|
||||
BOOL in_list(char *s,char *list,BOOL case_sensitive);
|
||||
void strupper(char *s);
|
||||
BOOL file_exist(char *fname,struct stat *sbuf);
|
||||
int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt, long time_out, BOOL exact);
|
||||
void close_sockets(void );
|
||||
BOOL send_smb(int fd,char *buffer);
|
||||
BOOL send_keepalive(int client);
|
||||
int read_data(int fd,char *buffer,int N);
|
||||
int smb_len(char *buf);
|
||||
BOOL receive_smb(int fd,char *buffer,int timeout);
|
||||
void show_msg(char *buf);
|
||||
BOOL big_endian(void );
|
||||
BOOL become_user(int cnum, int uid);
|
||||
BOOL unbecome_user(void);
|
||||
void become_daemon(void);
|
||||
BOOL reduce_name(char *s,char *dir,BOOL widelinks);
|
||||
void strlower(char *s);
|
||||
void strnorm(char *s);
|
||||
char *smb_buf(char *buf);
|
||||
char *smb_trans2_param(char *buf);
|
||||
char *smb_trans2_data(char *buf);
|
||||
BOOL strequal(char *,char *);
|
||||
BOOL strnequal(char *,char *,int n);
|
||||
BOOL strcsequal(char *,char *);
|
||||
BOOL mask_match( char *str, char *regexp, int case_sig, BOOL trans2);
|
||||
int dos_mode(int ,char *,struct stat *);
|
||||
char *timestring();
|
||||
BOOL ip_equal(struct in_addr ip1,struct in_addr ip2);
|
||||
BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type);
|
||||
char *get_home_dir(char *);
|
||||
int set_filelen(int fd, long len);
|
||||
void put_dos_date(char *buf,int offset,time_t unixdate);
|
||||
void put_dos_date2(char *buf,int offset,time_t unixdate);
|
||||
int lp_keepalive(void);
|
||||
int name_len(char *s);
|
||||
void dos_clean_name(char *s);
|
||||
void unix_clean_name(char *s);
|
||||
time_t make_unix_date(void *date_ptr);
|
||||
BOOL lanman2_match( char *str, char *regexp, int case_sig, BOOL autoext);
|
||||
BOOL trim_string(char *s,char *front,char *back);
|
||||
int byte_checksum(char *buf,int len);
|
||||
BOOL yesno(char *p);
|
||||
uint32 file_size(char *file_name);
|
||||
void dos_format(char *fname);
|
||||
char *GetWd(char *s);
|
||||
int name_mangle(char *in,char *out,char name_type);
|
||||
int name_len(char *s);
|
||||
void create_mangled_stack(int size);
|
||||
int name_extract(char *buf,int ofs,char *name);
|
||||
void get_broadcast(struct in_addr *if_ipaddr, struct in_addr *if_bcast, struct in_addr *if_nmask);
|
||||
BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client);
|
||||
#ifdef __STDC__
|
||||
int Debug1(char *, ...);
|
||||
#else
|
||||
int Debug1();
|
||||
#endif
|
||||
BOOL check_hosts_equiv(char *user);
|
||||
int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize);
|
||||
void close_cnum(int cnum,int uid);
|
||||
char *smb_errstr(char *inbuf);
|
||||
void GetTimeOfDay(struct timeval *tval);
|
||||
struct tm *LocalTime(time_t *t);
|
||||
int TimeDiff(time_t t);
|
||||
BOOL set_filetime(char *fname,time_t mtime);
|
||||
char *dirname_dos(char *path,char *buf);
|
||||
BOOL get_myname(char *myname,struct in_addr *ip);
|
||||
void expand_mask(char *Mask, BOOL);
|
||||
char *smb_fn_name(int cnum);
|
||||
void get_machine_info(void);
|
||||
int open_socket_in(int type, int port, int dlevel);
|
||||
int open_socket_out(int type,struct in_addr *addr, int port );
|
||||
struct in_addr *interpret_addr2(char *str);
|
||||
BOOL zero_ip(struct in_addr ip);
|
||||
int read_max_udp(int fd,char *buffer,int bufsize,int maxtime);
|
||||
int interpret_protocol(char *str,int def);
|
||||
int interpret_security(char *str,int def);
|
||||
int ChDir(char *path);
|
||||
int smb_buflen(char *buf);
|
||||
unsigned long interpret_addr(char *str);
|
||||
void mangle_name_83(char *s);
|
||||
BOOL lp_casesignames(void);
|
||||
void setup_logging(char *pname,BOOL interactive);
|
||||
|
||||
#ifdef DFS_AUTH
|
||||
void dfs_unlogin(void);
|
||||
extern int dcelogin_atmost_once;
|
||||
#endif
|
||||
|
||||
#if AJT
|
||||
void ajt_panic(void);
|
||||
#endif
|
||||
|
||||
#ifdef NOSTRDUP
|
||||
char *strdup(char *s);
|
||||
#endif
|
||||
|
||||
#ifdef REPLACE_STRLEN
|
||||
int Strlen(char *);
|
||||
#endif
|
||||
|
||||
#ifdef REPLACE_STRSTR
|
||||
char *Strstr(char *s, char *p);
|
||||
#endif
|
||||
|
@ -71,8 +71,7 @@ static void initiso() {
|
||||
/*
|
||||
* Convert unix to dos
|
||||
*/
|
||||
char *
|
||||
unix2dos_format(char *str,BOOL overwrite)
|
||||
char *unix2dos_format(char *str,BOOL overwrite)
|
||||
{
|
||||
char *p;
|
||||
char *dp;
|
||||
@ -91,8 +90,7 @@ unix2dos_format(char *str,BOOL overwrite)
|
||||
/*
|
||||
* Convert dos to unix
|
||||
*/
|
||||
char *
|
||||
dos2unix_format (char *str, BOOL overwrite)
|
||||
char *dos2unix_format(char *str, BOOL overwrite)
|
||||
{
|
||||
char *p;
|
||||
char *dp;
|
||||
@ -112,8 +110,7 @@ dos2unix_format (char *str, BOOL overwrite)
|
||||
/*
|
||||
* Interpret character set.
|
||||
*/
|
||||
int
|
||||
interpret_character_set (char *str, int def)
|
||||
int interpret_character_set(char *str, int def)
|
||||
{
|
||||
|
||||
if (strequal (str, "iso8859-1")) {
|
||||
|
@ -40,12 +40,12 @@ static struct termio t;
|
||||
#define TCSANOW 0
|
||||
#endif
|
||||
|
||||
int tcgetattr(int fd, struct termio *t)
|
||||
int tcgetattr(int fd, struct termio *t)
|
||||
{
|
||||
return ioctl(fd, TCGETA, t);
|
||||
}
|
||||
|
||||
int tcsetattr(int fd, int flags, const struct termio *t)
|
||||
int tcsetattr(int fd, int flags, const struct termio *t)
|
||||
{
|
||||
if(flags & TCSAFLUSH)
|
||||
ioctl(fd, TCFLSH, TCIOFLUSH);
|
||||
@ -71,12 +71,12 @@ static struct sgttyb t;
|
||||
#define TCSANOW 0
|
||||
#endif
|
||||
|
||||
int tcgetattr(int fd, struct sgttyb *t)
|
||||
int tcgetattr(int fd, struct sgttyb *t)
|
||||
{
|
||||
return ioctl(fd, TIOCGETP, (char *)t);
|
||||
}
|
||||
|
||||
int tcsetattr(int fd, int flags, const struct sgttyb *t)
|
||||
int tcsetattr(int fd, int flags, const struct sgttyb *t)
|
||||
{
|
||||
return ioctl(fd, TIOCSETP, (char *)t);
|
||||
}
|
||||
@ -92,8 +92,7 @@ static struct termios t;
|
||||
#endif /* BSD_TERMIO */
|
||||
#endif /* SYSV_TERMIO */
|
||||
|
||||
char *
|
||||
getsmbpass(char *prompt)
|
||||
char *getsmbpass(char *prompt)
|
||||
{
|
||||
FILE *in, *out;
|
||||
int echo_off;
|
||||
@ -162,5 +161,5 @@ getsmbpass(char *prompt)
|
||||
|
||||
#else
|
||||
|
||||
void getsmbpasswd_dummy() {;}
|
||||
void getsmbpasswd_dummy() {;}
|
||||
#endif
|
||||
|
@ -796,8 +796,7 @@ setup_string_function (int codes)
|
||||
/*
|
||||
* Interpret coding system.
|
||||
*/
|
||||
int
|
||||
interpret_coding_system (char *str, int def)
|
||||
int interpret_coding_system(char *str, int def)
|
||||
{
|
||||
int codes = def;
|
||||
|
||||
@ -890,6 +889,6 @@ interpret_coding_system (char *str, int def)
|
||||
return setup_string_function (codes);
|
||||
}
|
||||
#else
|
||||
int kanji_dummy_procedure(void)
|
||||
int kanji_dummy_procedure(void)
|
||||
{return 0;}
|
||||
#endif /* KANJI */
|
||||
|
@ -295,5 +295,5 @@
|
||||
** End of md4.c
|
||||
*/
|
||||
#else
|
||||
void md4_dummy() {;}
|
||||
void md4_dummy() {;}
|
||||
#endif
|
||||
|
@ -777,6 +777,6 @@ ufc_long *_ufc_doit(l1, l2, r1, r2, itr)
|
||||
|
||||
|
||||
#else
|
||||
int ufc_dummy_procedure(void)
|
||||
int ufc_dummy_procedure(void)
|
||||
{return 0;}
|
||||
#endif
|
||||
|
@ -182,10 +182,10 @@ write an debug message on the debugfile. This is called by the DEBUG
|
||||
macro
|
||||
********************************************************************/
|
||||
#ifdef __STDC__
|
||||
int Debug1(char *format_str, ...)
|
||||
int Debug1(char *format_str, ...)
|
||||
{
|
||||
#else
|
||||
int Debug1(va_alist)
|
||||
int Debug1(va_alist)
|
||||
va_dcl
|
||||
{
|
||||
char *format_str;
|
||||
@ -3234,7 +3234,7 @@ void *Realloc(void *p,int size)
|
||||
/****************************************************************************
|
||||
duplicate a string
|
||||
****************************************************************************/
|
||||
char *strdup(char *s)
|
||||
char *strdup(char *s)
|
||||
{
|
||||
char *ret = NULL;
|
||||
if (!s) return(NULL);
|
||||
@ -3260,7 +3260,7 @@ void Abort(void )
|
||||
/****************************************************************************
|
||||
a replacement strlen() that returns int for solaris
|
||||
****************************************************************************/
|
||||
int Strlen(char *s)
|
||||
int Strlen(char *s)
|
||||
{
|
||||
int ret=0;
|
||||
if (!s) return(0);
|
||||
@ -3274,7 +3274,7 @@ int Strlen(char *s)
|
||||
/*******************************************************************
|
||||
ftruncate for operating systems that don't have it
|
||||
********************************************************************/
|
||||
int ftruncate(int f,long l)
|
||||
int ftruncate(int f,long l)
|
||||
{
|
||||
struct flock fl;
|
||||
|
||||
@ -3382,7 +3382,7 @@ int open_socket_in(int type, int port, int dlevel)
|
||||
if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
|
||||
{
|
||||
if (port) {
|
||||
if (port == 139 || port == 137)
|
||||
if (port == SMB_PORT || port == NMB_PORT)
|
||||
DEBUG(dlevel,("bind failed on port %d (%s)\n",
|
||||
port,strerror(errno)));
|
||||
close(res);
|
||||
@ -3569,6 +3569,21 @@ void standard_sub_basic(char *s)
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
are two IPs on the same subnet?
|
||||
********************************************************************/
|
||||
BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
|
||||
{
|
||||
unsigned long net1,net2,nmask;
|
||||
|
||||
nmask = ntohl(mask.s_addr);
|
||||
net1 = ntohl(ip1.s_addr);
|
||||
net2 = ntohl(ip2.s_addr);
|
||||
|
||||
return((net1 & nmask) == (net2 & nmask));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
write a string in unicoode format
|
||||
********************************************************************/
|
||||
@ -3797,7 +3812,7 @@ long nap(long milliseconds) {
|
||||
/****************************************************************************
|
||||
some systems don't have an initgroups call
|
||||
****************************************************************************/
|
||||
int initgroups(char *name,gid_t id)
|
||||
int initgroups(char *name,gid_t id)
|
||||
{
|
||||
#ifdef NO_SETGROUPS
|
||||
/* yikes! no SETGROUPS or INITGROUPS? how can this work? */
|
||||
@ -3981,8 +3996,7 @@ time_t Mktime(struct tm *t)
|
||||
|
||||
#ifdef REPLACE_RENAME
|
||||
/* Rename a file. (from libiberty in GNU binutils) */
|
||||
int
|
||||
rename (zfrom, zto)
|
||||
int rename (zfrom, zto)
|
||||
const char *zfrom;
|
||||
const char *zto;
|
||||
{
|
||||
@ -4003,8 +4017,7 @@ rename (zfrom, zto)
|
||||
/*
|
||||
* Search for a match in a netgroup. This replaces it on broken systems.
|
||||
*/
|
||||
int InNetGr(group, host, user, dom)
|
||||
char *group, *host, *user, *dom;
|
||||
int InNetGr(char *group,char *host,char *user,char *dom)
|
||||
{
|
||||
char *hst, *usr, *dm;
|
||||
|
||||
|
292
source3/libsmb/namequery.c
Normal file
292
source3/libsmb/namequery.c
Normal file
@ -0,0 +1,292 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
name query routines
|
||||
Copyright (C) Andrew Tridgell 1994-1995
|
||||
|
||||
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 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
extern pstring scope;
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
interpret a node status response
|
||||
****************************************************************************/
|
||||
static void _interpret_node_status(char *p, char *master,char *rname)
|
||||
{
|
||||
int level = (master||rname)?4:0;
|
||||
int numnames = CVAL(p,0);
|
||||
DEBUG(level,("received %d names\n",numnames));
|
||||
|
||||
if (rname) *rname = 0;
|
||||
if (master) *master = 0;
|
||||
|
||||
p += 1;
|
||||
while (numnames--)
|
||||
{
|
||||
char qname[17];
|
||||
int type;
|
||||
fstring flags;
|
||||
int i;
|
||||
*flags = 0;
|
||||
StrnCpy(qname,p,15);
|
||||
type = CVAL(p,15);
|
||||
p += 16;
|
||||
|
||||
strcat(flags, (p[0] & 0x80) ? "<GROUP> " : " ");
|
||||
if ((p[0] & 0x60) == 0x00) strcat(flags,"B ");
|
||||
if ((p[0] & 0x60) == 0x20) strcat(flags,"P ");
|
||||
if ((p[0] & 0x60) == 0x40) strcat(flags,"M ");
|
||||
if ((p[0] & 0x60) == 0x60) strcat(flags,"_ ");
|
||||
if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
|
||||
if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
|
||||
if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
|
||||
if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
|
||||
|
||||
if (master && !*master && type == 0x1d) {
|
||||
StrnCpy(master,qname,15);
|
||||
trim_string(master,NULL," ");
|
||||
}
|
||||
|
||||
if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
|
||||
StrnCpy(rname,qname,15);
|
||||
trim_string(rname,NULL," ");
|
||||
}
|
||||
|
||||
for (i = strlen( qname) ; --i >= 0 ; ) {
|
||||
if (!isprint(qname[i])) qname[i] = '.';
|
||||
}
|
||||
DEBUG(level,("\t%-15s <%02x> - %s\n",qname,type,flags));
|
||||
p+=2;
|
||||
}
|
||||
DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
|
||||
IVAL(p,20),IVAL(p,24)));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
do a netbios name status query on a host
|
||||
|
||||
the "master" parameter is a hack used for finding workgroups.
|
||||
**************************************************************************/
|
||||
BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
struct in_addr to_ip,char *master,char *rname,
|
||||
void (*fn)())
|
||||
{
|
||||
BOOL found=False;
|
||||
int retries = 2;
|
||||
int retry_time = 5000;
|
||||
struct timeval tval;
|
||||
struct packet_struct p;
|
||||
struct packet_struct *p2;
|
||||
struct nmb_packet *nmb = &p.packet.nmb;
|
||||
static int name_trn_id = 0;
|
||||
|
||||
bzero((char *)&p,sizeof(p));
|
||||
|
||||
if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
|
||||
(getpid()%(unsigned)100);
|
||||
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
|
||||
|
||||
nmb->header.name_trn_id = name_trn_id;
|
||||
nmb->header.opcode = 0;
|
||||
nmb->header.response = False;
|
||||
nmb->header.nm_flags.bcast = False;
|
||||
nmb->header.nm_flags.recursion_available = 0;
|
||||
nmb->header.nm_flags.recursion_desired = 1;
|
||||
nmb->header.nm_flags.trunc = False;
|
||||
nmb->header.nm_flags.authoritative = False;
|
||||
nmb->header.rcode = 0;
|
||||
nmb->header.qdcount = 1;
|
||||
nmb->header.ancount = 0;
|
||||
nmb->header.nscount = 0;
|
||||
nmb->header.arcount = 0;
|
||||
|
||||
make_nmb_name(&nmb->question.question_name,name,name_type,scope);
|
||||
|
||||
nmb->question.question_type = 0x21;
|
||||
nmb->question.question_class = 0x1;
|
||||
|
||||
p.ip = to_ip;
|
||||
p.port = NMB_PORT;
|
||||
p.fd = fd;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = NMB_PACKET;
|
||||
|
||||
GetTimeOfDay(&tval);
|
||||
|
||||
if (!send_packet(&p))
|
||||
return(False);
|
||||
|
||||
retries--;
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct timeval tval2;
|
||||
GetTimeOfDay(&tval2);
|
||||
if (TvalDiff(&tval,&tval2) > retry_time) {
|
||||
if (!retries) break;
|
||||
if (!found && !send_packet(&p))
|
||||
return False;
|
||||
GetTimeOfDay(&tval);
|
||||
retries--;
|
||||
}
|
||||
|
||||
if ((p2=receive_packet(fd,NMB_PACKET,90)))
|
||||
{
|
||||
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
||||
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
|
||||
!nmb2->header.response) {
|
||||
/* its not for us - maybe deal with it later */
|
||||
if (fn)
|
||||
fn(p2);
|
||||
else
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nmb2->header.opcode != 0 ||
|
||||
nmb2->header.nm_flags.bcast ||
|
||||
nmb2->header.rcode ||
|
||||
!nmb2->header.ancount ||
|
||||
nmb2->answers->rr_type != 0x21) {
|
||||
/* XXXX what do we do with this? could be a redirect, but
|
||||
we'll discard it for the moment */
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
_interpret_node_status(&nmb2->answers->rdata[0], master,rname);
|
||||
free_packet(p2);
|
||||
return(True);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DEBUG(0,("No status response (this is not unusual)\n"));
|
||||
|
||||
return(False);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
do a netbios name query to find someones IP
|
||||
****************************************************************************/
|
||||
BOOL name_query(int fd,char *name,int name_type,
|
||||
BOOL bcast,BOOL recurse,
|
||||
struct in_addr to_ip, struct in_addr *ip,void (*fn)())
|
||||
{
|
||||
BOOL found=False;
|
||||
int retries = 3;
|
||||
int retry_time = bcast?250:2000;
|
||||
struct timeval tval;
|
||||
struct packet_struct p;
|
||||
struct packet_struct *p2;
|
||||
struct nmb_packet *nmb = &p.packet.nmb;
|
||||
static int name_trn_id = 0;
|
||||
|
||||
bzero((char *)&p,sizeof(p));
|
||||
|
||||
if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
|
||||
(getpid()%(unsigned)100);
|
||||
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
|
||||
|
||||
nmb->header.name_trn_id = name_trn_id;
|
||||
nmb->header.opcode = 0;
|
||||
nmb->header.response = False;
|
||||
nmb->header.nm_flags.bcast = bcast;
|
||||
nmb->header.nm_flags.recursion_available = 0;
|
||||
nmb->header.nm_flags.recursion_desired = 1;
|
||||
nmb->header.nm_flags.trunc = False;
|
||||
nmb->header.nm_flags.authoritative = False;
|
||||
nmb->header.rcode = 0;
|
||||
nmb->header.qdcount = 1;
|
||||
nmb->header.ancount = 0;
|
||||
nmb->header.nscount = 0;
|
||||
nmb->header.arcount = 0;
|
||||
|
||||
make_nmb_name(&nmb->question.question_name,name,name_type,scope);
|
||||
|
||||
nmb->question.question_type = 0x20;
|
||||
nmb->question.question_class = 0x1;
|
||||
|
||||
p.ip = to_ip;
|
||||
p.port = NMB_PORT;
|
||||
p.fd = fd;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = NMB_PACKET;
|
||||
|
||||
GetTimeOfDay(&tval);
|
||||
|
||||
if (!send_packet(&p))
|
||||
return(False);
|
||||
|
||||
retries--;
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct timeval tval2;
|
||||
GetTimeOfDay(&tval2);
|
||||
if (TvalDiff(&tval,&tval2) > retry_time) {
|
||||
if (!retries) break;
|
||||
if (!found && !send_packet(&p))
|
||||
return False;
|
||||
GetTimeOfDay(&tval);
|
||||
retries--;
|
||||
}
|
||||
|
||||
if ((p2=receive_packet(fd,NMB_PACKET,90)))
|
||||
{
|
||||
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
||||
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
|
||||
!nmb2->header.response) {
|
||||
/* its not for us - maybe deal with it later
|
||||
(put it on the queue?) */
|
||||
if (fn)
|
||||
fn(p2);
|
||||
else
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nmb2->header.opcode != 0 ||
|
||||
nmb2->header.nm_flags.bcast ||
|
||||
nmb2->header.rcode ||
|
||||
!nmb2->header.ancount) {
|
||||
/* XXXX what do we do with this? could be a redirect, but
|
||||
we'll discard it for the moment */
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ip) {
|
||||
putip((char *)ip,&nmb2->answers->rdata[2]);
|
||||
DEBUG(fn?3:2,("Got a positive name query response from %s",
|
||||
inet_ntoa(p2->ip)));
|
||||
DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip)));
|
||||
}
|
||||
found=True; retries=0;
|
||||
free_packet(p2);
|
||||
if (fn) break;
|
||||
}
|
||||
}
|
||||
|
||||
return(found);
|
||||
}
|
@ -21,15 +21,104 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "nameserv.h"
|
||||
#include "localnet.h"
|
||||
#include "loadparm.h"
|
||||
|
||||
extern struct in_addr myip;
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
int num_good_sends=0;
|
||||
int num_good_receives=0;
|
||||
static uint16 name_trn_id = 0;
|
||||
BOOL CanRecurse = True;
|
||||
int num_good_sends = 0;
|
||||
int num_good_receives = 0;
|
||||
extern pstring scope;
|
||||
extern pstring myname;
|
||||
extern struct in_addr ipzero;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
print out a res_rec structure
|
||||
****************************************************************************/
|
||||
static void debug_nmb_res_rec(struct res_rec *res, char *hdr)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
DEBUG(4,(" %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
|
||||
hdr,
|
||||
namestr(&res->rr_name),
|
||||
res->rr_type,
|
||||
res->rr_class,
|
||||
res->ttl));
|
||||
|
||||
if (res->rdlength == 0 || res->rdata == NULL) return;
|
||||
|
||||
for (i = 0; i < res->rdlength; i+= 16)
|
||||
{
|
||||
DEBUG(4, (" %s %3x char ", hdr, i));
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
unsigned char x = res->rdata[i+j];
|
||||
if (x < 32 || x > 127) x = '.';
|
||||
|
||||
if (i+j >= res->rdlength) break;
|
||||
DEBUG(4, ("%c", x));
|
||||
}
|
||||
|
||||
DEBUG(4, (" hex ", i));
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
if (i+j >= res->rdlength) break;
|
||||
DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j]));
|
||||
}
|
||||
|
||||
DEBUG(4, ("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
process a nmb packet
|
||||
****************************************************************************/
|
||||
void debug_nmb_packet(struct packet_struct *p)
|
||||
{
|
||||
struct nmb_packet *nmb = &p->packet.nmb;
|
||||
|
||||
DEBUG(4,("nmb packet from %s header: id=%d opcode=%d response=%s\n",
|
||||
inet_ntoa(p->ip),
|
||||
nmb->header.name_trn_id,nmb->header.opcode,BOOLSTR(nmb->header.response)));
|
||||
DEBUG(4,(" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
|
||||
BOOLSTR(nmb->header.nm_flags.bcast),
|
||||
BOOLSTR(nmb->header.nm_flags.recursion_available),
|
||||
BOOLSTR(nmb->header.nm_flags.recursion_desired),
|
||||
BOOLSTR(nmb->header.nm_flags.trunc),
|
||||
BOOLSTR(nmb->header.nm_flags.authoritative)));
|
||||
DEBUG(4,(" header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
|
||||
nmb->header.rcode,
|
||||
nmb->header.qdcount,
|
||||
nmb->header.ancount,
|
||||
nmb->header.nscount,
|
||||
nmb->header.arcount));
|
||||
|
||||
if (nmb->header.qdcount)
|
||||
{
|
||||
DEBUG(4,(" question: q_name=%s q_type=%d q_class=%d\n",
|
||||
namestr(&nmb->question.question_name),
|
||||
nmb->question.question_type,
|
||||
nmb->question.question_class));
|
||||
}
|
||||
|
||||
if (nmb->answers && nmb->header.ancount)
|
||||
{
|
||||
debug_nmb_res_rec(nmb->answers,"answers");
|
||||
}
|
||||
if (nmb->nsrecs && nmb->header.nscount)
|
||||
{
|
||||
debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
|
||||
}
|
||||
if (nmb->additional && nmb->header.arcount)
|
||||
{
|
||||
debug_nmb_res_rec(nmb->additional,"additional");
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
handle "compressed" name pointers
|
||||
@ -38,7 +127,7 @@ static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
|
||||
BOOL *got_pointer,int *ret)
|
||||
{
|
||||
int loop_count=0;
|
||||
|
||||
|
||||
while ((ubuf[*offset] & 0xC0) == 0xC0) {
|
||||
if (!*got_pointer) (*ret) += 2;
|
||||
(*got_pointer)=True;
|
||||
@ -54,8 +143,7 @@ static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
|
||||
parse a nmb name from "compressed" format to something readable
|
||||
return the space taken by the name, or 0 if the name is invalid
|
||||
******************************************************************/
|
||||
static int parse_nmb_name(char *inbuf,int offset,int length,
|
||||
struct nmb_name *name)
|
||||
static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name)
|
||||
{
|
||||
int m,n=0;
|
||||
unsigned char *ubuf = (unsigned char *)inbuf;
|
||||
@ -186,11 +274,10 @@ char *namestr(struct nmb_name *n)
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
allocate are parse some resource records
|
||||
allocate and parse some resource records
|
||||
******************************************************************/
|
||||
static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
|
||||
struct res_rec **recs,
|
||||
int count)
|
||||
struct res_rec **recs, int count)
|
||||
{
|
||||
int i;
|
||||
*recs = (struct res_rec *)malloc(sizeof(**recs)*count);
|
||||
@ -382,10 +469,10 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type)
|
||||
char buf[MAX_DGRAM_SIZE];
|
||||
int length;
|
||||
BOOL ok=False;
|
||||
|
||||
|
||||
length = read_udp_socket(fd,buf,sizeof(buf));
|
||||
if (length < MIN_DGRAM_SIZE) return(NULL);
|
||||
|
||||
|
||||
packet = (struct packet_struct *)malloc(sizeof(*packet));
|
||||
if (!packet) return(NULL);
|
||||
|
||||
@ -528,6 +615,7 @@ static int build_nmb(char *buf,struct packet_struct *p)
|
||||
if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80;
|
||||
if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
|
||||
ubuf[offset+3] |= (nmb->header.rcode & 0xF);
|
||||
|
||||
RSSVAL(ubuf,offset+4,nmb->header.qdcount);
|
||||
RSSVAL(ubuf,offset+6,nmb->header.ancount);
|
||||
RSSVAL(ubuf,offset+8,nmb->header.nscount);
|
||||
@ -607,334 +695,3 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
interpret a node status response
|
||||
****************************************************************************/
|
||||
static void interpret_node_status(char *p, char *master,char *rname)
|
||||
{
|
||||
int level = (master||rname)?4:0;
|
||||
int numnames = CVAL(p,0);
|
||||
DEBUG(level,("received %d names\n",numnames));
|
||||
|
||||
if (rname) *rname = 0;
|
||||
if (master) *master = 0;
|
||||
|
||||
p += 1;
|
||||
while (numnames--)
|
||||
{
|
||||
char qname[17];
|
||||
int type;
|
||||
fstring flags;
|
||||
int i;
|
||||
*flags = 0;
|
||||
StrnCpy(qname,p,15);
|
||||
type = CVAL(p,15);
|
||||
p += 16;
|
||||
|
||||
strcat(flags, (p[0] & 0x80) ? "<GROUP> " : " ");
|
||||
if ((p[0] & 0x60) == 0x00) strcat(flags,"B ");
|
||||
if ((p[0] & 0x60) == 0x20) strcat(flags,"P ");
|
||||
if ((p[0] & 0x60) == 0x40) strcat(flags,"M ");
|
||||
if ((p[0] & 0x60) == 0x60) strcat(flags,"_ ");
|
||||
if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
|
||||
if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
|
||||
if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
|
||||
if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
|
||||
|
||||
if (master && !*master && type == 0x1d) {
|
||||
StrnCpy(master,qname,15);
|
||||
trim_string(master,NULL," ");
|
||||
}
|
||||
|
||||
if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
|
||||
StrnCpy(rname,qname,15);
|
||||
trim_string(rname,NULL," ");
|
||||
}
|
||||
|
||||
for (i = strlen( qname) ; --i >= 0 ; ) {
|
||||
if (!isprint(qname[i])) qname[i] = '.';
|
||||
}
|
||||
DEBUG(level,("\t%-15s <%02x> - %s\n",qname,type,flags));
|
||||
p+=2;
|
||||
}
|
||||
DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
|
||||
IVAL(p,20),IVAL(p,24)));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
do a netbios name status query on a host
|
||||
|
||||
the "master" parameter is a hack used for finding workgroups.
|
||||
**************************************************************************/
|
||||
BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
|
||||
struct in_addr to_ip,char *master,char *rname,
|
||||
void (*fn)())
|
||||
{
|
||||
BOOL found=False;
|
||||
int retries = 2;
|
||||
int retry_time = 5000;
|
||||
struct timeval tval;
|
||||
struct packet_struct p;
|
||||
struct packet_struct *p2;
|
||||
struct nmb_packet *nmb = &p.packet.nmb;
|
||||
|
||||
bzero((char *)&p,sizeof(p));
|
||||
|
||||
if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
|
||||
(getpid()%(unsigned)100);
|
||||
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
|
||||
|
||||
nmb->header.name_trn_id = name_trn_id;
|
||||
nmb->header.opcode = 0;
|
||||
nmb->header.response = False;
|
||||
nmb->header.nm_flags.bcast = False;
|
||||
nmb->header.nm_flags.recursion_available = CanRecurse;
|
||||
nmb->header.nm_flags.recursion_desired = recurse;
|
||||
nmb->header.nm_flags.trunc = False;
|
||||
nmb->header.nm_flags.authoritative = False;
|
||||
nmb->header.rcode = 0;
|
||||
nmb->header.qdcount = 1;
|
||||
nmb->header.ancount = 0;
|
||||
nmb->header.nscount = 0;
|
||||
nmb->header.arcount = 0;
|
||||
|
||||
make_nmb_name(&nmb->question.question_name,name,name_type,scope);
|
||||
|
||||
nmb->question.question_type = 0x21;
|
||||
nmb->question.question_class = 0x1;
|
||||
|
||||
p.ip = to_ip;
|
||||
p.port = NMB_PORT;
|
||||
p.fd = fd;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = NMB_PACKET;
|
||||
|
||||
GetTimeOfDay(&tval);
|
||||
|
||||
if (!send_packet(&p))
|
||||
return(False);
|
||||
|
||||
retries--;
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct timeval tval2;
|
||||
GetTimeOfDay(&tval2);
|
||||
if (TvalDiff(&tval,&tval2) > retry_time) {
|
||||
if (!retries) break;
|
||||
if (!found && !send_packet(&p))
|
||||
return False;
|
||||
GetTimeOfDay(&tval);
|
||||
retries--;
|
||||
}
|
||||
|
||||
if ((p2=receive_packet(fd,NMB_PACKET,90)))
|
||||
{
|
||||
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
||||
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
|
||||
!nmb2->header.response) {
|
||||
/* its not for us - maybe deal with it later */
|
||||
if (fn)
|
||||
fn(p2);
|
||||
else
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nmb2->header.opcode != 0 ||
|
||||
nmb2->header.nm_flags.bcast ||
|
||||
nmb2->header.rcode ||
|
||||
!nmb2->header.ancount ||
|
||||
nmb2->answers->rr_type != 0x21) {
|
||||
/* XXXX what do we do with this? could be a redirect, but
|
||||
we'll discard it for the moment */
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
interpret_node_status(&nmb2->answers->rdata[0], master,rname);
|
||||
free_packet(p2);
|
||||
return(True);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DEBUG(0,("No status response (this is not unusual)\n"));
|
||||
|
||||
return(False);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
do a netbios name query to find someones IP
|
||||
****************************************************************************/
|
||||
BOOL name_query(int fd,char *name,int name_type,
|
||||
BOOL bcast,BOOL recurse,
|
||||
struct in_addr to_ip, struct in_addr *ip,void (*fn)())
|
||||
{
|
||||
BOOL found=False;
|
||||
int retries = 3;
|
||||
int retry_time = bcast?250:2000;
|
||||
struct timeval tval;
|
||||
struct packet_struct p;
|
||||
struct packet_struct *p2;
|
||||
struct nmb_packet *nmb = &p.packet.nmb;
|
||||
|
||||
bzero((char *)&p,sizeof(p));
|
||||
|
||||
if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
|
||||
(getpid()%(unsigned)100);
|
||||
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
|
||||
|
||||
nmb->header.name_trn_id = name_trn_id;
|
||||
nmb->header.opcode = 0;
|
||||
nmb->header.response = False;
|
||||
nmb->header.nm_flags.bcast = bcast;
|
||||
nmb->header.nm_flags.recursion_available = CanRecurse;
|
||||
nmb->header.nm_flags.recursion_desired = recurse;
|
||||
nmb->header.nm_flags.trunc = False;
|
||||
nmb->header.nm_flags.authoritative = False;
|
||||
nmb->header.rcode = 0;
|
||||
nmb->header.qdcount = 1;
|
||||
nmb->header.ancount = 0;
|
||||
nmb->header.nscount = 0;
|
||||
nmb->header.arcount = 0;
|
||||
|
||||
make_nmb_name(&nmb->question.question_name,name,name_type,scope);
|
||||
|
||||
nmb->question.question_type = 0x20;
|
||||
nmb->question.question_class = 0x1;
|
||||
|
||||
p.ip = to_ip;
|
||||
p.port = NMB_PORT;
|
||||
p.fd = fd;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = NMB_PACKET;
|
||||
|
||||
GetTimeOfDay(&tval);
|
||||
|
||||
if (!send_packet(&p))
|
||||
return(False);
|
||||
|
||||
retries--;
|
||||
|
||||
while (1)
|
||||
{
|
||||
struct timeval tval2;
|
||||
GetTimeOfDay(&tval2);
|
||||
if (TvalDiff(&tval,&tval2) > retry_time) {
|
||||
if (!retries) break;
|
||||
if (!found && !send_packet(&p))
|
||||
return False;
|
||||
GetTimeOfDay(&tval);
|
||||
retries--;
|
||||
}
|
||||
|
||||
if ((p2=receive_packet(fd,NMB_PACKET,90)))
|
||||
{
|
||||
struct nmb_packet *nmb2 = &p2->packet.nmb;
|
||||
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
|
||||
!nmb2->header.response) {
|
||||
/* its not for us - maybe deal with it later
|
||||
(put it on the queue?) */
|
||||
if (fn)
|
||||
fn(p2);
|
||||
else
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nmb2->header.opcode != 0 ||
|
||||
nmb2->header.nm_flags.bcast ||
|
||||
nmb2->header.rcode ||
|
||||
!nmb2->header.ancount) {
|
||||
/* XXXX what do we do with this? could be a redirect, but
|
||||
we'll discard it for the moment */
|
||||
free_packet(p2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ip) {
|
||||
putip((char *)ip,&nmb2->answers->rdata[2]);
|
||||
DEBUG(fn?3:2,("Got a positive name query response from %s",
|
||||
inet_ntoa(p2->ip)));
|
||||
DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip)));
|
||||
}
|
||||
found=True; retries=0;
|
||||
free_packet(p2);
|
||||
if (fn) break;
|
||||
}
|
||||
}
|
||||
|
||||
return(found);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
construct and send a netbios DGRAM
|
||||
|
||||
Note that this currently sends all answers to port 138. thats the
|
||||
wrong things to do! I should send to the requestors port. XXX
|
||||
**************************************************************************/
|
||||
BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,
|
||||
char *srcname,char *dstname,
|
||||
int src_type,int dest_type,
|
||||
struct in_addr dest_ip,
|
||||
struct in_addr src_ip)
|
||||
{
|
||||
struct packet_struct p;
|
||||
struct dgram_packet *dgram = &p.packet.dgram;
|
||||
char *ptr,*p2;
|
||||
char tmp[4];
|
||||
|
||||
bzero((char *)&p,sizeof(p));
|
||||
|
||||
dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
|
||||
dgram->header.flags.node_type = M_NODE;
|
||||
dgram->header.flags.first = True;
|
||||
dgram->header.flags.more = False;
|
||||
dgram->header.dgm_id = name_trn_id++;
|
||||
dgram->header.source_ip = src_ip;
|
||||
dgram->header.source_port = DGRAM_PORT;
|
||||
dgram->header.dgm_length = 0; /* let build_dgram() handle this */
|
||||
dgram->header.packet_offset = 0;
|
||||
|
||||
make_nmb_name(&dgram->source_name,srcname,src_type,scope);
|
||||
make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
|
||||
|
||||
ptr = &dgram->data[0];
|
||||
|
||||
/* now setup the smb part */
|
||||
ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
|
||||
memcpy(tmp,ptr,4);
|
||||
set_message(ptr,17,17 + len,True);
|
||||
memcpy(ptr,tmp,4);
|
||||
|
||||
CVAL(ptr,smb_com) = SMBtrans;
|
||||
SSVAL(ptr,smb_vwv1,len);
|
||||
SSVAL(ptr,smb_vwv11,len);
|
||||
SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
|
||||
SSVAL(ptr,smb_vwv13,3);
|
||||
SSVAL(ptr,smb_vwv14,1);
|
||||
SSVAL(ptr,smb_vwv15,1);
|
||||
SSVAL(ptr,smb_vwv16,2);
|
||||
p2 = smb_buf(ptr);
|
||||
strcpy(p2,mailslot);
|
||||
p2 = skip_string(p2,1);
|
||||
|
||||
memcpy(p2,buf,len);
|
||||
p2 += len;
|
||||
|
||||
dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
|
||||
|
||||
p.ip = dest_ip;
|
||||
p.port = DGRAM_PORT;
|
||||
p.fd = fd;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = DGRAM_PACKET;
|
||||
|
||||
return(send_packet(&p));
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,19 +28,6 @@
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
#ifndef uchar
|
||||
#define uchar unsigned char
|
||||
#endif
|
||||
#ifndef int16
|
||||
#define int16 unsigned short
|
||||
#endif
|
||||
#ifndef uint16
|
||||
#define uint16 unsigned short
|
||||
#endif
|
||||
#ifndef uint32
|
||||
#define uint32 unsigned int
|
||||
#endif
|
||||
|
||||
#include "byteorder.h"
|
||||
|
||||
void str_to_key(uchar *str,uchar *key)
|
||||
@ -198,5 +185,5 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
|
||||
}
|
||||
|
||||
#else
|
||||
void smbencrypt_dummy(void){}
|
||||
void smbencrypt_dummy(void){}
|
||||
#endif
|
||||
|
@ -67,6 +67,7 @@ extern int lp_max_log_size(void);
|
||||
extern int lp_maxxmit(void);
|
||||
extern int lp_maxmux(void);
|
||||
extern int lp_mangledstack(void);
|
||||
extern BOOL lp_wins_support(void);
|
||||
extern BOOL lp_preferred_master(void);
|
||||
extern BOOL lp_domain_master(void);
|
||||
extern BOOL lp_domain_logons(void);
|
||||
|
6
source3/localnet.h
Normal file
6
source3/localnet.h
Normal file
@ -0,0 +1,6 @@
|
||||
extern struct in_addr myip;
|
||||
extern struct in_addr bcast_ip;
|
||||
extern struct in_addr Netmask;
|
||||
|
||||
extern int ClientNMB;
|
||||
extern int ClientDGRAM;
|
444
source3/nameannounce.c
Normal file
444
source3/nameannounce.c
Normal file
@ -0,0 +1,444 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
NBT netbios routines and daemon - version 2
|
||||
Copyright (C) Andrew Tridgell 1994-1995
|
||||
|
||||
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 02139, USA.
|
||||
|
||||
Revision History:
|
||||
|
||||
14 jan 96: lkcl@pires.co.uk
|
||||
added multiple workgroup domain master support
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
|
||||
#define TEST_CODE
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
extern BOOL CanRecurse;
|
||||
|
||||
extern struct in_addr myip;
|
||||
extern struct in_addr bcast_ip;
|
||||
extern struct in_addr Netmask;
|
||||
extern struct in_addr ipzero;
|
||||
|
||||
extern pstring myname;
|
||||
|
||||
extern int ClientDGRAM;
|
||||
extern int ClientNMB;
|
||||
|
||||
/* this is our domain/workgroup/server database */
|
||||
extern struct domain_record *domainlist;
|
||||
|
||||
/* machine comment for host announcements */
|
||||
extern pstring ServerComment;
|
||||
|
||||
extern int updatecount;
|
||||
extern int workgroup_count;
|
||||
|
||||
/* what server type are we currently */
|
||||
|
||||
#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
|
||||
#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
|
||||
#define AM_DOMCTL(work) (work->ServerType & SV_TYPE_DOMAIN_CTRL)
|
||||
|
||||
#define MSBROWSE "\001\002__MSBROWSE__\002"
|
||||
#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
|
||||
|
||||
/****************************************************************************
|
||||
send a announce request to the local net
|
||||
**************************************************************************/
|
||||
void announce_request(struct work_record *work, struct in_addr ip)
|
||||
{
|
||||
pstring outbuf;
|
||||
char *p;
|
||||
|
||||
if (!work) return;
|
||||
|
||||
work->needannounce = True;
|
||||
|
||||
DEBUG(2,("Sending announce request to %s for workgroup %s\n",
|
||||
inet_ntoa(ip),work->work_group));
|
||||
|
||||
bzero(outbuf,sizeof(outbuf));
|
||||
p = outbuf;
|
||||
CVAL(p,0) = 2; /* announce request */
|
||||
p++;
|
||||
|
||||
CVAL(p,0) = work->token; /* flags?? XXXX probably a token*/
|
||||
p++;
|
||||
StrnCpy(p,myname,16);
|
||||
strupper(p);
|
||||
p = skip_string(p,1);
|
||||
|
||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
||||
myname,work->work_group,0x20,0x0,ip,myip);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
request an announcement
|
||||
**************************************************************************/
|
||||
void do_announce_request(char *info, char *to_name, int announce_type, int from,
|
||||
int to, struct in_addr dest_ip)
|
||||
{
|
||||
pstring outbuf;
|
||||
char *p;
|
||||
|
||||
bzero(outbuf,sizeof(outbuf));
|
||||
p = outbuf;
|
||||
CVAL(p,0) = announce_type; /* announce request */
|
||||
p++;
|
||||
|
||||
DEBUG(2,("Sending announce type %d: info %s to %s - server %s(%x)\n",
|
||||
announce_type, info, inet_ntoa(dest_ip),to_name,to));
|
||||
|
||||
StrnCpy(p,info,16);
|
||||
strupper(p);
|
||||
p = skip_string(p,1);
|
||||
|
||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
||||
myname,to_name,from,to,dest_ip,myip);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
construct a host announcement unicast
|
||||
**************************************************************************/
|
||||
void announce_backup(void)
|
||||
{
|
||||
static time_t lastrun = 0;
|
||||
time_t t = time(NULL);
|
||||
pstring outbuf;
|
||||
char *p;
|
||||
struct domain_record *d1;
|
||||
int tok;
|
||||
|
||||
if (!lastrun) lastrun = t;
|
||||
if (t < lastrun + 1*60) return;
|
||||
lastrun = t;
|
||||
|
||||
for (tok = 0; tok <= workgroup_count; tok++)
|
||||
{
|
||||
for (d1 = domainlist; d1; d1 = d1->next)
|
||||
{
|
||||
struct work_record *work;
|
||||
struct domain_record *d;
|
||||
|
||||
/* search for unique workgroup: only the name matters */
|
||||
for (work = d1->workgrouplist;
|
||||
work && (tok != work->token);
|
||||
work = work->next);
|
||||
|
||||
if (work)
|
||||
{
|
||||
/* found one: announce it across all domains */
|
||||
for (d = domainlist; d; d = d->next)
|
||||
{
|
||||
DEBUG(2,("Sending announce backup %s workgroup %s(%d)\n",
|
||||
inet_ntoa(d->bcast_ip),work->work_group,
|
||||
work->token));
|
||||
|
||||
bzero(outbuf,sizeof(outbuf));
|
||||
p = outbuf;
|
||||
CVAL(p,0) = 9; /* backup list response */
|
||||
p++;
|
||||
|
||||
CVAL(p,0) = 1; /* count? */
|
||||
SIVAL(p,1,work->token); /* workgroup unique key index */
|
||||
p += 5;
|
||||
p++;
|
||||
|
||||
if (AM_DOMCTL(work))
|
||||
{
|
||||
send_mailslot_reply(BROWSE_MAILSLOT,
|
||||
ClientDGRAM,outbuf,
|
||||
PTR_DIFF(p,outbuf),
|
||||
myname, work->work_group,
|
||||
0x0,0x1b,d->bcast_ip,myip);
|
||||
}
|
||||
else if (AM_MASTER(work))
|
||||
{
|
||||
send_mailslot_reply(BROWSE_MAILSLOT,
|
||||
ClientDGRAM,outbuf,
|
||||
PTR_DIFF(p,outbuf),
|
||||
myname, work->work_group,
|
||||
0x0,0x1d,d->bcast_ip,myip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
construct a host announcement unicast
|
||||
**************************************************************************/
|
||||
void announce_host(void)
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
pstring outbuf;
|
||||
char *p;
|
||||
char *namep;
|
||||
char *stypep;
|
||||
char *commentp;
|
||||
pstring comment;
|
||||
char *my_name;
|
||||
struct domain_record *d;
|
||||
|
||||
StrnCpy(comment, *ServerComment ? ServerComment : "NoComment", 43);
|
||||
|
||||
my_name = *myname ? myname : "NoName";
|
||||
|
||||
for (d = domainlist; d; d = d->next)
|
||||
{
|
||||
struct work_record *work;
|
||||
|
||||
if (!ip_equal(bcast_ip,d->bcast_ip))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (work = d->workgrouplist; work; work = work->next)
|
||||
{
|
||||
uint32 stype = work->ServerType;
|
||||
struct server_record *s;
|
||||
BOOL announce = False;
|
||||
|
||||
if (work->needannounce)
|
||||
{
|
||||
/* drop back to a max 3 minute announce - this is to prevent a
|
||||
single lost packet from stuffing things up for too long */
|
||||
work->announce_interval = MIN(work->announce_interval,3*60);
|
||||
work->lastannounce_time = t - (work->announce_interval+1);
|
||||
}
|
||||
|
||||
/* announce every minute at first then progress to every 12 mins */
|
||||
if (work->lastannounce_time &&
|
||||
(t - work->lastannounce_time) < work->announce_interval)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (work->announce_interval < 12*60) work->announce_interval += 60;
|
||||
|
||||
work->lastannounce_time = t;
|
||||
|
||||
DEBUG(2,("Sending announcement to subnet %s for workgroup %s\n",
|
||||
inet_ntoa(d->bcast_ip),work->work_group));
|
||||
|
||||
if (!ip_equal(bcast_ip,d->bcast_ip))
|
||||
{
|
||||
stype &= ~(SV_TYPE_POTENTIAL_BROWSER | SV_TYPE_MASTER_BROWSER |
|
||||
SV_TYPE_DOMAIN_MASTER | SV_TYPE_BACKUP_BROWSER |
|
||||
SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_MEMBER);
|
||||
}
|
||||
|
||||
for (s = work->serverlist; s; s = s->next)
|
||||
{
|
||||
if (strequal(myname, s->serv.name)) { announce = True; break; }
|
||||
}
|
||||
|
||||
if (announce)
|
||||
{
|
||||
bzero(outbuf,sizeof(outbuf));
|
||||
p = outbuf+1;
|
||||
|
||||
CVAL(p,0) = updatecount;
|
||||
SIVAL(p,1,work->announce_interval*1000); /* ms - despite the spec */
|
||||
namep = p+5;
|
||||
StrnCpy(namep,my_name,16);
|
||||
strupper(namep);
|
||||
CVAL(p,21) = 2; /* major version */
|
||||
CVAL(p,22) = 2; /* minor version */
|
||||
stypep = p+23;
|
||||
SIVAL(p,23,stype);
|
||||
SSVAL(p,27,0xaa55); /* browse signature */
|
||||
SSVAL(p,29,1); /* browse version */
|
||||
commentp = p+31;
|
||||
strcpy(commentp,comment);
|
||||
p = p+31;
|
||||
p = skip_string(p,1);
|
||||
|
||||
if (ip_equal(bcast_ip,d->bcast_ip))
|
||||
{
|
||||
if (AM_MASTER(work))
|
||||
{
|
||||
SIVAL(stypep,0,work->ServerType);
|
||||
|
||||
CVAL(outbuf,0) = 15; /* local member announce */
|
||||
|
||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
|
||||
PTR_DIFF(p,outbuf),
|
||||
my_name,work->work_group,0,0x1e,d->bcast_ip,myip);
|
||||
|
||||
CVAL(outbuf,0) = 12; /* domain announce */
|
||||
|
||||
StrnCpy(namep,work->work_group,15);
|
||||
strupper(namep);
|
||||
StrnCpy(commentp,myname,15);
|
||||
strupper(commentp);
|
||||
|
||||
SIVAL(stypep,0,(unsigned)0x80000000);
|
||||
p = commentp + strlen(commentp) + 1;
|
||||
|
||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
|
||||
PTR_DIFF(p,outbuf),
|
||||
my_name,MSBROWSE,0,0x01,d->bcast_ip,myip);
|
||||
}
|
||||
else
|
||||
{
|
||||
CVAL(outbuf,0) = 1; /* host announce */
|
||||
|
||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
|
||||
PTR_DIFF(p,outbuf),
|
||||
my_name,work->work_group,0,0x1d,d->bcast_ip,myip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (work->needannounce)
|
||||
{
|
||||
work->needannounce = False;
|
||||
break;
|
||||
/* sorry: can't do too many announces. do some more later */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
announce myself as a master to all other primary domain conrollers.
|
||||
|
||||
BIG NOTE: this code will remain untested until some kind soul that has access
|
||||
to a couple of windows NT advanced servers runs this version of nmbd for at
|
||||
least 15 minutes.
|
||||
|
||||
this actually gets done in search_and_sync_workgroups() via the
|
||||
MASTER_SERVER_CHECK command, if there is a response from the
|
||||
name query initiated here. see response_name_query()
|
||||
**************************************************************************/
|
||||
void announce_master(void)
|
||||
{
|
||||
struct domain_record *d;
|
||||
static time_t last=0;
|
||||
time_t t = time(NULL);
|
||||
BOOL am_master = False; /* are we a master of some sort? :-) */
|
||||
|
||||
#ifdef TEST_CODE
|
||||
if (last && (t-last < 2*60)) return;
|
||||
#else
|
||||
if (last && (t-last < 15*60)) return;
|
||||
#endif
|
||||
|
||||
last = t;
|
||||
|
||||
for (d = domainlist; d; d = d->next)
|
||||
{
|
||||
struct work_record *work;
|
||||
for (work = d->workgrouplist; work; work = work->next)
|
||||
{
|
||||
if (AM_MASTER(work))
|
||||
{
|
||||
am_master = True;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!am_master) return; /* only proceed if we are a master browser */
|
||||
|
||||
for (d = domainlist; d; d = d->next)
|
||||
{
|
||||
struct work_record *work;
|
||||
for (work = d->workgrouplist; work; work = work->next)
|
||||
{
|
||||
struct server_record *s;
|
||||
for (s = work->serverlist; s; s = s->next)
|
||||
{
|
||||
if (strequal(s->serv.name, myname)) continue;
|
||||
|
||||
/* all PDCs (which should also be master browsers) */
|
||||
if (s->serv.type & SV_TYPE_DOMAIN_CTRL)
|
||||
{
|
||||
/* check the existence of a pdc for this workgroup, and if
|
||||
one exists at the specified ip, sync with it and announce
|
||||
ourselves as a master browser to it */
|
||||
|
||||
if (!*lp_domain_controller() ||
|
||||
!strequal(lp_domain_controller(), s->serv.name))
|
||||
{
|
||||
if (!lp_wins_support() && *lp_wins_server())
|
||||
{
|
||||
struct in_addr ip;
|
||||
ip = ipzero;
|
||||
|
||||
queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,
|
||||
MASTER_SERVER_CHECK,
|
||||
work->work_group,0x1b,0,
|
||||
False, False, ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct domain_record *d2;
|
||||
for (d2 = domainlist; d2; d2 = d2->next)
|
||||
{
|
||||
queue_netbios_packet(ClientNMB,NMB_QUERY,
|
||||
MASTER_SERVER_CHECK,
|
||||
work->work_group,0x1b,0,
|
||||
True, False, d2->bcast_ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* now do primary domain controller - the one that's not
|
||||
necessarily in our browse lists, although it ought to be
|
||||
this pdc is the one that we get TOLD about through smb.conf.
|
||||
basically, if it's on a subnet that we know about, it may end
|
||||
up in our browse lists (which is why it's explicitly excluded
|
||||
in the code above) */
|
||||
|
||||
if (*lp_domain_controller())
|
||||
{
|
||||
struct in_addr ip;
|
||||
BOOL bcast = False;
|
||||
|
||||
ip = *interpret_addr2(lp_domain_controller());
|
||||
|
||||
if (zero_ip(ip))
|
||||
{
|
||||
ip = bcast_ip;
|
||||
bcast = True;
|
||||
}
|
||||
|
||||
DEBUG(2, ("Searching for PDC %s at %s\n",
|
||||
lp_domain_controller(), inet_ntoa(ip)));
|
||||
|
||||
/* check the existence of a pdc for this workgroup, and if
|
||||
one exists at the specified ip, sync with it and announce
|
||||
ourselves as a master browser to it */
|
||||
queue_netbios_pkt_wins(ClientNMB, NMB_QUERY,MASTER_SERVER_CHECK,
|
||||
work->work_group,0x1b, 0,
|
||||
bcast, False, ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
709
source3/namedb.c
Normal file
709
source3/namedb.c
Normal file
@ -0,0 +1,709 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
NBT netbios routines and daemon - version 2
|
||||
Copyright (C) Andrew Tridgell 1994-1995
|
||||
|
||||
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 02139, USA.
|
||||
|
||||
Revision History:
|
||||
|
||||
14 jan 96: lkcl@pires.co.uk
|
||||
added multiple workgroup domain master support
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "smb.h"
|
||||
#include "loadparm.h"
|
||||
#include "localnet.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
extern time_t StartupTime;
|
||||
extern pstring myname;
|
||||
extern pstring scope;
|
||||
extern struct in_addr bcast_ip;
|
||||
|
||||
/* this is our browse master/backup cache database */
|
||||
struct browse_cache_record *browserlist = NULL;
|
||||
|
||||
/* this is our domain/workgroup/server database */
|
||||
struct domain_record *domainlist = NULL;
|
||||
|
||||
static BOOL updatedlists = True;
|
||||
int updatecount=0;
|
||||
|
||||
int workgroup_count = 0; /* unique index key: one for each workgroup */
|
||||
|
||||
/* what server type are we currently */
|
||||
|
||||
#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
|
||||
SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX | \
|
||||
SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
|
||||
|
||||
/* here are my election parameters */
|
||||
|
||||
/* NTAS uses 2, NT uses 1, WfWg uses 0 */
|
||||
#define MAINTAIN_LIST 2
|
||||
#define ELECTION_VERSION 2
|
||||
|
||||
#define MSBROWSE "\001\002__MSBROWSE__\002"
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
add a workgroup into the domain list
|
||||
**************************************************************************/
|
||||
static void add_workgroup(struct work_record *work, struct domain_record *d)
|
||||
{
|
||||
struct work_record *w2;
|
||||
|
||||
if (!work || !d) return;
|
||||
|
||||
if (!d->workgrouplist)
|
||||
{
|
||||
d->workgrouplist = work;
|
||||
work->prev = NULL;
|
||||
work->next = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
for (w2 = d->workgrouplist; w2->next; w2 = w2->next);
|
||||
|
||||
w2->next = work;
|
||||
work->next = NULL;
|
||||
work->prev = w2;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
create a blank workgroup
|
||||
**************************************************************************/
|
||||
static struct work_record *make_workgroup(char *name)
|
||||
{
|
||||
struct work_record *work;
|
||||
struct domain_record *d;
|
||||
int t = -1;
|
||||
|
||||
if (!name || !name[0]) return NULL;
|
||||
|
||||
work = (struct work_record *)malloc(sizeof(*work));
|
||||
if (!work) return(NULL);
|
||||
|
||||
StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
|
||||
work->serverlist = NULL;
|
||||
|
||||
work->ServerType = DFLT_SERVER_TYPE;
|
||||
work->RunningElection = False;
|
||||
work->ElectionCount = 0;
|
||||
work->needelection = False;
|
||||
work->needannounce = True;
|
||||
|
||||
/* make sure all token representations of workgroups are unique */
|
||||
|
||||
for (d = domainlist; d && t == -1; d = d->next)
|
||||
{
|
||||
struct work_record *w;
|
||||
for (w = d->workgrouplist; w && t == -1; w = w->next)
|
||||
{
|
||||
if (strequal(w->work_group, work->work_group)) t = w->token;
|
||||
}
|
||||
}
|
||||
|
||||
if (t == -1)
|
||||
{
|
||||
work->token = ++workgroup_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
work->token = t;
|
||||
}
|
||||
|
||||
|
||||
/* WfWg uses 01040b01 */
|
||||
/* Win95 uses 01041501 */
|
||||
/* NTAS uses ???????? */
|
||||
work->ElectionCriterion = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8);
|
||||
work->ElectionCriterion |= (lp_os_level() << 24);
|
||||
if (lp_domain_master())
|
||||
{
|
||||
work->ElectionCriterion |= 0x80;
|
||||
}
|
||||
|
||||
return work;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
expire old servers in the serverlist
|
||||
time of -1 indicates everybody dies
|
||||
******************************************************************/
|
||||
static void remove_old_servers(struct work_record *work, time_t t)
|
||||
{
|
||||
struct server_record *s;
|
||||
struct server_record *nexts;
|
||||
|
||||
/* expire old entries in the serverlist */
|
||||
for (s = work->serverlist; s; s = nexts)
|
||||
{
|
||||
if (t == -1 || (s->death_time && s->death_time < t))
|
||||
{
|
||||
DEBUG(3,("Removing dead server %s\n",s->serv.name));
|
||||
updatedlists = True;
|
||||
nexts = s->next;
|
||||
|
||||
if (s->prev) s->prev->next = s->next;
|
||||
if (s->next) s->next->prev = s->prev;
|
||||
|
||||
if (work->serverlist == s) work->serverlist = s->next;
|
||||
|
||||
free(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
nexts = s->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
remove workgroups
|
||||
******************************************************************/
|
||||
struct work_record *remove_workgroup(struct domain_record *d, struct work_record *work)
|
||||
{
|
||||
struct work_record *ret_work = NULL;
|
||||
|
||||
if (!d || !work) return NULL;
|
||||
|
||||
DEBUG(3,("Removing old workgroup %s\n", work->work_group));
|
||||
|
||||
remove_old_servers(work, -1);
|
||||
|
||||
ret_work = work->next;
|
||||
|
||||
if (work->prev) work->prev->next = work->next;
|
||||
if (work->next) work->next->prev = work->prev;
|
||||
|
||||
if (d->workgrouplist == work) d->workgrouplist = work->next;
|
||||
|
||||
free(work);
|
||||
|
||||
return ret_work;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
add a domain into the list
|
||||
**************************************************************************/
|
||||
static void add_domain(struct domain_record *d)
|
||||
{
|
||||
struct domain_record *d2;
|
||||
|
||||
if (!domainlist)
|
||||
{
|
||||
domainlist = d;
|
||||
d->prev = NULL;
|
||||
d->next = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
for (d2 = domainlist; d2->next; d2 = d2->next);
|
||||
|
||||
d2->next = d;
|
||||
d->next = NULL;
|
||||
d->prev = d2;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
add a browser into the list
|
||||
**************************************************************************/
|
||||
static void add_browse_cache(struct browse_cache_record *b)
|
||||
{
|
||||
struct browse_cache_record *b2;
|
||||
|
||||
if (!browserlist)
|
||||
{
|
||||
browserlist = b;
|
||||
b->prev = NULL;
|
||||
b->next = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
for (b2 = browserlist; b2->next; b2 = b2->next) ;
|
||||
|
||||
b2->next = b;
|
||||
b->next = NULL;
|
||||
b->prev = b2;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
add a server into the list
|
||||
**************************************************************************/
|
||||
static void add_server(struct work_record *work,struct server_record *s)
|
||||
{
|
||||
struct server_record *s2;
|
||||
|
||||
if (!work->serverlist) {
|
||||
work->serverlist = s;
|
||||
s->prev = NULL;
|
||||
s->next = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
for (s2 = work->serverlist; s2->next; s2 = s2->next) ;
|
||||
|
||||
s2->next = s;
|
||||
s->next = NULL;
|
||||
s->prev = s2;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
remove old browse entries
|
||||
******************************************************************/
|
||||
void expire_browse_cache(time_t t)
|
||||
{
|
||||
struct browse_cache_record *b;
|
||||
struct browse_cache_record *nextb;
|
||||
|
||||
/* expire old entries in the serverlist */
|
||||
for (b = browserlist; b; b = nextb)
|
||||
{
|
||||
if (b->synced && b->sync_time < t)
|
||||
{
|
||||
DEBUG(3,("Removing dead cached browser %s\n",b->name));
|
||||
nextb = b->next;
|
||||
|
||||
if (b->prev) b->prev->next = b->next;
|
||||
if (b->next) b->next->prev = b->prev;
|
||||
|
||||
if (browserlist == b) browserlist = b->next;
|
||||
|
||||
free(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextb = b->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
find a workgroup in the workgrouplist
|
||||
only create it if the domain allows it, or the parameter 'add' insists
|
||||
that it get created/added anyway. this allows us to force entries in
|
||||
lmhosts file to be added.
|
||||
**************************************************************************/
|
||||
struct work_record *find_workgroupstruct(struct domain_record *d, fstring name, BOOL add)
|
||||
{
|
||||
struct work_record *ret, *work;
|
||||
|
||||
if (!d) return NULL;
|
||||
|
||||
DEBUG(4, ("workgroup search for %s: ", name));
|
||||
|
||||
if (strequal(name, "*"))
|
||||
{
|
||||
DEBUG(2,("add any workgroups: initiating browser search on %s\n",
|
||||
inet_ntoa(d->bcast_ip)));
|
||||
queue_netbios_pkt_wins(ClientNMB,NMB_QUERY, FIND_MASTER,
|
||||
MSBROWSE,0x1,0,
|
||||
True,False, d->bcast_ip);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (ret = d->workgrouplist; ret; ret = ret->next)
|
||||
{
|
||||
if (!strcmp(ret->work_group,name))
|
||||
{
|
||||
DEBUG(4, ("found\n"));
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(4, ("not found: creating\n"));
|
||||
|
||||
if ((work = make_workgroup(name)))
|
||||
{
|
||||
if (lp_preferred_master() &&
|
||||
strequal(lp_workgroup(), name) &&
|
||||
ip_equal(d->bcast_ip, bcast_ip))
|
||||
{
|
||||
DEBUG(3, ("preferred master startup for %s\n", work->work_group));
|
||||
work->needelection = True;
|
||||
work->ElectionCriterion |= (1<<3);
|
||||
}
|
||||
if (!ip_equal(bcast_ip, d->bcast_ip))
|
||||
{
|
||||
work->needelection = False;
|
||||
}
|
||||
add_workgroup(work, d);
|
||||
return(work);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
find a domain in the domainlist
|
||||
**************************************************************************/
|
||||
struct domain_record *find_domain(struct in_addr source_ip)
|
||||
{
|
||||
struct domain_record *d;
|
||||
|
||||
/* search through domain list for broadcast/netmask that matches
|
||||
the source ip address */
|
||||
|
||||
for (d = domainlist; d; d = d->next)
|
||||
{
|
||||
if (same_net(source_ip, d->bcast_ip, d->mask_ip))
|
||||
{
|
||||
return(d);
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
dump a copy of the workgroup/domain database
|
||||
**************************************************************************/
|
||||
static void dump_workgroups(void)
|
||||
{
|
||||
struct domain_record *d;
|
||||
|
||||
for (d = domainlist; d; d = d->next)
|
||||
{
|
||||
if (d->workgrouplist)
|
||||
{
|
||||
struct work_record *work;
|
||||
|
||||
DEBUG(3,("dump domain %15s: ", inet_ntoa(d->bcast_ip)));
|
||||
DEBUG(3,(" %15s:\n", inet_ntoa(d->bcast_ip)));
|
||||
|
||||
for (work = d->workgrouplist; work; work = work->next)
|
||||
{
|
||||
if (work->serverlist)
|
||||
{
|
||||
struct server_record *s;
|
||||
|
||||
DEBUG(3,("\t%s(%d)\n", work->work_group, work->token));
|
||||
for (s = work->serverlist; s; s = s->next)
|
||||
{
|
||||
DEBUG(3,("\t\t%s %8x (%s)\n",
|
||||
s->serv.name, s->serv.type, s->serv.comment));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
create a domain entry
|
||||
****************************************************************************/
|
||||
static struct domain_record *make_domain(struct in_addr ip, struct in_addr mask)
|
||||
{
|
||||
struct domain_record *d;
|
||||
d = (struct domain_record *)malloc(sizeof(*d));
|
||||
|
||||
if (!d) return(NULL);
|
||||
|
||||
bzero((char *)d,sizeof(*d));
|
||||
|
||||
DEBUG(4, ("making domain %s ", inet_ntoa(ip)));
|
||||
DEBUG(4, ("%s\n", inet_ntoa(mask)));
|
||||
|
||||
d->bcast_ip = ip;
|
||||
d->mask_ip = mask;
|
||||
d->workgrouplist = NULL;
|
||||
|
||||
add_domain(d);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
add a domain entry. creates a workgroup, if necessary, and adds the domain
|
||||
to the named a workgroup.
|
||||
****************************************************************************/
|
||||
struct domain_record *add_domain_entry(struct in_addr source_ip, struct in_addr source_mask,
|
||||
char *name, BOOL add)
|
||||
{
|
||||
struct domain_record *d;
|
||||
struct in_addr ip;
|
||||
|
||||
ip = *interpret_addr2("255.255.255.255");
|
||||
|
||||
if (zero_ip(source_ip)) source_ip = bcast_ip;
|
||||
|
||||
/* add the domain into our domain database */
|
||||
if ((d = find_domain(source_ip)) ||
|
||||
(d = make_domain(source_ip, source_mask)))
|
||||
{
|
||||
find_workgroupstruct(d, name, add);
|
||||
|
||||
/* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
|
||||
or register with WINS server, if it's our workgroup */
|
||||
if (strequal(lp_workgroup(), name))
|
||||
{
|
||||
add_name_entry(name,0x1e,NB_ACTIVE|NB_GROUP);
|
||||
add_name_entry(name,0x0 ,NB_ACTIVE|NB_GROUP);
|
||||
}
|
||||
|
||||
DEBUG(3,("Added domain name entry %s at %s\n", name,inet_ntoa(ip)));
|
||||
return d;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
add a browser entry
|
||||
****************************************************************************/
|
||||
struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
|
||||
time_t ttl, struct in_addr ip)
|
||||
{
|
||||
BOOL newentry=False;
|
||||
|
||||
struct browse_cache_record *b;
|
||||
|
||||
/* search for the entry: if it's already in the cache, update that entry */
|
||||
for (b = browserlist; b; b = b->next)
|
||||
{
|
||||
if (ip_equal(ip,b->ip) && strequal(b->group, wg)) break;
|
||||
}
|
||||
|
||||
if (b && b->synced)
|
||||
{
|
||||
/* entries get left in the cache for a while. this stops sync'ing too
|
||||
often if the network is large */
|
||||
DEBUG(4, ("browser %s %s %s already sync'd at time %d\n",
|
||||
b->name, b->group, inet_ntoa(b->ip), b->sync_time));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!b)
|
||||
{
|
||||
newentry = True;
|
||||
b = (struct browse_cache_record *)malloc(sizeof(*b));
|
||||
|
||||
if (!b) return(NULL);
|
||||
|
||||
bzero((char *)b,sizeof(*b));
|
||||
}
|
||||
|
||||
/* update the entry */
|
||||
ttl = time(NULL)+ttl;
|
||||
|
||||
StrnCpy(b->name ,name,sizeof(b->name )-1);
|
||||
StrnCpy(b->group,wg ,sizeof(b->group)-1);
|
||||
strupper(b->name);
|
||||
strupper(b->group);
|
||||
|
||||
b->ip = ip;
|
||||
b->type = type;
|
||||
|
||||
if (newentry || ttl < b->sync_time) b->sync_time = ttl;
|
||||
|
||||
if (newentry)
|
||||
{
|
||||
b->synced = False;
|
||||
add_browse_cache(b);
|
||||
|
||||
DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n",
|
||||
wg, name, type, inet_ntoa(ip),ttl));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n",
|
||||
wg, name, type, inet_ntoa(ip),ttl));
|
||||
}
|
||||
|
||||
return(b);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
add a server entry
|
||||
****************************************************************************/
|
||||
struct server_record *add_server_entry(struct domain_record *d, struct work_record *work,
|
||||
char *name,int servertype, int ttl,char *comment,
|
||||
BOOL replace)
|
||||
{
|
||||
BOOL newentry=False;
|
||||
struct server_record *s;
|
||||
|
||||
if (name[0] == '*')
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
for (s = work->serverlist; s; s = s->next)
|
||||
{
|
||||
if (strequal(name,s->serv.name)) break;
|
||||
}
|
||||
|
||||
if (s && !replace)
|
||||
{
|
||||
DEBUG(4,("Not replacing %s\n",name));
|
||||
return(s);
|
||||
}
|
||||
|
||||
updatedlists=True;
|
||||
|
||||
if (!s)
|
||||
{
|
||||
newentry = True;
|
||||
s = (struct server_record *)malloc(sizeof(*s));
|
||||
|
||||
if (!s) return(NULL);
|
||||
|
||||
bzero((char *)s,sizeof(*s));
|
||||
}
|
||||
|
||||
if (ip_equal(bcast_ip, d->bcast_ip) &&
|
||||
strequal(lp_workgroup(),work->work_group))
|
||||
{
|
||||
servertype |= SV_TYPE_LOCAL_LIST_ONLY;
|
||||
}
|
||||
else
|
||||
{
|
||||
servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
|
||||
}
|
||||
|
||||
/* update the entry */
|
||||
StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
|
||||
StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
|
||||
strupper(s->serv.name);
|
||||
s->serv.type = servertype;
|
||||
s->death_time = ttl?time(NULL)+ttl*3:0;
|
||||
|
||||
/* for a domain entry, the comment field refers to the server name */
|
||||
|
||||
if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
|
||||
|
||||
if (newentry)
|
||||
{
|
||||
add_server(work, s);
|
||||
|
||||
DEBUG(3,("Added "));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(3,("Updated "));
|
||||
}
|
||||
|
||||
DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
|
||||
name,servertype,comment,
|
||||
work->work_group,inet_ntoa(d->bcast_ip)));
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
write out browse.dat
|
||||
******************************************************************/
|
||||
void write_browse_list(void)
|
||||
{
|
||||
struct domain_record *d;
|
||||
|
||||
pstring fname,fnamenew;
|
||||
FILE *f;
|
||||
|
||||
if (!updatedlists) return;
|
||||
|
||||
dump_names();
|
||||
dump_workgroups();
|
||||
|
||||
updatedlists = False;
|
||||
updatecount++;
|
||||
|
||||
strcpy(fname,lp_lockdir());
|
||||
trim_string(fname,NULL,"/");
|
||||
strcat(fname,"/");
|
||||
strcat(fname,SERVER_LIST);
|
||||
strcpy(fnamenew,fname);
|
||||
strcat(fnamenew,".");
|
||||
|
||||
f = fopen(fnamenew,"w");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
|
||||
return;
|
||||
}
|
||||
|
||||
for (d = domainlist; d ; d = d->next)
|
||||
{
|
||||
struct work_record *work;
|
||||
for (work = d->workgrouplist; work ; work = work->next)
|
||||
{
|
||||
struct server_record *s;
|
||||
for (s = work->serverlist; s ; s = s->next)
|
||||
{
|
||||
fstring tmp;
|
||||
|
||||
/* don't list domains I don't have a master for */
|
||||
if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) &&
|
||||
!s->serv.comment[0])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* output server details, plus what workgroup/domain
|
||||
they're in. without the domain information, the
|
||||
combined list of all servers in all workgroups gets
|
||||
sent to anyone asking about any workgroup! */
|
||||
|
||||
sprintf(tmp, "\"%s\"", s->serv.name);
|
||||
fprintf(f, "%-25s ", tmp);
|
||||
fprintf(f, "%08x ", s->serv.type);
|
||||
sprintf(tmp, "\"%s\"", s->serv.comment);
|
||||
fprintf(f, "%-30s", tmp);
|
||||
fprintf(f, "\"%s\"\n", work->work_group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
unlink(fname);
|
||||
chmod(fnamenew,0644);
|
||||
rename(fnamenew,fname);
|
||||
DEBUG(3,("Wrote browse list %s\n",fname));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
expire old servers in the serverlist
|
||||
******************************************************************/
|
||||
void expire_servers(time_t t)
|
||||
{
|
||||
struct domain_record *d;
|
||||
|
||||
for (d = domainlist ; d ; d = d->next)
|
||||
{
|
||||
struct work_record *work;
|
||||
|
||||
for (work = d->workgrouplist; work; work = work->next)
|
||||
{
|
||||
remove_old_servers(work, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
371
source3/nameelect.c
Normal file
371
source3/nameelect.c
Normal file
@ -0,0 +1,371 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
NBT netbios routines and daemon - version 2
|
||||
Copyright (C) Andrew Tridgell 1994-1995
|
||||
|
||||
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 02139, USA.
|
||||
|
||||
Revision History:
|
||||
|
||||
14 jan 96: lkcl@pires.co.uk
|
||||
added multiple workgroup domain master support
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
#include "localnet.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
extern pstring scope;
|
||||
|
||||
extern pstring myname;
|
||||
|
||||
/* machine comment for host announcements */
|
||||
extern pstring ServerComment;
|
||||
|
||||
/* here are my election parameters */
|
||||
|
||||
/* NTAS uses 2, NT uses 1, WfWg uses 0 */
|
||||
#define MAINTAIN_LIST 2
|
||||
#define ELECTION_VERSION 2
|
||||
|
||||
extern time_t StartupTime;
|
||||
|
||||
#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
|
||||
|
||||
#define MSBROWSE "\001\002__MSBROWSE__\002"
|
||||
#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
|
||||
|
||||
extern struct domain_record *domainlist;
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
occasionally check to see if the master browser is around
|
||||
******************************************************************/
|
||||
void check_master_browser(void)
|
||||
{
|
||||
static time_t lastrun=0;
|
||||
time_t t = time(NULL);
|
||||
struct domain_record *d;
|
||||
|
||||
if (!lastrun) lastrun = t;
|
||||
if (t < lastrun + 2*60) return;
|
||||
lastrun = t;
|
||||
|
||||
for (d = domainlist; d; d = d->next)
|
||||
{
|
||||
struct work_record *work;
|
||||
|
||||
for (work = d->workgrouplist; work; work = work->next)
|
||||
{
|
||||
/* if we are not the browse master of a workgroup, and we can't
|
||||
find a browser on the subnet, do something about it. */
|
||||
|
||||
if (!AM_MASTER(work))
|
||||
{
|
||||
queue_netbios_packet(ClientNMB,NMB_QUERY,CHECK_MASTER,
|
||||
work->work_group,0x1d,0,
|
||||
True,False,d->bcast_ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
what to do if a master browser DOESN't exist
|
||||
******************************************************************/
|
||||
void browser_gone(char *work_name, struct in_addr ip)
|
||||
{
|
||||
struct domain_record *d = find_domain(ip);
|
||||
struct work_record *work = find_workgroupstruct(d, work_name, False);
|
||||
|
||||
if (!work || !d) return;
|
||||
|
||||
DEBUG(2,("Forcing election on %s\n",work->work_group));
|
||||
|
||||
if (strequal(work->work_group, lp_workgroup()) &&
|
||||
ip_equal(bcast_ip, d->bcast_ip))
|
||||
{
|
||||
/* we can attempt to become master browser */
|
||||
work->needelection = True;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(2,("no master browser for persistent entry %s %s\n",
|
||||
work->work_group, inet_ntoa(d->bcast_ip)));
|
||||
|
||||
/* XXXX oh dear. we are going to have problems here. the
|
||||
entry is a persistent one, there isn't anyone responsible
|
||||
for this workgroup up and running, yet we can't find it
|
||||
and we are going to continually have name_queries until
|
||||
a master browser is found for this workgroup on the
|
||||
remote subnet.
|
||||
*/
|
||||
}
|
||||
}
|
||||
/****************************************************************************
|
||||
send an election packet
|
||||
**************************************************************************/
|
||||
void send_election(struct domain_record *d, char *group,uint32 criterion,
|
||||
int timeup,char *name)
|
||||
{
|
||||
pstring outbuf;
|
||||
char *p;
|
||||
|
||||
if (!d) return;
|
||||
|
||||
DEBUG(2,("Sending election to %s for workgroup %s\n",
|
||||
inet_ntoa(d->bcast_ip),group));
|
||||
|
||||
bzero(outbuf,sizeof(outbuf));
|
||||
p = outbuf;
|
||||
CVAL(p,0) = 8; /* election */
|
||||
p++;
|
||||
|
||||
CVAL(p,0) = (criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION;
|
||||
SIVAL(p,1,criterion);
|
||||
SIVAL(p,5,timeup*1000); /* ms - despite the spec */
|
||||
p += 13;
|
||||
strcpy(p,name);
|
||||
strupper(p);
|
||||
p = skip_string(p,1);
|
||||
|
||||
send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
|
||||
name,group,0,0x1e,d->bcast_ip,myip);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
become the master browser
|
||||
******************************************************************/
|
||||
static void become_master(struct domain_record *d, struct work_record *work)
|
||||
{
|
||||
uint32 domain_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_SERVER_UNIX | 0x00400000;
|
||||
|
||||
if (!work) return;
|
||||
|
||||
DEBUG(2,("Becoming master for %s\n",work->work_group));
|
||||
|
||||
work->ServerType |= SV_TYPE_MASTER_BROWSER;
|
||||
work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
|
||||
work->ElectionCriterion |= 0x5;
|
||||
|
||||
/* add browse, master and general names to database or register with WINS */
|
||||
add_name_entry(MSBROWSE ,0x01,NB_ACTIVE|NB_GROUP);
|
||||
add_name_entry(work->work_group,0x1d,NB_ACTIVE );
|
||||
|
||||
if (lp_domain_master())
|
||||
{
|
||||
DEBUG(4,("Domain master: adding names...\n"));
|
||||
|
||||
/* add domain master and domain member names or register with WINS */
|
||||
add_name_entry(work->work_group,0x1b,NB_ACTIVE );
|
||||
add_name_entry(work->work_group,0x1c,NB_ACTIVE|NB_GROUP);
|
||||
|
||||
work->ServerType |= SV_TYPE_DOMAIN_MASTER;
|
||||
|
||||
if (lp_domain_logons())
|
||||
{
|
||||
work->ServerType |= SV_TYPE_DOMAIN_CTRL;
|
||||
work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
|
||||
}
|
||||
}
|
||||
|
||||
/* update our server status */
|
||||
add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
|
||||
add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
|
||||
|
||||
if (ip_equal(bcast_ip, d->bcast_ip))
|
||||
{
|
||||
/* ask all servers on our local net to announce to us */
|
||||
announce_request(work, d->bcast_ip);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
unbecome the master browser
|
||||
******************************************************************/
|
||||
void become_nonmaster(struct domain_record *d, struct work_record *work)
|
||||
{
|
||||
DEBUG(2,("Becoming non-master for %s\n",work->work_group));
|
||||
|
||||
work->ServerType &= ~SV_TYPE_MASTER_BROWSER;
|
||||
work->ServerType &= ~SV_TYPE_DOMAIN_MASTER;
|
||||
work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
|
||||
|
||||
work->ElectionCriterion &= ~0x4;
|
||||
|
||||
remove_name_entry(work->work_group,0x1b);
|
||||
remove_name_entry(work->work_group,0x1c);
|
||||
remove_name_entry(work->work_group,0x1d);
|
||||
remove_name_entry(MSBROWSE ,0x01);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
run the election
|
||||
******************************************************************/
|
||||
void run_elections(void)
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
static time_t lastime = 0;
|
||||
|
||||
struct domain_record *d;
|
||||
|
||||
/* send election packets once a second */
|
||||
if (lastime && t-lastime <= 0) return;
|
||||
|
||||
lastime = t;
|
||||
|
||||
for (d = domainlist; d; d = d->next)
|
||||
{
|
||||
struct work_record *work;
|
||||
for (work = d->workgrouplist; work; work = work->next)
|
||||
{
|
||||
if (work->RunningElection)
|
||||
{
|
||||
send_election(d,work->work_group, work->ElectionCriterion,
|
||||
t-StartupTime,myname);
|
||||
|
||||
if (work->ElectionCount++ >= 4)
|
||||
{
|
||||
/* I won! now what :-) */
|
||||
DEBUG(2,(">>> Won election on %s <<<\n",work->work_group));
|
||||
|
||||
work->RunningElection = False;
|
||||
become_master(d, work);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
work out if I win an election
|
||||
******************************************************************/
|
||||
static BOOL win_election(struct work_record *work,int version,uint32 criterion,
|
||||
int timeup,char *name)
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
uint32 mycriterion;
|
||||
if (version > ELECTION_VERSION) return(False);
|
||||
if (version < ELECTION_VERSION) return(True);
|
||||
|
||||
mycriterion = work->ElectionCriterion;
|
||||
|
||||
if (criterion > mycriterion) return(False);
|
||||
if (criterion < mycriterion) return(True);
|
||||
|
||||
if (timeup > (t - StartupTime)) return(False);
|
||||
if (timeup < (t - StartupTime)) return(True);
|
||||
|
||||
if (strcasecmp(myname,name) > 0) return(False);
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
process a election packet
|
||||
|
||||
An election dynamically decides who will be the master.
|
||||
******************************************************************/
|
||||
void process_election(struct packet_struct *p,char *buf)
|
||||
{
|
||||
struct dgram_packet *dgram = &p->packet.dgram;
|
||||
struct in_addr ip = dgram->header.source_ip;
|
||||
struct domain_record *d = find_domain(ip);
|
||||
int version = CVAL(buf,0);
|
||||
uint32 criterion = IVAL(buf,1);
|
||||
int timeup = IVAL(buf,5)/1000;
|
||||
char *name = buf+13;
|
||||
struct work_record *work;
|
||||
|
||||
if (!d) return;
|
||||
|
||||
name[15] = 0;
|
||||
|
||||
DEBUG(3,("Election request from %s vers=%d criterion=%08x timeup=%d\n",
|
||||
name,version,criterion,timeup));
|
||||
|
||||
if (same_context(dgram)) return;
|
||||
|
||||
for (work = d->workgrouplist; work; work = work->next)
|
||||
{
|
||||
if (listening_name(work, &dgram->dest_name) &&
|
||||
strequal(work->work_group, lp_workgroup()) &&
|
||||
ip_equal(d->bcast_ip, bcast_ip))
|
||||
{
|
||||
if (win_election(work, version,criterion,timeup,name))
|
||||
{
|
||||
if (!work->RunningElection)
|
||||
{
|
||||
work->needelection = True;
|
||||
work->ElectionCount=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
work->needelection = False;
|
||||
|
||||
if (work->RunningElection)
|
||||
{
|
||||
work->RunningElection = False;
|
||||
DEBUG(3,(">>> Lost election on %s <<<\n",work->work_group));
|
||||
|
||||
/* if we are the master then remove our masterly names */
|
||||
if (AM_MASTER(work))
|
||||
{
|
||||
become_nonmaster(d, work);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
checks whether a browser election is to be run on any workgroup
|
||||
***************************************************************************/
|
||||
BOOL check_elections(void)
|
||||
{
|
||||
struct domain_record *d;
|
||||
BOOL run_any_election = False;
|
||||
|
||||
for (d = domainlist; d; d = d->next)
|
||||
{
|
||||
struct work_record *work;
|
||||
for (work = d->workgrouplist; work; work = work->next)
|
||||
{
|
||||
run_any_election |= work->RunningElection;
|
||||
|
||||
if (work->needelection && !work->RunningElection)
|
||||
{
|
||||
DEBUG(3,(">>> Starting election on %s <<<\n",work->work_group));
|
||||
work->ElectionCount = 0;
|
||||
work->RunningElection = True;
|
||||
work->needelection = False;
|
||||
}
|
||||
}
|
||||
}
|
||||
return run_any_election;
|
||||
}
|
||||
|
625
source3/nameresp.c
Normal file
625
source3/nameresp.c
Normal file
@ -0,0 +1,625 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
NBT netbios library routines
|
||||
Copyright (C) Andrew Tridgell 1994-1995
|
||||
|
||||
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 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "localnet.h"
|
||||
#include "loadparm.h"
|
||||
|
||||
/* this is our initiated name query response database */
|
||||
struct name_response_record *nameresponselist = NULL;
|
||||
|
||||
extern struct in_addr myip;
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
static uint16 name_trn_id=0;
|
||||
BOOL CanRecurse = True;
|
||||
extern pstring scope;
|
||||
extern pstring myname;
|
||||
extern struct in_addr ipzero;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
add an initated name query into the list
|
||||
**************************************************************************/
|
||||
extern void add_response_record(struct name_response_record *n)
|
||||
{
|
||||
struct name_response_record *n2;
|
||||
|
||||
if (!nameresponselist)
|
||||
{
|
||||
nameresponselist = n;
|
||||
n->prev = NULL;
|
||||
n->next = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
for (n2 = nameresponselist; n2->next; n2 = n2->next) ;
|
||||
|
||||
n2->next = n;
|
||||
n->next = NULL;
|
||||
n->prev = n2;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
remove old name response entries
|
||||
******************************************************************/
|
||||
void expire_netbios_response_entries(time_t t)
|
||||
{
|
||||
struct name_response_record *n;
|
||||
struct name_response_record *nextn;
|
||||
|
||||
for (n = nameresponselist; n; n = nextn)
|
||||
{
|
||||
if (n->start_time < t)
|
||||
{
|
||||
DEBUG(3,("Removing dead name query for %s %s (num_msgs=%d)\n",
|
||||
inet_ntoa(n->to_ip), namestr(&n->name), n->num_msgs));
|
||||
|
||||
if (n->cmd_type == CHECK_MASTER && n->num_msgs == 0)
|
||||
{
|
||||
if (n->num_msgs > 1)
|
||||
{
|
||||
/* more than one master browser detected on a subnet.
|
||||
there is a configuration problem. force an election */
|
||||
struct domain_record *d;
|
||||
if ((d = find_domain(n->to_ip)))
|
||||
{
|
||||
send_election(d,n->name.name,0,0,myname);
|
||||
}
|
||||
}
|
||||
|
||||
/* if no response received, the master browser must have gone */
|
||||
browser_gone(n->name.name, n->to_ip);
|
||||
}
|
||||
|
||||
nextn = n->next;
|
||||
|
||||
if (n->prev) n->prev->next = n->next;
|
||||
if (n->next) n->next->prev = n->prev;
|
||||
|
||||
if (nameresponselist == n) nameresponselist = n->next;
|
||||
|
||||
free(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextn = n->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
reply to a netbios name packet
|
||||
****************************************************************************/
|
||||
void reply_netbios_packet(struct packet_struct *p1,int trn_id,int rcode,int opcode,
|
||||
struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
|
||||
char *data,int len)
|
||||
{
|
||||
struct packet_struct p;
|
||||
struct nmb_packet *nmb = &p.packet.nmb;
|
||||
struct res_rec answers;
|
||||
char *packet_type = "unknown";
|
||||
|
||||
p = *p1;
|
||||
|
||||
if (rr_type == NMB_STATUS) packet_type = "nmb_status";
|
||||
if (rr_type == NMB_QUERY ) packet_type = "nmb_query";
|
||||
if (rr_type == NMB_REG ) packet_type = "nmb_reg";
|
||||
if (rr_type == NMB_REL ) packet_type = "nmb_rel";
|
||||
|
||||
DEBUG(4,("replying netbios packet: %s %s\n",
|
||||
packet_type, namestr(rr_name), inet_ntoa(p.ip)));
|
||||
|
||||
nmb->header.name_trn_id = trn_id;
|
||||
nmb->header.opcode = opcode;
|
||||
nmb->header.response = True;
|
||||
nmb->header.nm_flags.bcast = False;
|
||||
nmb->header.nm_flags.recursion_available = True;
|
||||
nmb->header.nm_flags.recursion_desired = True;
|
||||
nmb->header.nm_flags.trunc = False;
|
||||
nmb->header.nm_flags.authoritative = True;
|
||||
|
||||
nmb->header.qdcount = 0;
|
||||
nmb->header.ancount = 1;
|
||||
nmb->header.nscount = 0;
|
||||
nmb->header.arcount = 0;
|
||||
nmb->header.rcode = 0;
|
||||
|
||||
bzero((char*)&nmb->question,sizeof(nmb->question));
|
||||
|
||||
nmb->answers = &answers;
|
||||
bzero((char*)nmb->answers,sizeof(*nmb->answers));
|
||||
|
||||
nmb->answers->rr_name = *rr_name;
|
||||
nmb->answers->rr_type = rr_type;
|
||||
nmb->answers->rr_class = rr_class;
|
||||
nmb->answers->ttl = ttl;
|
||||
|
||||
if (data && len)
|
||||
{
|
||||
nmb->answers->rdlength = len;
|
||||
memcpy(nmb->answers->rdata, data, len);
|
||||
}
|
||||
|
||||
p.packet_type = NMB_PACKET;
|
||||
|
||||
debug_nmb_packet(&p);
|
||||
|
||||
send_packet(&p);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
initiate a netbios packet
|
||||
****************************************************************************/
|
||||
uint16 initiate_netbios_packet(int fd,int quest_type,char *name,int name_type,
|
||||
int nb_flags,BOOL bcast,BOOL recurse,struct in_addr to_ip)
|
||||
{
|
||||
struct packet_struct p;
|
||||
struct nmb_packet *nmb = &p.packet.nmb;
|
||||
struct res_rec additional_rec;
|
||||
char *packet_type = "unknown";
|
||||
int opcode = -1;
|
||||
|
||||
if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
|
||||
if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
|
||||
if (quest_type == NMB_REG ) { packet_type = "nmb_reg"; opcode = 5; }
|
||||
if (quest_type == NMB_REL ) { packet_type = "nmb_rel"; opcode = 6; }
|
||||
|
||||
DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
|
||||
packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
|
||||
|
||||
if (opcode == -1) return False;
|
||||
|
||||
bzero((char *)&p,sizeof(p));
|
||||
|
||||
if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
|
||||
(getpid()%(unsigned)100);
|
||||
name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
|
||||
|
||||
nmb->header.name_trn_id = name_trn_id;
|
||||
nmb->header.opcode = opcode;
|
||||
nmb->header.response = False;
|
||||
nmb->header.nm_flags.bcast = bcast;
|
||||
nmb->header.nm_flags.recursion_available = CanRecurse;
|
||||
nmb->header.nm_flags.recursion_desired = recurse;
|
||||
nmb->header.nm_flags.trunc = False;
|
||||
nmb->header.nm_flags.authoritative = False;
|
||||
nmb->header.rcode = 0;
|
||||
nmb->header.qdcount = 1;
|
||||
nmb->header.ancount = 0;
|
||||
nmb->header.nscount = 0;
|
||||
nmb->header.arcount = (quest_type==NMB_REG || quest_type==NMB_REL) ? 1 : 0;
|
||||
|
||||
make_nmb_name(&nmb->question.question_name,name,name_type,scope);
|
||||
|
||||
nmb->question.question_type = quest_type;
|
||||
nmb->question.question_class = 0x1;
|
||||
|
||||
if (quest_type == NMB_REG || quest_type == NMB_REL)
|
||||
{
|
||||
nmb->additional = &additional_rec;
|
||||
bzero((char *)nmb->additional,sizeof(*nmb->additional));
|
||||
|
||||
nmb->additional->rr_name = nmb->question.question_name;
|
||||
nmb->additional->rr_type = nmb->question.question_type;
|
||||
nmb->additional->rr_class = nmb->question.question_class;
|
||||
|
||||
nmb->additional->ttl = quest_type == NMB_REG ? lp_max_ttl() : 0;
|
||||
nmb->additional->rdlength = 6;
|
||||
nmb->additional->rdata[0] = nb_flags;
|
||||
putip(&nmb->additional->rdata[2],(char *)&myip);
|
||||
}
|
||||
|
||||
p.ip = to_ip;
|
||||
p.port = NMB_PORT;
|
||||
p.fd = fd;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = NMB_PACKET;
|
||||
|
||||
if (!send_packet(&p))
|
||||
return(0);
|
||||
|
||||
return(name_trn_id);
|
||||
}
|
||||
|
||||
|
||||
void send_name_reg(void)
|
||||
{
|
||||
struct packet_struct p;
|
||||
struct nmb_packet *nmb = &p.packet.nmb;
|
||||
int rcode = 0;
|
||||
|
||||
nmb->header.opcode = 5;
|
||||
nmb->header.response = True;
|
||||
nmb->header.nm_flags.bcast = False;
|
||||
nmb->header.nm_flags.recursion_available = CanRecurse;
|
||||
nmb->header.nm_flags.recursion_desired = CanRecurse;
|
||||
nmb->header.nm_flags.trunc = False;
|
||||
nmb->header.nm_flags.authoritative = True;
|
||||
nmb->header.qdcount = 0;
|
||||
nmb->header.ancount = 1;
|
||||
nmb->header.nscount = 0;
|
||||
nmb->header.arcount = 0;
|
||||
nmb->header.rcode = rcode;
|
||||
|
||||
send_packet(&p);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
wrapper function to override a broadcast message and send it to the WINS
|
||||
name server instead, if it exists. if wins is false, and there has been no
|
||||
WINS server specified, the packet will NOT be sent.
|
||||
****************************************************************************/
|
||||
void queue_netbios_pkt_wins(int fd,int quest_type,enum cmd_type cmd,
|
||||
char *name,int name_type,int nb_flags,
|
||||
BOOL bcast,BOOL recurse,struct in_addr to_ip)
|
||||
{
|
||||
if ((!lp_wins_support()) && (*lp_wins_server()))
|
||||
{
|
||||
/* samba is not a WINS server, and we are using a WINS server */
|
||||
struct in_addr wins_ip;
|
||||
wins_ip = *interpret_addr2(lp_wins_server());
|
||||
|
||||
if (!zero_ip(wins_ip))
|
||||
{
|
||||
bcast = False;
|
||||
to_ip = wins_ip;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* oops. smb.conf's wins server parameter MUST be a host_name
|
||||
or an ip_address. */
|
||||
DEBUG(0,("invalid smb.conf parameter 'wins server'\n"));
|
||||
}
|
||||
}
|
||||
|
||||
if (zero_ip(to_ip)) return;
|
||||
|
||||
queue_netbios_packet(fd, quest_type, cmd,
|
||||
name, name_type, nb_flags,
|
||||
bcast, recurse, to_ip);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
create a name query response record
|
||||
**************************************************************************/
|
||||
static struct name_response_record *make_name_query_record(
|
||||
enum cmd_type cmd,int id,int fd,
|
||||
char *name,int type,
|
||||
BOOL bcast,BOOL recurse,
|
||||
struct in_addr ip)
|
||||
{
|
||||
struct name_response_record *n;
|
||||
|
||||
if (!name || !name[0]) return NULL;
|
||||
|
||||
if (!(n = (struct name_response_record *)malloc(sizeof(*n))))
|
||||
return(NULL);
|
||||
|
||||
n->response_id = id;
|
||||
n->cmd_type = cmd;
|
||||
n->fd = fd;
|
||||
make_nmb_name(&n->name, name, type, scope);
|
||||
n->bcast = bcast;
|
||||
n->recurse = recurse;
|
||||
n->to_ip = ip;
|
||||
n->start_time = time(NULL);
|
||||
n->num_msgs = 0;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
initiate a netbios name query to find someone's or someones' IP
|
||||
this is intended to be used (not exclusively) for broadcasting to
|
||||
master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
|
||||
complete lists across a wide area network
|
||||
****************************************************************************/
|
||||
void queue_netbios_packet(int fd,int quest_type,enum cmd_type cmd,char *name,
|
||||
int name_type,int nb_flags,BOOL bcast,BOOL recurse,
|
||||
struct in_addr to_ip)
|
||||
{
|
||||
uint16 id = initiate_netbios_packet(fd, quest_type, name, name_type,
|
||||
nb_flags, bcast, recurse, to_ip);
|
||||
struct name_response_record *n;
|
||||
|
||||
if (id == 0) return;
|
||||
|
||||
if ((n = make_name_query_record(cmd,id,fd,name,name_type,bcast,recurse,to_ip)))
|
||||
{
|
||||
add_response_record(n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
find a response in the name query response list
|
||||
**************************************************************************/
|
||||
struct name_response_record *find_name_query(uint16 id)
|
||||
{
|
||||
struct name_response_record *n;
|
||||
|
||||
for (n = nameresponselist; n; n = n->next)
|
||||
{
|
||||
if (n->response_id == id) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
the global packet linked-list. incoming entries are added to the
|
||||
end of this list. it is supposed to remain fairly short so we
|
||||
won't bother with an end pointer.
|
||||
******************************************************************/
|
||||
static struct packet_struct *packet_queue = NULL;
|
||||
|
||||
/*******************************************************************
|
||||
queue a packet into the packet queue
|
||||
******************************************************************/
|
||||
void queue_packet(struct packet_struct *packet)
|
||||
{
|
||||
struct packet_struct *p;
|
||||
|
||||
if (!packet_queue) {
|
||||
packet->prev = NULL;
|
||||
packet->next = NULL;
|
||||
packet_queue = packet;
|
||||
return;
|
||||
}
|
||||
|
||||
/* find the bottom */
|
||||
for (p=packet_queue;p->next;p=p->next) ;
|
||||
|
||||
p->next = packet;
|
||||
packet->next = NULL;
|
||||
packet->prev = p;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
run elements off the packet queue till its empty
|
||||
******************************************************************/
|
||||
void run_packet_queue()
|
||||
{
|
||||
struct packet_struct *p;
|
||||
|
||||
while ((p=packet_queue))
|
||||
{
|
||||
switch (p->packet_type)
|
||||
{
|
||||
case NMB_PACKET:
|
||||
process_nmb(p);
|
||||
break;
|
||||
|
||||
case DGRAM_PACKET:
|
||||
process_dgram(p);
|
||||
break;
|
||||
}
|
||||
|
||||
packet_queue = packet_queue->next;
|
||||
if (packet_queue) packet_queue->prev = NULL;
|
||||
free_packet(p);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
listens for NMB or DGRAM packets, and queues them
|
||||
***************************************************************************/
|
||||
void listen_for_packets(BOOL run_election)
|
||||
{
|
||||
fd_set fds;
|
||||
int selrtn;
|
||||
struct timeval timeout;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(ClientNMB,&fds);
|
||||
FD_SET(ClientDGRAM,&fds);
|
||||
|
||||
/* during elections we need to send election packets at one
|
||||
second intervals */
|
||||
|
||||
timeout.tv_sec = run_election ? 1 : NMBD_SELECT_LOOP;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
selrtn = sys_select(&fds,&timeout);
|
||||
|
||||
if (FD_ISSET(ClientNMB,&fds))
|
||||
{
|
||||
struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
|
||||
if (packet) queue_packet(packet);
|
||||
}
|
||||
|
||||
if (FD_ISSET(ClientDGRAM,&fds))
|
||||
{
|
||||
struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
|
||||
if (packet) queue_packet(packet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
interpret a node status response. this is pretty hacked: we need two bits of
|
||||
info. a) the name of the workgroup b) the name of the server. it will also
|
||||
add all the names it finds into the namelist.
|
||||
****************************************************************************/
|
||||
BOOL interpret_node_status(char *p, struct nmb_name *name,int t,
|
||||
char *serv_name, struct in_addr ip)
|
||||
{
|
||||
int level = t==0x20 ? 4 : 0;
|
||||
int numnames = CVAL(p,0);
|
||||
BOOL found = False;
|
||||
|
||||
DEBUG(level,("received %d names\n",numnames));
|
||||
|
||||
p += 1;
|
||||
|
||||
if (serv_name) *serv_name = 0;
|
||||
|
||||
while (numnames--)
|
||||
{
|
||||
char qname[17];
|
||||
int type;
|
||||
fstring flags;
|
||||
int nb_flags;
|
||||
|
||||
BOOL group = False;
|
||||
BOOL add = False;
|
||||
|
||||
*flags = 0;
|
||||
|
||||
StrnCpy(qname,p,15);
|
||||
type = CVAL(p,15);
|
||||
nb_flags = p[16];
|
||||
|
||||
p += 18;
|
||||
|
||||
if (NAME_GROUP (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
|
||||
if (NAME_BFLAG (nb_flags)) { strcat(flags,"B "); }
|
||||
if (NAME_PFLAG (nb_flags)) { strcat(flags,"P "); }
|
||||
if (NAME_MFLAG (nb_flags)) { strcat(flags,"M "); }
|
||||
if (NAME__FLAG (nb_flags)) { strcat(flags,"_ "); }
|
||||
if (NAME_DEREG (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
|
||||
if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); add=True;}
|
||||
if (NAME_ACTIVE (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
|
||||
if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
|
||||
|
||||
/* might as well update our namelist while we're at it */
|
||||
if (add)
|
||||
{
|
||||
struct in_addr nameip;
|
||||
enum name_source src;
|
||||
|
||||
if (ip_equal(ip, myip))
|
||||
{
|
||||
nameip = ipzero;
|
||||
src = SELF;
|
||||
}
|
||||
else
|
||||
{
|
||||
nameip = ip;
|
||||
src = STATUS_QUERY;
|
||||
}
|
||||
add_netbios_entry(qname,type,nb_flags,2*60*60,src,nameip);
|
||||
}
|
||||
|
||||
/* we want the server name */
|
||||
if (serv_name && !*serv_name && !group && t == 0)
|
||||
{
|
||||
StrnCpy(serv_name,qname,15);
|
||||
serv_name[15] = 0;
|
||||
}
|
||||
|
||||
/* looking for a name and type? */
|
||||
if (name && !found && (t == type))
|
||||
{
|
||||
/* take a guess at some of the name types we're going to ask for.
|
||||
evaluate whether they are group names or no... */
|
||||
if (((t == 0x1b || t == 0x1d ) && !group) ||
|
||||
((t == 0x20 || t == 0x1c || t == 0x1e) && group))
|
||||
{
|
||||
found = True;
|
||||
make_nmb_name(name,qname,type,scope);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(level,("\t%s(0x%x)\t%s\n",qname,type,flags));
|
||||
}
|
||||
DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
|
||||
IVAL(p,20),IVAL(p,24)));
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
construct and send a netbios DGRAM
|
||||
|
||||
Note that this currently sends all answers to port 138. thats the
|
||||
wrong things to do! I should send to the requestors port. XXX
|
||||
**************************************************************************/
|
||||
BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
|
||||
char *dstname,int src_type,int dest_type,
|
||||
struct in_addr dest_ip,struct in_addr src_ip)
|
||||
{
|
||||
struct packet_struct p;
|
||||
struct dgram_packet *dgram = &p.packet.dgram;
|
||||
char *ptr,*p2;
|
||||
char tmp[4];
|
||||
|
||||
bzero((char *)&p,sizeof(p));
|
||||
|
||||
dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
|
||||
dgram->header.flags.node_type = M_NODE;
|
||||
dgram->header.flags.first = True;
|
||||
dgram->header.flags.more = False;
|
||||
dgram->header.dgm_id = name_trn_id++;
|
||||
dgram->header.source_ip = src_ip;
|
||||
dgram->header.source_port = DGRAM_PORT;
|
||||
dgram->header.dgm_length = 0; /* let build_dgram() handle this */
|
||||
dgram->header.packet_offset = 0;
|
||||
|
||||
make_nmb_name(&dgram->source_name,srcname,src_type,scope);
|
||||
make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
|
||||
|
||||
ptr = &dgram->data[0];
|
||||
|
||||
/* now setup the smb part */
|
||||
ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
|
||||
memcpy(tmp,ptr,4);
|
||||
set_message(ptr,17,17 + len,True);
|
||||
memcpy(ptr,tmp,4);
|
||||
|
||||
CVAL(ptr,smb_com) = SMBtrans;
|
||||
SSVAL(ptr,smb_vwv1,len);
|
||||
SSVAL(ptr,smb_vwv11,len);
|
||||
SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
|
||||
SSVAL(ptr,smb_vwv13,3);
|
||||
SSVAL(ptr,smb_vwv14,1);
|
||||
SSVAL(ptr,smb_vwv15,1);
|
||||
SSVAL(ptr,smb_vwv16,2);
|
||||
p2 = smb_buf(ptr);
|
||||
strcpy(p2,mailslot);
|
||||
p2 = skip_string(p2,1);
|
||||
|
||||
memcpy(p2,buf,len);
|
||||
p2 += len;
|
||||
|
||||
dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
|
||||
|
||||
p.ip = dest_ip;
|
||||
p.port = DGRAM_PORT;
|
||||
p.fd = fd;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = DGRAM_PACKET;
|
||||
|
||||
return(send_packet(&p));
|
||||
}
|
||||
|
||||
|
2880
source3/nameserv.c
2880
source3/nameserv.c
File diff suppressed because it is too large
Load Diff
1072
source3/namework.c
Normal file
1072
source3/namework.c
Normal file
File diff suppressed because it is too large
Load Diff
601
source3/nmbd/nmbd.c
Normal file
601
source3/nmbd/nmbd.c
Normal file
@ -0,0 +1,601 @@
|
||||
/*
|
||||
Unix SMB/Netbios implementation.
|
||||
Version 1.9.
|
||||
NBT netbios routines and daemon - version 2
|
||||
Copyright (C) Andrew Tridgell 1994-1995
|
||||
|
||||
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 02139, USA.
|
||||
|
||||
Revision History:
|
||||
|
||||
14 jan 96: lkcl@pires.co.uk
|
||||
added multiple workgroup domain master support
|
||||
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
#include "localnet.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
extern pstring debugf;
|
||||
pstring servicesf = CONFIGFILE;
|
||||
|
||||
extern pstring scope;
|
||||
|
||||
int ClientNMB = -1;
|
||||
int ClientDGRAM = -1;
|
||||
|
||||
extern pstring myhostname;
|
||||
static pstring host_file;
|
||||
extern pstring myname;
|
||||
|
||||
/* are we running as a daemon ? */
|
||||
static BOOL is_daemon = False;
|
||||
|
||||
/* machine comment for host announcements */
|
||||
pstring ServerComment="";
|
||||
|
||||
static BOOL got_bcast = False;
|
||||
static BOOL got_myip = False;
|
||||
static BOOL got_nmask = False;
|
||||
|
||||
/* what server type are we currently */
|
||||
|
||||
time_t StartupTime =0;
|
||||
|
||||
struct in_addr ipzero;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
catch a sighup
|
||||
****************************************************************************/
|
||||
static int sig_hup(void)
|
||||
{
|
||||
BlockSignals(True);
|
||||
|
||||
DEBUG(0,("Got SIGHUP (reload not implemented)\n"));
|
||||
dump_names();
|
||||
reload_services(True);
|
||||
|
||||
BlockSignals(False);
|
||||
#ifndef DONT_REINSTALL_SIG
|
||||
signal(SIGHUP,SIGNAL_CAST sig_hup);
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
catch a sigpipe
|
||||
****************************************************************************/
|
||||
static int sig_pipe(void)
|
||||
{
|
||||
BlockSignals(True);
|
||||
|
||||
DEBUG(0,("Got SIGPIPE\n"));
|
||||
if (!is_daemon)
|
||||
exit(1);
|
||||
BlockSignals(False);
|
||||
return(0);
|
||||
}
|
||||
|
||||
#if DUMP_CORE
|
||||
/*******************************************************************
|
||||
prepare to dump a core file - carefully!
|
||||
********************************************************************/
|
||||
static BOOL dump_core(void)
|
||||
{
|
||||
char *p;
|
||||
pstring dname;
|
||||
strcpy(dname,debugf);
|
||||
if ((p=strrchr(dname,'/'))) *p=0;
|
||||
strcat(dname,"/corefiles");
|
||||
mkdir(dname,0700);
|
||||
sys_chown(dname,getuid(),getgid());
|
||||
chmod(dname,0700);
|
||||
if (chdir(dname)) return(False);
|
||||
umask(~(0700));
|
||||
|
||||
#ifndef NO_GETRLIMIT
|
||||
#ifdef RLIMIT_CORE
|
||||
{
|
||||
struct rlimit rlp;
|
||||
getrlimit(RLIMIT_CORE, &rlp);
|
||||
rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
|
||||
setrlimit(RLIMIT_CORE, &rlp);
|
||||
getrlimit(RLIMIT_CORE, &rlp);
|
||||
DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
DEBUG(0,("Dumping core in %s\n",dname));
|
||||
return(True);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
possibly continue after a fault
|
||||
****************************************************************************/
|
||||
static void fault_continue(void)
|
||||
{
|
||||
#if DUMP_CORE
|
||||
dump_core();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
expire old names from the namelist and server list
|
||||
******************************************************************/
|
||||
static void expire_names_and_servers(void)
|
||||
{
|
||||
static time_t lastrun = 0;
|
||||
time_t t = time(NULL);
|
||||
|
||||
if (!lastrun) lastrun = t;
|
||||
if (t < lastrun + 5) return;
|
||||
lastrun = t;
|
||||
|
||||
expire_names(t);
|
||||
expire_servers(t);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
reload the services file
|
||||
**************************************************************************/
|
||||
BOOL reload_services(BOOL test)
|
||||
{
|
||||
BOOL ret;
|
||||
extern fstring remote_machine;
|
||||
|
||||
strcpy(remote_machine,"nmbd");
|
||||
|
||||
if (lp_loaded())
|
||||
{
|
||||
pstring fname;
|
||||
strcpy(fname,lp_configfile());
|
||||
if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
|
||||
{
|
||||
strcpy(servicesf,fname);
|
||||
test = False;
|
||||
}
|
||||
}
|
||||
|
||||
if (test && !lp_file_list_changed())
|
||||
return(True);
|
||||
|
||||
ret = lp_load(servicesf,True);
|
||||
|
||||
/* perhaps the config filename is now set */
|
||||
if (!test) {
|
||||
DEBUG(3,("services not loaded\n"));
|
||||
reload_services(True);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
load a netbios hosts file
|
||||
****************************************************************************/
|
||||
static void load_hosts_file(char *fname)
|
||||
{
|
||||
FILE *f = fopen(fname,"r");
|
||||
pstring line;
|
||||
if (!f) {
|
||||
DEBUG(2,("Can't open lmhosts file %s\n",fname));
|
||||
return;
|
||||
}
|
||||
|
||||
while (!feof(f))
|
||||
{
|
||||
if (!fgets_slash(line,sizeof(pstring),f)) continue;
|
||||
|
||||
if (*line == '#') continue;
|
||||
|
||||
{
|
||||
BOOL group=False;
|
||||
|
||||
pstring ip,name,mask,flags,extra;
|
||||
|
||||
char *ptr;
|
||||
int count = 0;
|
||||
struct in_addr ipaddr;
|
||||
struct in_addr ipmask;
|
||||
enum name_source source = LMHOSTS;
|
||||
|
||||
strcpy(ip,"");
|
||||
strcpy(name,"");
|
||||
strcpy(mask,"");
|
||||
strcpy(flags,"");
|
||||
strcpy(extra,"");
|
||||
|
||||
ptr = line;
|
||||
|
||||
if (next_token(&ptr,ip ,NULL)) ++count;
|
||||
if (next_token(&ptr,name ,NULL)) ++count;
|
||||
if (next_token(&ptr,mask ,NULL)) ++count;
|
||||
if (next_token(&ptr,flags,NULL)) ++count;
|
||||
if (next_token(&ptr,extra,NULL)) ++count;
|
||||
|
||||
if (count <= 0) continue;
|
||||
|
||||
if (count > 0 && count < 2) {
|
||||
DEBUG(0,("Ill formed hosts line [%s]\n",line));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* work out if we need to shuffle the tokens along due to the
|
||||
optional subnet mask argument */
|
||||
|
||||
if (strchr(mask, 'G') || strchr(mask, 'S') || strchr(mask, 'M')) {
|
||||
strcpy(flags, mask );
|
||||
/* default action for no subnet mask */
|
||||
strcpy(mask, inet_ntoa(Netmask));
|
||||
}
|
||||
|
||||
DEBUG(4, ("lmhost entry: %s %s %s %s\n", ip, name, mask, flags));
|
||||
|
||||
if (strchr(flags,'G') || strchr(flags,'S'))
|
||||
group = True;
|
||||
|
||||
if (strchr(flags,'M') && !group) {
|
||||
source = SELF;
|
||||
strcpy(myname,name);
|
||||
}
|
||||
|
||||
ipaddr = *interpret_addr2(ip);
|
||||
ipmask = *interpret_addr2(mask);
|
||||
|
||||
if (group) {
|
||||
add_domain_entry(ipaddr, ipmask, name, True);
|
||||
} else {
|
||||
add_netbios_entry(name,0x20,NB_ACTIVE,0,source,ipaddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
The main select loop.
|
||||
***************************************************************************/
|
||||
static void process(void)
|
||||
{
|
||||
BOOL run_election;
|
||||
|
||||
while (True)
|
||||
{
|
||||
run_election = check_elections();
|
||||
listen_for_packets(run_election);
|
||||
|
||||
run_packet_queue();
|
||||
run_elections();
|
||||
|
||||
announce_host();
|
||||
announce_backup();
|
||||
announce_master();
|
||||
|
||||
expire_names_and_servers();
|
||||
expire_netbios_response_entries(time(NULL)-10);
|
||||
|
||||
write_browse_list();
|
||||
do_browser_lists();
|
||||
check_master_browser();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
open the socket communication
|
||||
****************************************************************************/
|
||||
static BOOL open_sockets(BOOL isdaemon, int port)
|
||||
{
|
||||
struct hostent *hp;
|
||||
|
||||
/* get host info */
|
||||
if ((hp = Get_Hostbyname(myhostname)) == 0) {
|
||||
DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (isdaemon)
|
||||
ClientNMB = open_socket_in(SOCK_DGRAM, port,0);
|
||||
else
|
||||
ClientNMB = 0;
|
||||
|
||||
ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3);
|
||||
|
||||
if (ClientNMB == -1)
|
||||
return(False);
|
||||
|
||||
signal(SIGPIPE, SIGNAL_CAST sig_pipe);
|
||||
|
||||
set_socket_options(ClientNMB,"SO_BROADCAST");
|
||||
set_socket_options(ClientDGRAM,"SO_BROADCAST");
|
||||
|
||||
DEBUG(3,("Sockets opened.\n"));
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
check that a IP, bcast and netmask and consistent. Must be a 1s
|
||||
broadcast
|
||||
******************************************************************/
|
||||
static BOOL ip_consistent(struct in_addr ip,struct in_addr bcast, struct in_addr nmask)
|
||||
{
|
||||
unsigned long a_ip,a_bcast,a_nmask;
|
||||
|
||||
a_ip = ntohl(ip.s_addr);
|
||||
a_bcast = ntohl(bcast.s_addr);
|
||||
a_nmask = ntohl(nmask.s_addr);
|
||||
|
||||
/* check the netmask is sane */
|
||||
if (((a_nmask>>24)&0xFF) != 0xFF) {
|
||||
DEBUG(0,("Insane netmask %s\n",inet_ntoa(nmask)));
|
||||
return(False);
|
||||
}
|
||||
|
||||
/* check the IP and bcast are on the same net */
|
||||
if ((a_ip&a_nmask) != (a_bcast&a_nmask)) {
|
||||
DEBUG(0,("IP and broadcast are on different nets!\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
/* check the IP and bcast are on the same net */
|
||||
if ((a_bcast|a_nmask) != 0xFFFFFFFF) {
|
||||
DEBUG(0,("Not a ones based broadcast %s\n",inet_ntoa(bcast)));
|
||||
return(False);
|
||||
}
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
initialise connect, service and file structs
|
||||
****************************************************************************/
|
||||
static BOOL init_structs()
|
||||
{
|
||||
if (!get_myname(myhostname,got_myip?NULL:&myip))
|
||||
return(False);
|
||||
|
||||
/* Read the broadcast address from the interface */
|
||||
{
|
||||
struct in_addr ip0,ip1,ip2;
|
||||
|
||||
ip0 = myip;
|
||||
|
||||
if (!(got_bcast && got_nmask))
|
||||
{
|
||||
get_broadcast(&ip0,&ip1,&ip2);
|
||||
|
||||
if (!got_myip)
|
||||
myip = ip0;
|
||||
|
||||
if (!got_bcast)
|
||||
bcast_ip = ip1;
|
||||
|
||||
if (!got_nmask)
|
||||
Netmask = ip2;
|
||||
}
|
||||
|
||||
DEBUG(1,("Using IP %s ",inet_ntoa(myip)));
|
||||
DEBUG(1,("broadcast %s ",inet_ntoa(bcast_ip)));
|
||||
DEBUG(1,("netmask %s\n",inet_ntoa(Netmask)));
|
||||
|
||||
if (!ip_consistent(myip,bcast_ip,Netmask)) {
|
||||
DEBUG(0,("WARNING: The IP address, broadcast and Netmask are not consistent\n"));
|
||||
DEBUG(0,("You are likely to experience problems with this setup!\n"));
|
||||
}
|
||||
}
|
||||
|
||||
if (! *myname) {
|
||||
char *p;
|
||||
strcpy(myname,myhostname);
|
||||
p = strchr(myname,'.');
|
||||
if (p) *p = 0;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
usage on the program
|
||||
****************************************************************************/
|
||||
static void usage(char *pname)
|
||||
{
|
||||
DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
|
||||
|
||||
printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
|
||||
printf("Version %s\n",VERSION);
|
||||
printf("\t-D become a daemon\n");
|
||||
printf("\t-p port listen on the specified port\n");
|
||||
printf("\t-d debuglevel set the debuglevel\n");
|
||||
printf("\t-l log basename. Basename for log/debug files\n");
|
||||
printf("\t-n netbiosname. the netbios name to advertise for this host\n");
|
||||
printf("\t-B broadcast address the address to use for broadcasts\n");
|
||||
printf("\t-N netmask the netmask to use for subnet determination\n");
|
||||
printf("\t-H hosts file load a netbios hosts file\n");
|
||||
printf("\t-G group name add a group name to be part of\n");
|
||||
printf("\t-I ip-address override the IP address\n");
|
||||
printf("\t-C comment sets the machine comment that appears in browse lists\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
main program
|
||||
**************************************************************************/
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int port = NMB_PORT;
|
||||
int opt;
|
||||
extern FILE *dbf;
|
||||
extern char *optarg;
|
||||
|
||||
*host_file = 0;
|
||||
|
||||
StartupTime = time(NULL);
|
||||
|
||||
TimeInit();
|
||||
|
||||
strcpy(debugf,NMBLOGFILE);
|
||||
|
||||
setup_logging(argv[0],False);
|
||||
|
||||
charset_initialise();
|
||||
|
||||
ipzero = *interpret_addr2("0.0.0.0");
|
||||
|
||||
#ifdef LMHOSTSFILE
|
||||
strcpy(host_file,LMHOSTSFILE);
|
||||
#endif
|
||||
|
||||
/* this is for people who can't start the program correctly */
|
||||
while (argc > 1 && (*argv[1] != '-')) {
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
|
||||
fault_setup(fault_continue);
|
||||
|
||||
signal(SIGHUP,SIGNAL_CAST sig_hup);
|
||||
|
||||
bcast_ip = ipzero;
|
||||
myip = ipzero;
|
||||
|
||||
while ((opt = getopt (argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 's':
|
||||
strcpy(servicesf,optarg);
|
||||
break;
|
||||
case 'C':
|
||||
strcpy(ServerComment,optarg);
|
||||
break;
|
||||
case 'G':
|
||||
if (got_bcast && got_nmask) {
|
||||
add_domain_entry(bcast_ip,Netmask,optarg, True);
|
||||
} else {
|
||||
DEBUG(0, ("Warning: option -G %s added before broadcast and netmask.\n",
|
||||
optarg));
|
||||
DEBUG(0, ("Assuming default values: bcast %s netmask %s\n",
|
||||
inet_ntoa(bcast_ip), inet_ntoa(Netmask))); /* (i hope) */
|
||||
}
|
||||
break;
|
||||
case 'H':
|
||||
strcpy(host_file,optarg);
|
||||
break;
|
||||
case 'I':
|
||||
myip = *interpret_addr2(optarg);
|
||||
got_myip = True;
|
||||
break;
|
||||
case 'B':
|
||||
bcast_ip = *interpret_addr2(optarg);
|
||||
got_bcast = True;
|
||||
break;
|
||||
case 'N':
|
||||
Netmask = *interpret_addr2(optarg);
|
||||
got_nmask = True;
|
||||
break;
|
||||
case 'n':
|
||||
strcpy(myname,optarg);
|
||||
break;
|
||||
case 'l':
|
||||
sprintf(debugf,"%s.nmb",optarg);
|
||||
break;
|
||||
case 'i':
|
||||
strcpy(scope,optarg);
|
||||
strupper(scope);
|
||||
break;
|
||||
case 'D':
|
||||
is_daemon = True;
|
||||
break;
|
||||
case 'd':
|
||||
DEBUGLEVEL = atoi(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
if (!is_a_socket(0)) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
|
||||
DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
|
||||
|
||||
init_structs();
|
||||
|
||||
if (!reload_services(False))
|
||||
return(-1);
|
||||
|
||||
if (!is_daemon && !is_a_socket(0)) {
|
||||
DEBUG(0,("standard input is not a socket, assuming -D option\n"));
|
||||
is_daemon = True;
|
||||
}
|
||||
|
||||
if (is_daemon) {
|
||||
DEBUG(2,("%s becoming a daemon\n",timestring()));
|
||||
become_daemon();
|
||||
}
|
||||
|
||||
DEBUG(3,("Opening sockets %d\n", port));
|
||||
|
||||
if (!open_sockets(is_daemon,port)) return 1;
|
||||
|
||||
if (*host_file) {
|
||||
load_hosts_file(host_file);
|
||||
DEBUG(3,("Loaded hosts file\n"));
|
||||
}
|
||||
|
||||
if (!*ServerComment)
|
||||
strcpy(ServerComment,"Samba %v");
|
||||
string_sub(ServerComment,"%v",VERSION);
|
||||
string_sub(ServerComment,"%h",myhostname);
|
||||
|
||||
add_my_names();
|
||||
add_my_domains();
|
||||
|
||||
DEBUG(3,("Checked names\n"));
|
||||
|
||||
write_browse_list();
|
||||
|
||||
DEBUG(3,("Dumped names\n"));
|
||||
|
||||
process();
|
||||
close_sockets();
|
||||
|
||||
if (dbf)
|
||||
fclose(dbf);
|
||||
return(0);
|
||||
}
|
@ -22,282 +22,162 @@
|
||||
|
||||
#include "includes.h"
|
||||
#include "loadparm.h"
|
||||
#include "nameserv.h"
|
||||
#include "localnet.h"
|
||||
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
struct server_record *add_server_entry(char *name,int servertype,
|
||||
int ttl,char *comment,BOOL replace);
|
||||
extern pstring myname;
|
||||
extern struct in_addr bcast_ip;
|
||||
extern struct in_addr Netmask;
|
||||
|
||||
extern int name_type;
|
||||
extern int max_protocol;
|
||||
extern struct in_addr dest_ip;
|
||||
extern int pid;
|
||||
extern int gid;
|
||||
extern int uid;
|
||||
extern int mid;
|
||||
extern BOOL got_pass;
|
||||
extern BOOL have_ip;
|
||||
extern pstring workgroup;
|
||||
extern pstring service;
|
||||
extern pstring desthost;
|
||||
extern BOOL connect_as_ipc;
|
||||
|
||||
/****************************************************************************
|
||||
call a remote api
|
||||
fudge for getpass function
|
||||
****************************************************************************/
|
||||
static BOOL call_remote_api(int fd,int cnum,int uid,int timeout,
|
||||
char *inbuf,char *outbuf,
|
||||
int prcnt,int drcnt,
|
||||
int mprcnt,int mdrcnt,
|
||||
int *rprcnt,int *rdrcnt,
|
||||
char *param,char *data,
|
||||
char **rparam,char **rdata)
|
||||
char *getsmbpass(char *pass)
|
||||
{
|
||||
char *p1,*p2;
|
||||
return "dummy"; /* return anything: it should be ignored anyway */
|
||||
}
|
||||
|
||||
/* send a SMBtrans command */
|
||||
bzero(outbuf,smb_size);
|
||||
set_message(outbuf,14,0,True);
|
||||
CVAL(outbuf,smb_com) = SMBtrans;
|
||||
SSVAL(outbuf,smb_tid,cnum);
|
||||
SSVAL(outbuf,smb_uid,uid);
|
||||
/****************************************************************************
|
||||
adds information retrieved from a NetServerEnum call
|
||||
****************************************************************************/
|
||||
static BOOL add_info(struct domain_record *d, struct work_record *work, int servertype)
|
||||
{
|
||||
char *rparam = NULL;
|
||||
char *rdata = NULL;
|
||||
int rdrcnt,rprcnt;
|
||||
char *p;
|
||||
pstring param;
|
||||
int uLevel = 1;
|
||||
int count = -1;
|
||||
|
||||
p1 = smb_buf(outbuf);
|
||||
strcpy(p1,"\\PIPE\\LANMAN");
|
||||
p1 = skip_string(p1,1);
|
||||
p2 = p1 + prcnt;
|
||||
/* now send a SMBtrans command with api ServerEnum? */
|
||||
p = param;
|
||||
SSVAL(p,0,0x68); /* api number */
|
||||
p += 2;
|
||||
strcpy(p,"WrLehDz");
|
||||
p = skip_string(p,1);
|
||||
|
||||
if (prcnt > 0)
|
||||
memcpy(p1,param,prcnt);
|
||||
if (drcnt > 0)
|
||||
memcpy(p2,data,drcnt);
|
||||
strcpy(p,"B16BBDz");
|
||||
|
||||
SSVAL(outbuf,smb_vwv0,prcnt); /* param count */
|
||||
SSVAL(outbuf,smb_vwv1,drcnt); /* data count */
|
||||
SSVAL(outbuf,smb_vwv2,mprcnt); /* mprcnt */
|
||||
SSVAL(outbuf,smb_vwv3,mdrcnt); /* mdrcnt */
|
||||
SSVAL(outbuf,smb_vwv4,0); /* msrcnt */
|
||||
SSVAL(outbuf,smb_vwv5,0); /* flags */
|
||||
SSVAL(outbuf,smb_vwv9,prcnt); /* pscnt */
|
||||
SSVAL(outbuf,smb_vwv10,smb_offset(p1,outbuf)); /* psoff */
|
||||
SSVAL(outbuf,smb_vwv11,drcnt); /* dscnt */
|
||||
SSVAL(outbuf,smb_vwv12,smb_offset(p2,outbuf)); /* dsoff */
|
||||
CVAL(outbuf,smb_vwv13) = 0; /* suwcnt */
|
||||
p = skip_string(p,1);
|
||||
SSVAL(p,0,uLevel);
|
||||
SSVAL(p,2,0x2000); /* buf length */
|
||||
p += 4;
|
||||
SIVAL(p,0,servertype);
|
||||
p += 4;
|
||||
|
||||
set_message(outbuf,14,PTR_DIFF(p2+drcnt,smb_buf(outbuf)),False);
|
||||
strcpy(p, work->work_group);
|
||||
p = skip_string(p,1);
|
||||
|
||||
send_smb(fd,outbuf);
|
||||
|
||||
if (receive_smb(fd,inbuf,timeout) &&
|
||||
CVAL(inbuf,smb_rcls) == 0)
|
||||
{
|
||||
if (rparam)
|
||||
*rparam = inbuf+4 + SVAL(inbuf,smb_vwv4);
|
||||
if (rdata)
|
||||
*rdata = inbuf+4 + SVAL(inbuf,smb_vwv7);
|
||||
if (rprcnt)
|
||||
*rprcnt = SVAL(inbuf,smb_vwv3);
|
||||
if (rdrcnt)
|
||||
*rdrcnt = SVAL(inbuf,smb_vwv6);
|
||||
return(True);
|
||||
}
|
||||
if (cli_call_api(PTR_DIFF(p,param),0, 8,10000,
|
||||
&rprcnt,&rdrcnt, param,NULL,
|
||||
&rparam,&rdata))
|
||||
{
|
||||
int res = SVAL(rparam,0);
|
||||
int converter=SVAL(rparam,2);
|
||||
int i;
|
||||
|
||||
return(False);
|
||||
if (res == 0)
|
||||
{
|
||||
count=SVAL(rparam,4);
|
||||
p = rdata;
|
||||
|
||||
for (i = 0;i < count;i++, p += 26)
|
||||
{
|
||||
char *sname = p;
|
||||
uint32 stype = IVAL(p,18);
|
||||
int comment_offset = IVAL(p,22) & 0xFFFF;
|
||||
char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
|
||||
|
||||
struct work_record *w = work;
|
||||
|
||||
DEBUG(4, ("\t%-16.16s %08x %s\n", sname, stype, cmnt));
|
||||
|
||||
if (stype & SV_TYPE_DOMAIN_ENUM)
|
||||
{
|
||||
/* creates workgroup on remote subnet */
|
||||
if ((w = find_workgroupstruct(d,sname, False)))
|
||||
{
|
||||
if (ip_equal(bcast_ip, d->bcast_ip))
|
||||
{
|
||||
announce_request(w, d->bcast_ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rparam) free(rparam);
|
||||
if (rdata) free(rdata);
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
synchronise browse lists with another browse server
|
||||
synchronise browse lists with another browse server.
|
||||
|
||||
log in on the remote server's SMB port to their IPC$ service,
|
||||
do a NetServerEnum and update our server and workgroup databases.
|
||||
******************************************************************/
|
||||
void sync_browse_lists(char *name,int name_type,char *myname,
|
||||
char *domain,struct in_addr ip)
|
||||
void sync_browse_lists(struct work_record *work, char *name, int nm_type,
|
||||
struct in_addr ip)
|
||||
{
|
||||
char *protocol = "LM1.2X002";
|
||||
char *service = "IPC$";
|
||||
char *dev = "IPC";
|
||||
int timeout=2000;
|
||||
char *inbuf=NULL;
|
||||
pstring outbuf;
|
||||
char *p;
|
||||
int len;
|
||||
uint32 sesskey;
|
||||
int cnum,uid;
|
||||
BOOL ret;
|
||||
struct domain_record *d;
|
||||
pid = getpid();
|
||||
uid = getuid();
|
||||
gid = getgid();
|
||||
mid = pid + 100;
|
||||
name_type = nm_type;
|
||||
|
||||
int fd = open_socket_out(SOCK_STREAM, &ip, SMB_PORT);
|
||||
if (fd < 0) {
|
||||
DEBUG(3,("Failed to connect to %s at %s\n",name,inet_ntoa(ip)));
|
||||
return;
|
||||
}
|
||||
got_pass = True;
|
||||
|
||||
if (!(inbuf = (char *)malloc(0xFFFF+1024))) return;
|
||||
DEBUG(4, ("sync browse lists with %s for %s %s\n",
|
||||
work->work_group, name, inet_ntoa(ip)));
|
||||
|
||||
/* put in the destination name */
|
||||
len = 4;
|
||||
p = outbuf+len;
|
||||
name_mangle(name,p,name_type);
|
||||
len += name_len(p);
|
||||
strcpy(workgroup,work->work_group);
|
||||
strcpy(desthost,name);
|
||||
dest_ip = ip;
|
||||
|
||||
/* and my name */
|
||||
p = outbuf+len;
|
||||
name_mangle(myname,p,0x20);
|
||||
len += name_len(p);
|
||||
if (zero_ip(dest_ip)) return;
|
||||
have_ip = True;
|
||||
|
||||
_smb_setlen(outbuf,len);
|
||||
CVAL(outbuf,0) = 0x81;
|
||||
if (!(d = find_domain(ip))) return;
|
||||
|
||||
send_smb(fd,outbuf);
|
||||
receive_smb(fd,inbuf,5000);
|
||||
|
||||
bzero(outbuf,smb_size);
|
||||
connect_as_ipc = True;
|
||||
|
||||
/* setup the protocol string */
|
||||
set_message(outbuf,0,strlen(protocol)+2,True);
|
||||
p = smb_buf(outbuf);
|
||||
*p++ = 2;
|
||||
strcpy(p,protocol);
|
||||
/* connect as server and get domains, then servers */
|
||||
|
||||
CVAL(outbuf,smb_com) = SMBnegprot;
|
||||
CVAL(outbuf,smb_flg) = 0x8;
|
||||
SSVAL(outbuf,smb_flg2,0x1);
|
||||
sprintf(service,"\\\\%s\\IPC$", name);
|
||||
strupper(service);
|
||||
|
||||
send_smb(fd,outbuf);
|
||||
bzero(inbuf,smb_size);
|
||||
ret = receive_smb(fd,inbuf,timeout);
|
||||
|
||||
if (!ret || CVAL(inbuf,smb_rcls) || SVAL(inbuf,smb_vwv0)) {
|
||||
DEBUG(3,("%s rejected the protocol\n",name));
|
||||
close(fd);
|
||||
if (inbuf) free(inbuf);
|
||||
return;
|
||||
}
|
||||
if (cli_open_sockets(SMB_PORT))
|
||||
{
|
||||
if (cli_send_login(NULL,NULL,True,True))
|
||||
{
|
||||
add_info(d, work, SV_TYPE_DOMAIN_ENUM);
|
||||
add_info(d, work, SV_TYPE_ALL&~SV_TYPE_DOMAIN_ENUM);
|
||||
}
|
||||
|
||||
sesskey = IVAL(inbuf,smb_vwv6);
|
||||
|
||||
bzero(outbuf,smb_size);
|
||||
set_message(outbuf,10,2,True);
|
||||
CVAL(outbuf,smb_com) = SMBsesssetupX;
|
||||
|
||||
CVAL(outbuf,smb_vwv0) = 0xFF;
|
||||
SSVAL(outbuf,smb_vwv2,0xFFFF);
|
||||
SSVAL(outbuf,smb_vwv3,2);
|
||||
SSVAL(outbuf,smb_vwv4,1);
|
||||
SIVAL(outbuf,smb_vwv5,sesskey);
|
||||
SSVAL(outbuf,smb_vwv7,1);
|
||||
|
||||
send_smb(fd,outbuf);
|
||||
bzero(inbuf,smb_size);
|
||||
ret = receive_smb(fd,inbuf,timeout);
|
||||
if (!ret || CVAL(inbuf,smb_rcls)) {
|
||||
DEBUG(3,("%s rejected session setup\n",name));
|
||||
close(fd);
|
||||
if (inbuf) free(inbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
uid = SVAL(inbuf,smb_uid);
|
||||
|
||||
bzero(outbuf,smb_size);
|
||||
set_message(outbuf,4,2 + (2 + strlen(name) + 1 + strlen(service)) +
|
||||
1 + strlen(dev),True);
|
||||
CVAL(outbuf,smb_com) = SMBtconX;
|
||||
SSVAL(outbuf,smb_uid,uid);
|
||||
|
||||
SSVAL(outbuf,smb_vwv0,0xFF);
|
||||
SSVAL(outbuf,smb_vwv3,1);
|
||||
|
||||
p = smb_buf(outbuf) + 1;
|
||||
strcpy(p, "\\\\");
|
||||
strcat(p, name);
|
||||
strcat(p, "\\");
|
||||
strcat(p,service);
|
||||
p = skip_string(p,1);
|
||||
strcpy(p,dev);
|
||||
|
||||
send_smb(fd,outbuf);
|
||||
bzero(inbuf,smb_size);
|
||||
ret = receive_smb(fd,inbuf,timeout);
|
||||
if (!ret || CVAL(inbuf,smb_rcls)) {
|
||||
DEBUG(3,("%s rejected IPC connect (%d,%d)\n",name,
|
||||
CVAL(inbuf,smb_rcls),SVAL(inbuf,smb_err)));
|
||||
close(fd);
|
||||
if (inbuf) free(inbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
cnum = SVAL(inbuf,smb_tid);
|
||||
|
||||
/* now I need to send a NetServerEnum */
|
||||
{
|
||||
fstring param;
|
||||
uint32 *typep;
|
||||
char *rparam,*rdata;
|
||||
|
||||
p = param;
|
||||
SSVAL(p,0,0x68); /* api number */
|
||||
p += 2;
|
||||
strcpy(p,"WrLehDz");
|
||||
p = skip_string(p,1);
|
||||
|
||||
strcpy(p,"B16BBDz");
|
||||
|
||||
p = skip_string(p,1);
|
||||
SSVAL(p,0,1); /* level 1 */
|
||||
SSVAL(p,2,0xFFFF - 500); /* buf length */
|
||||
p += 4;
|
||||
typep = (uint32 *)p;
|
||||
p += 4;
|
||||
strcpy(p,domain);
|
||||
strupper(p);
|
||||
p = skip_string(p,1);
|
||||
|
||||
SIVAL(typep,0,0x80000000); /* domain list */
|
||||
|
||||
if (call_remote_api(fd,cnum,uid,timeout,inbuf,outbuf,
|
||||
PTR_DIFF(p,param),0,
|
||||
8,0xFFFF - 500,
|
||||
NULL,NULL,
|
||||
param,NULL,
|
||||
&rparam,&rdata) && SVAL(rparam,0)==0)
|
||||
{
|
||||
int converter=SVAL(rparam,2);
|
||||
int count=SVAL(rparam,4);
|
||||
int i;
|
||||
char *p2 = rdata;
|
||||
for (i=0;i<count;i++) {
|
||||
char *sname = p2;
|
||||
uint32 type = IVAL(p2,18);
|
||||
int comment_offset = IVAL(p2,22) & 0xFFFF;
|
||||
char *comment = comment_offset?(rdata+comment_offset-converter):"";
|
||||
|
||||
add_server_entry(sname,type,lp_max_ttl(),comment,False);
|
||||
p2 += 26;
|
||||
}
|
||||
}
|
||||
|
||||
SIVAL(typep,0,0xFFFFFFFF); /* server list */
|
||||
|
||||
if (call_remote_api(fd,cnum,uid,timeout,inbuf,outbuf,
|
||||
PTR_DIFF(p,param),0,
|
||||
8,0xFFFF - 500,
|
||||
NULL,NULL,
|
||||
param,NULL,
|
||||
&rparam,&rdata) && SVAL(rparam,0)==0)
|
||||
{
|
||||
int converter=SVAL(rparam,2);
|
||||
int count=SVAL(rparam,4);
|
||||
int i;
|
||||
|
||||
p = rdata;
|
||||
for (i=0;i<count;i++) {
|
||||
char *sname = p;
|
||||
uint32 type = IVAL(p,18);
|
||||
int comment_offset = IVAL(p,22) & 0xFFFF;
|
||||
char *comment = comment_offset?(rdata+comment_offset-converter):"";
|
||||
|
||||
add_server_entry(sname,type,lp_max_ttl(),comment,False);
|
||||
p += 26;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* close up */
|
||||
bzero(outbuf,smb_size);
|
||||
set_message(outbuf,0,0,True);
|
||||
CVAL(outbuf,smb_com) = SMBtdis;
|
||||
SSVAL(outbuf,smb_uid,uid);
|
||||
SSVAL(outbuf,smb_tid,cnum);
|
||||
send_smb(fd,outbuf);
|
||||
receive_smb(fd,inbuf,1000);
|
||||
|
||||
close(fd);
|
||||
if (inbuf) free(inbuf);
|
||||
close_sockets();
|
||||
}
|
||||
}
|
||||
|
@ -131,8 +131,8 @@ typedef struct
|
||||
char *szUsernameMap;
|
||||
char *szCharacterSet;
|
||||
char *szLogonScript;
|
||||
char *szWINSserver;
|
||||
char *szSmbrun;
|
||||
char *szWINSserver;
|
||||
int max_log_size;
|
||||
int mangled_stack;
|
||||
int max_xmit;
|
||||
@ -148,6 +148,7 @@ typedef struct
|
||||
int syslog;
|
||||
int os_level;
|
||||
int max_ttl;
|
||||
BOOL bWINSsupport;
|
||||
BOOL bPreferredMaster;
|
||||
BOOL bDomainMaster;
|
||||
BOOL bDomainLogons;
|
||||
@ -396,7 +397,6 @@ struct parm_struct
|
||||
{"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL},
|
||||
{"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set},
|
||||
{"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL},
|
||||
{"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
|
||||
{"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL},
|
||||
{"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL},
|
||||
{"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL},
|
||||
@ -413,6 +413,8 @@ struct parm_struct
|
||||
#endif /* KANJI */
|
||||
{"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL},
|
||||
{"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL},
|
||||
{"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL},
|
||||
{"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
|
||||
{"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
|
||||
{"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
|
||||
{"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL},
|
||||
@ -577,6 +579,7 @@ static void init_globals(void)
|
||||
Globals.bDomainLogons = False;
|
||||
Globals.bBrowseList = True;
|
||||
Globals.bProxyNameResolution = True;
|
||||
Globals.bWINSsupport = True;
|
||||
|
||||
#ifdef KANJI
|
||||
coding_system = interpret_coding_system (KANJI, SJIS_CODE);
|
||||
@ -702,6 +705,7 @@ FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
|
||||
FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
|
||||
FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
|
||||
|
||||
FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
|
||||
FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
|
||||
FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
|
||||
FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
|
||||
|
@ -63,23 +63,74 @@ the other = 3
|
||||
static char *pszParmFile = NULL;
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
/* local prototypes */
|
||||
static BOOL enumerate_parameters(FILE *infile, PM_PARMFUNC pfunc);
|
||||
static BOOL enumerate_sections(FILE *infile,
|
||||
PM_SECFUNC sfunc, PM_PARMFUNC pfunc);
|
||||
|
||||
/* prototypes for local toolbox functions */
|
||||
static void trimleft(char *psz);
|
||||
static void trimright(char *psz);
|
||||
static void collapse_spaces(char *psz);
|
||||
static int firstnonwhite(char *psz);
|
||||
/**************************************************************************
|
||||
Strip all leading whitespace from a string.
|
||||
**************************************************************************/
|
||||
static void trimleft(char *psz)
|
||||
{
|
||||
char *pszDest;
|
||||
|
||||
pszDest = psz;
|
||||
if (psz != NULL)
|
||||
{
|
||||
while (*psz != '\0' && isspace(*psz))
|
||||
psz++;
|
||||
while (*psz != '\0')
|
||||
*pszDest++ = *psz++;
|
||||
*pszDest = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Strip all trailing whitespace from a string.
|
||||
**************************************************************************/
|
||||
static void trimright(char *psz)
|
||||
{
|
||||
char *pszTemp;
|
||||
|
||||
if (psz != NULL && psz[0] != '\0')
|
||||
{
|
||||
pszTemp = psz + strlen(psz) - 1;
|
||||
while (isspace(*pszTemp))
|
||||
*pszTemp-- = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Collapse each whitespace area in a string to a single space.
|
||||
***********************************************************************/
|
||||
static void collapse_spaces(char *psz)
|
||||
{
|
||||
while (*psz)
|
||||
if (isspace(*psz))
|
||||
{
|
||||
*psz++ = ' ';
|
||||
trimleft(psz);
|
||||
}
|
||||
else
|
||||
psz++;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Return the value of the first non-white character in the specified string.
|
||||
The terminating NUL counts as non-white for the purposes of this function.
|
||||
Note - no check for a NULL string! What would we return?
|
||||
**************************************************************************/
|
||||
static int firstnonwhite(char *psz)
|
||||
{
|
||||
while (isspace(*psz) && (*psz != '\0'))
|
||||
psz++;
|
||||
return (*psz);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
Identifies all parameters in the current section, calls the parameter
|
||||
function for each. Ignores comment lines, stops and backs up in file when
|
||||
a section is encountered. Returns True on success, False on error.
|
||||
**************************************************************************/
|
||||
static BOOL enumerate_parameters(FILE *fileIn, PM_PARMFUNC pfunc)
|
||||
static BOOL enumerate_parameters(FILE *fileIn, BOOL (*pfunc)(char *,char *))
|
||||
{
|
||||
pstring szBuf;
|
||||
char *pszTemp;
|
||||
@ -186,8 +237,8 @@ Returns True on success, False on failure. Note that the section and
|
||||
parameter names will have all internal whitespace areas collapsed to a
|
||||
single space for processing.
|
||||
**************************************************************************/
|
||||
static BOOL enumerate_sections(FILE *fileIn,
|
||||
PM_SECFUNC sfunc, PM_PARMFUNC pfunc)
|
||||
static BOOL enumerate_sections(FILE *fileIn,
|
||||
BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *))
|
||||
{
|
||||
pstring szBuf;
|
||||
BOOL bRetval;
|
||||
@ -246,7 +297,7 @@ Process the passed parameter file.
|
||||
|
||||
Returns True if successful, else False.
|
||||
**************************************************************************/
|
||||
BOOL pm_process(char *pszFileName, PM_SECFUNC sfunc, PM_PARMFUNC pfunc)
|
||||
BOOL pm_process(char *pszFileName,BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *))
|
||||
{
|
||||
FILE *fileIn;
|
||||
BOOL bRetval;
|
||||
@ -274,62 +325,3 @@ BOOL pm_process(char *pszFileName, PM_SECFUNC sfunc, PM_PARMFUNC pfunc)
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
Strip all leading whitespace from a string.
|
||||
**************************************************************************/
|
||||
static void trimleft(char *psz)
|
||||
{
|
||||
char *pszDest;
|
||||
|
||||
pszDest = psz;
|
||||
if (psz != NULL)
|
||||
{
|
||||
while (*psz != '\0' && isspace(*psz))
|
||||
psz++;
|
||||
while (*psz != '\0')
|
||||
*pszDest++ = *psz++;
|
||||
*pszDest = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Strip all trailing whitespace from a string.
|
||||
**************************************************************************/
|
||||
static void trimright(char *psz)
|
||||
{
|
||||
char *pszTemp;
|
||||
|
||||
if (psz != NULL && psz[0] != '\0')
|
||||
{
|
||||
pszTemp = psz + strlen(psz) - 1;
|
||||
while (isspace(*pszTemp))
|
||||
*pszTemp-- = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Collapse each whitespace area in a string to a single space.
|
||||
***********************************************************************/
|
||||
static void collapse_spaces(char *psz)
|
||||
{
|
||||
while (*psz)
|
||||
if (isspace(*psz))
|
||||
{
|
||||
*psz++ = ' ';
|
||||
trimleft(psz);
|
||||
}
|
||||
else
|
||||
psz++;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Return the value of the first non-white character in the specified string.
|
||||
The terminating NUL counts as non-white for the purposes of this function.
|
||||
Note - no check for a NULL string! What would we return?
|
||||
**************************************************************************/
|
||||
static int firstnonwhite(char *psz)
|
||||
{
|
||||
while (isspace(*psz) && (*psz != '\0'))
|
||||
psz++;
|
||||
return (*psz);
|
||||
}
|
||||
|
@ -32,14 +32,9 @@ Prototypes and definitions for PARAMS.C.
|
||||
#include <stdio.h>
|
||||
#include "smb.h"
|
||||
|
||||
typedef BOOL (* PM_PARMFUNC)(char *pszParmName, char *pszParmValue);
|
||||
typedef BOOL (* PM_SECFUNC)(char *pszSectionName);
|
||||
|
||||
#define PM_NOFILE 1
|
||||
#define PM_NOFILENAME 2
|
||||
#define PM_FILEERROR 3
|
||||
|
||||
extern BOOL pm_process(char *pszFileName, PM_SECFUNC sfunc, PM_PARMFUNC pfunc);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -297,8 +297,7 @@ get_smbpwnam(char *name)
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
void
|
||||
smbpass_dummy(void)
|
||||
void smbpass_dummy(void)
|
||||
{
|
||||
} /* To avoid compiler complaints */
|
||||
#endif
|
||||
|
39
source3/script/mkproto.awk
Normal file
39
source3/script/mkproto.awk
Normal file
@ -0,0 +1,39 @@
|
||||
# generate prototypes for Samba C code
|
||||
|
||||
|
||||
BEGIN {
|
||||
inheader=0;
|
||||
}
|
||||
|
||||
{
|
||||
if (inheader) {
|
||||
if (match($0,"[)][ \t]*$")) {
|
||||
inheader = 0;
|
||||
printf "%s;\n",$0;
|
||||
} else {
|
||||
printf "%s\n",$0;
|
||||
}
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
/^static|^extern/ || !/^[a-zA-Z]/ || /[;]/ {
|
||||
next;
|
||||
}
|
||||
|
||||
!/^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time/ {
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
/[(].*[)][ \t]*$/ {
|
||||
printf "%s;\n",$0;
|
||||
next;
|
||||
}
|
||||
|
||||
/[(]/ {
|
||||
inheader=1;
|
||||
printf "%s\n",$0;
|
||||
next;
|
||||
}
|
||||
|
@ -1258,7 +1258,7 @@ BOOL server_cryptkey(char *buf)
|
||||
fstring desthost;
|
||||
struct in_addr dest_ip;
|
||||
extern struct in_addr myip;
|
||||
int port = 139;
|
||||
int port = SMB_PORT;
|
||||
BOOL ret;
|
||||
|
||||
if (password_client >= 0)
|
||||
|
@ -1928,11 +1928,11 @@ int reply_close(char *inbuf,char *outbuf)
|
||||
|
||||
mtime = make_unix_date3(inbuf+smb_vwv1);
|
||||
|
||||
close_file(fnum);
|
||||
|
||||
/* try and set the date */
|
||||
set_filetime(Files[fnum].name,mtime);
|
||||
|
||||
close_file(fnum);
|
||||
|
||||
/* We have a cached error */
|
||||
if(eclass || err)
|
||||
return(ERROR(eclass,err));
|
||||
@ -1976,10 +1976,10 @@ int reply_writeclose(char *inbuf,char *outbuf)
|
||||
|
||||
nwritten = write_file(fnum,data,numtowrite);
|
||||
|
||||
close_file(fnum);
|
||||
|
||||
set_filetime(Files[fnum].name,mtime);
|
||||
|
||||
close_file(fnum);
|
||||
|
||||
DEBUG(3,("%s writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n",
|
||||
timestring(),fnum,cnum,numtowrite,nwritten,
|
||||
Connections[cnum].num_files_open));
|
||||
|
@ -139,31 +139,20 @@ mode_t unix_mode(int cnum,int dosmode)
|
||||
int dos_mode(int cnum,char *path,struct stat *sbuf)
|
||||
{
|
||||
int result = 0;
|
||||
extern struct current_user current_user;
|
||||
|
||||
#if OLD_DOS_MODE
|
||||
if (!CAN_WRITE(cnum) || !((sbuf->st_mode & S_IWOTH) ||
|
||||
Connections[cnum].admin_user ||
|
||||
((sbuf->st_mode & S_IWUSR) &&
|
||||
Connections[cnum].uid==sbuf->st_uid) ||
|
||||
((sbuf->st_mode & S_IWGRP) &&
|
||||
in_group(sbuf->st_gid,Connections[cnum].gid,
|
||||
Connections[cnum].ngroups,
|
||||
Connections[cnum].igroups))))
|
||||
result |= aRONLY;
|
||||
#else
|
||||
if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
|
||||
if (!((sbuf->st_mode & S_IWOTH) ||
|
||||
Connections[cnum].admin_user ||
|
||||
((sbuf->st_mode & S_IWUSR) && Connections[cnum].uid==sbuf->st_uid) ||
|
||||
((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
|
||||
((sbuf->st_mode & S_IWGRP) &&
|
||||
in_group(sbuf->st_gid,Connections[cnum].gid,
|
||||
Connections[cnum].ngroups,Connections[cnum].igroups))))
|
||||
in_group(sbuf->st_gid,current_user.gid,
|
||||
current_user.ngroups,current_user.igroups))))
|
||||
result |= aRONLY;
|
||||
} else {
|
||||
if ((sbuf->st_mode & S_IWUSR) == 0)
|
||||
result |= aRONLY;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((sbuf->st_mode & S_IXUSR) != 0)
|
||||
result |= aARCH;
|
||||
@ -3383,7 +3372,7 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
|
||||
/****************************************************************************
|
||||
process commands from the client
|
||||
****************************************************************************/
|
||||
void process(void )
|
||||
static void process(void)
|
||||
{
|
||||
static int trans_num = 0;
|
||||
int nread;
|
||||
@ -3407,7 +3396,7 @@ void process(void )
|
||||
ip = *interpret_addr2("localhost");
|
||||
if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
|
||||
*OutBuffer = 0;
|
||||
send_one_packet(OutBuffer,1,ip,137,SOCK_DGRAM);
|
||||
send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3592,7 +3581,7 @@ static void init_structs(void )
|
||||
/****************************************************************************
|
||||
usage on the program
|
||||
****************************************************************************/
|
||||
void usage(char *pname)
|
||||
static void usage(char *pname)
|
||||
{
|
||||
DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
|
||||
|
||||
@ -3612,12 +3601,12 @@ void usage(char *pname)
|
||||
/****************************************************************************
|
||||
main program
|
||||
****************************************************************************/
|
||||
int main(int argc,char *argv[])
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
extern BOOL append_log;
|
||||
/* shall I run as a daemon */
|
||||
BOOL is_daemon = False;
|
||||
int port = 139;
|
||||
int port = SMB_PORT;
|
||||
int opt;
|
||||
extern char *optarg;
|
||||
|
||||
|
@ -46,7 +46,7 @@ as non root from a program which is switching between root and non-root
|
||||
|
||||
It takes 3 arguments as uid,gid,command and runs command after
|
||||
becoming a non-root user */
|
||||
int main(int argc,char *argv[])
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int uid,gid;
|
||||
|
||||
|
@ -264,7 +264,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l
|
||||
int mode=0;
|
||||
uint32 size=0,len;
|
||||
uint32 mdate=0, adate=0, cdate=0;
|
||||
char *name_ptr;
|
||||
char *nameptr;
|
||||
BOOL isrootdir = (strequal(Connections[cnum].dirpath,"./") ||
|
||||
strequal(Connections[cnum].dirpath,".") ||
|
||||
strequal(Connections[cnum].dirpath,"/"));
|
||||
@ -349,7 +349,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l
|
||||
#endif
|
||||
|
||||
p = pdata;
|
||||
name_ptr = p;
|
||||
nameptr = p;
|
||||
|
||||
name_map_mangle(fname,False,SNUM(cnum));
|
||||
|
||||
@ -368,7 +368,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l
|
||||
SSVAL(p,l1_attrFile,mode);
|
||||
SCVAL(p,l1_cchName,strlen(fname));
|
||||
strcpy(p + l1_achName, fname);
|
||||
name_ptr = p + l1_achName;
|
||||
nameptr = p + l1_achName;
|
||||
p += l1_achName + strlen(fname) + 1;
|
||||
break;
|
||||
|
||||
@ -387,7 +387,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l
|
||||
SIVAL(p,l2_cbList,0); /* No extended attributes */
|
||||
SCVAL(p,l2_cchName,strlen(fname));
|
||||
strcpy(p + l2_achName, fname);
|
||||
name_ptr = p + l2_achName;
|
||||
nameptr = p + l2_achName;
|
||||
p += l2_achName + strlen(fname) + 1;
|
||||
break;
|
||||
|
||||
@ -402,7 +402,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l
|
||||
SIVAL(p,26,4);
|
||||
CVAL(p,30) = strlen(fname);
|
||||
strcpy(p+31, fname);
|
||||
name_ptr = p+31;
|
||||
nameptr = p+31;
|
||||
p += 31 + strlen(fname) + 1;
|
||||
break;
|
||||
|
||||
@ -420,7 +420,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l
|
||||
SSVAL(p,24,mode);
|
||||
CVAL(p,32) = strlen(fname);
|
||||
strcpy(p + 33, fname);
|
||||
name_ptr = p+33;
|
||||
nameptr = p+33;
|
||||
p += 33 + strlen(fname) + 1;
|
||||
break;
|
||||
|
||||
@ -452,7 +452,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l
|
||||
strupper(p+2);
|
||||
SSVAL(p,0,strlen(p+2));
|
||||
p += 2 + 24;
|
||||
/* name_ptr = p; */
|
||||
/* nameptr = p; */
|
||||
strcpy(p,fname); p += strlen(p);
|
||||
p = pdata + len;
|
||||
break;
|
||||
@ -517,7 +517,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l
|
||||
}
|
||||
|
||||
/* Setup the last_filename pointer, as an offset from base_data */
|
||||
*last_name_off = PTR_DIFF(name_ptr,base_data);
|
||||
*last_name_off = PTR_DIFF(nameptr,base_data);
|
||||
/* Advance the data pointer to the next slot */
|
||||
*ppdata = p;
|
||||
return(found);
|
||||
@ -1004,7 +1004,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length,
|
||||
|
||||
|
||||
if (tran_call == TRANSACT2_QFILEINFO) {
|
||||
int16 fnum = SVAL(params,0);
|
||||
int16 fnum = SVALS(params,0);
|
||||
info_level = SVAL(params,2);
|
||||
|
||||
CHECK_FNUM(fnum,cnum);
|
||||
@ -1198,7 +1198,7 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length,
|
||||
return(ERROR(ERRSRV,ERRaccess));
|
||||
|
||||
if (tran_call == TRANSACT2_SETFILEINFO) {
|
||||
int16 fnum = SVAL(params,0);
|
||||
int16 fnum = SVALS(params,0);
|
||||
info_level = SVAL(params,2);
|
||||
|
||||
CHECK_FNUM(fnum,cnum);
|
||||
|
@ -30,23 +30,18 @@ static int initial_uid;
|
||||
static int initial_gid;
|
||||
static int old_umask = 022;
|
||||
|
||||
int current_uid;
|
||||
int current_gid;
|
||||
|
||||
static pstring OriginalDir;
|
||||
|
||||
/* have I done a become_user? */
|
||||
static struct {
|
||||
int cnum, uid;
|
||||
} last_user;
|
||||
/* what user is current? */
|
||||
struct current_user current_user;
|
||||
|
||||
/****************************************************************************
|
||||
initialise the uid routines
|
||||
****************************************************************************/
|
||||
void init_uid(void)
|
||||
{
|
||||
initial_uid = current_uid = geteuid();
|
||||
initial_gid = current_gid = getegid();
|
||||
initial_uid = current_user.uid = geteuid();
|
||||
initial_gid = current_user.gid = getegid();
|
||||
|
||||
if (initial_gid != 0 && initial_uid == 0)
|
||||
{
|
||||
@ -61,7 +56,7 @@ void init_uid(void)
|
||||
initial_uid = geteuid();
|
||||
initial_gid = getegid();
|
||||
|
||||
last_user.cnum = -1;
|
||||
current_user.cnum = -1;
|
||||
|
||||
GetWd(OriginalDir);
|
||||
}
|
||||
@ -111,7 +106,7 @@ static BOOL become_uid(int uid)
|
||||
return(False);
|
||||
}
|
||||
|
||||
current_uid = uid;
|
||||
current_user.uid = uid;
|
||||
|
||||
return(True);
|
||||
}
|
||||
@ -140,7 +135,7 @@ static BOOL become_gid(int gid)
|
||||
return(False);
|
||||
}
|
||||
|
||||
current_gid = gid;
|
||||
current_user.gid = gid;
|
||||
|
||||
return(True);
|
||||
}
|
||||
@ -174,7 +169,7 @@ BOOL become_guest(void)
|
||||
if (!ret)
|
||||
DEBUG(1,("Failed to become guest. Invalid guest account?\n"));
|
||||
|
||||
last_user.cnum = -2;
|
||||
current_user.cnum = -2;
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@ -208,10 +203,9 @@ BOOL become_user(int cnum, int uid)
|
||||
int new_umask;
|
||||
user_struct *vuser;
|
||||
int snum,gid;
|
||||
int ngroups;
|
||||
gid_t *groups;
|
||||
int id = uid;
|
||||
|
||||
if (last_user.cnum == cnum && last_user.uid == uid) {
|
||||
if (current_user.cnum == cnum && current_user.id == id) {
|
||||
DEBUG(4,("Skipping become_user - already user\n"));
|
||||
return(True);
|
||||
}
|
||||
@ -231,8 +225,9 @@ BOOL become_user(int cnum, int uid)
|
||||
!check_user_ok(cnum,vuser,snum)) {
|
||||
uid = Connections[cnum].uid;
|
||||
gid = Connections[cnum].gid;
|
||||
groups = Connections[cnum].groups;
|
||||
ngroups = Connections[cnum].ngroups;
|
||||
current_user.groups = Connections[cnum].groups;
|
||||
current_user.igroups = Connections[cnum].igroups;
|
||||
current_user.ngroups = Connections[cnum].ngroups;
|
||||
} else {
|
||||
if (!vuser) {
|
||||
DEBUG(2,("Invalid vuid used %d\n",uid));
|
||||
@ -243,8 +238,9 @@ BOOL become_user(int cnum, int uid)
|
||||
gid = vuser->gid;
|
||||
else
|
||||
gid = Connections[cnum].gid;
|
||||
groups = vuser->user_groups;
|
||||
ngroups = vuser->user_ngroups;
|
||||
current_user.groups = vuser->user_groups;
|
||||
current_user.igroups = vuser->user_igroups;
|
||||
current_user.ngroups = vuser->user_ngroups;
|
||||
}
|
||||
|
||||
if (initial_uid == 0)
|
||||
@ -254,8 +250,8 @@ BOOL become_user(int cnum, int uid)
|
||||
#ifndef NO_SETGROUPS
|
||||
if (!IS_IPC(cnum)) {
|
||||
/* groups stuff added by ih/wreu */
|
||||
if (ngroups > 0)
|
||||
if (setgroups(ngroups,groups)<0)
|
||||
if (current_user.ngroups > 0)
|
||||
if (setgroups(current_user.ngroups,current_user.groups)<0)
|
||||
DEBUG(0,("setgroups call failed!\n"));
|
||||
}
|
||||
#endif
|
||||
@ -267,8 +263,8 @@ BOOL become_user(int cnum, int uid)
|
||||
new_umask = 0777 & ~CREATE_MODE(cnum);
|
||||
old_umask = umask(new_umask);
|
||||
|
||||
last_user.cnum = cnum;
|
||||
last_user.uid = uid;
|
||||
current_user.cnum = cnum;
|
||||
current_user.id = id;
|
||||
|
||||
DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d) new_umask=0%o\n",
|
||||
getuid(),geteuid(),getgid(),getegid(),new_umask));
|
||||
@ -281,7 +277,7 @@ BOOL become_user(int cnum, int uid)
|
||||
****************************************************************************/
|
||||
BOOL unbecome_user(void )
|
||||
{
|
||||
if (last_user.cnum == -1)
|
||||
if (current_user.cnum == -1)
|
||||
return(False);
|
||||
|
||||
ChDir(OriginalDir);
|
||||
@ -320,8 +316,8 @@ BOOL unbecome_user(void )
|
||||
}
|
||||
#endif
|
||||
|
||||
current_uid = initial_uid;
|
||||
current_gid = initial_gid;
|
||||
current_user.uid = initial_uid;
|
||||
current_user.gid = initial_gid;
|
||||
|
||||
if (ChDir(OriginalDir) != 0)
|
||||
DEBUG(0,("%s chdir(%s) failed in unbecome_user\n",
|
||||
@ -330,7 +326,7 @@ BOOL unbecome_user(void )
|
||||
DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
|
||||
getuid(),geteuid(),getgid(),getegid()));
|
||||
|
||||
last_user.cnum = -1;
|
||||
current_user.cnum = -1;
|
||||
|
||||
return(True);
|
||||
}
|
||||
@ -352,7 +348,7 @@ int smbrun(char *cmd,char *outfile)
|
||||
}
|
||||
|
||||
sprintf(syscmd,"%s %d %d \"(%s 2>&1) > %s\"",
|
||||
path,current_uid,current_gid,cmd,
|
||||
path,current_user.uid,current_user.gid,cmd,
|
||||
outfile?outfile:"/dev/null");
|
||||
|
||||
DEBUG(5,("smbrun - running %s ",syscmd));
|
||||
|
@ -60,8 +60,7 @@ int ms_type = MS_NONE,
|
||||
/*
|
||||
VT_Check: test incoming packet for "vtp" or "iVT1\0"
|
||||
*/
|
||||
int VT_Check(buffer)
|
||||
char *buffer;
|
||||
int VT_Check(char *buffer)
|
||||
{
|
||||
DEBUG(3,("Checking packet: <%10s...>\n", buffer+4));
|
||||
if((strncmp(buffer+4, "vtp", 3) == 0 && smb_len(buffer) == 3) || (strncmp(buffer+4, "iVT1\0", 5) == 0 && smb_len(buffer) == 5))
|
||||
@ -74,7 +73,7 @@ char *buffer;
|
||||
/*
|
||||
VT_Start_utmp: prepare /etc/utmp for /bin/login
|
||||
*/
|
||||
VT_Start_utmp()
|
||||
int VT_Start_utmp(void)
|
||||
{
|
||||
struct utmp u, *v;
|
||||
char *tt;
|
||||
@ -111,7 +110,7 @@ VT_Start_utmp()
|
||||
/*
|
||||
VT_Stop_utmp: prepare /etc/utmp for other processes
|
||||
*/
|
||||
VT_Stop_utmp()
|
||||
int VT_Stop_utmp(void)
|
||||
{
|
||||
struct utmp u, *v;
|
||||
|
||||
@ -138,7 +137,7 @@ VT_Stop_utmp()
|
||||
/*
|
||||
VT_AtExit: Things to do when the program exits
|
||||
*/
|
||||
void VT_AtExit()
|
||||
void VT_AtExit(void)
|
||||
{
|
||||
if(VT_ChildPID > 0) {
|
||||
kill(VT_ChildPID, SIGHUP);
|
||||
@ -152,8 +151,7 @@ void VT_AtExit()
|
||||
/*
|
||||
VT_SigCLD: signalhandler for SIGCLD: set flag if child-process died
|
||||
*/
|
||||
void VT_SigCLD(sig)
|
||||
int sig;
|
||||
void VT_SigCLD(int sig)
|
||||
{
|
||||
if(wait(NULL) == VT_ChildPID)
|
||||
VT_ChildDied = True;
|
||||
@ -165,8 +163,7 @@ int sig;
|
||||
/*
|
||||
VT_SigEXIT: signalhandler for signals that cause the process to exit
|
||||
*/
|
||||
void VT_SigEXIT(sig)
|
||||
int sig;
|
||||
void VT_SigEXIT(int sig)
|
||||
{
|
||||
VT_AtExit();
|
||||
|
||||
@ -177,7 +174,7 @@ int sig;
|
||||
/*
|
||||
VT_Start: initialize vt-specific data, alloc pty, spawn shell and send ACK
|
||||
*/
|
||||
int VT_Start()
|
||||
int VT_Start(void)
|
||||
{
|
||||
char OutBuf [64], *X, *Y;
|
||||
|
||||
@ -330,8 +327,7 @@ int VT_Start()
|
||||
/*
|
||||
VT_Output: transport data from socket to pty
|
||||
*/
|
||||
int VT_Output(Buffer)
|
||||
char *Buffer;
|
||||
int VT_Output(char *Buffer)
|
||||
{
|
||||
int i, len, nb;
|
||||
|
||||
@ -350,9 +346,7 @@ char *Buffer;
|
||||
/*
|
||||
VT_Input: transport data from pty to socket
|
||||
*/
|
||||
int VT_Input(Buffer, Size)
|
||||
char *Buffer;
|
||||
int Size;
|
||||
int VT_Input(char *Buffer,int Size)
|
||||
{
|
||||
int len;
|
||||
|
||||
@ -372,7 +366,7 @@ int Size;
|
||||
/*
|
||||
VT_Process: main loop while in vt-mode
|
||||
*/
|
||||
void VT_Process()
|
||||
void VT_Process(void)
|
||||
{
|
||||
static int trans_num = 0;
|
||||
extern int Client;
|
||||
|
@ -1,302 +0,0 @@
|
||||
/*
|
||||
USAGE
|
||||
sockspy desthost destservice
|
||||
|
||||
You install this program in /etc/inetd.conf and /etc/services
|
||||
|
||||
For example I have used these entries:
|
||||
|
||||
/etc/services:
|
||||
spy 8001/tcp spy port
|
||||
|
||||
/etc/inetd.conf:
|
||||
spy stream tcp nowait tridge /usr/local/smb/sockspy sockspy fjall netbios-ssn
|
||||
|
||||
This means any connection to port 8001 will be redirected to
|
||||
netbios-ssn on fjall. By playing with these parameters you can easily
|
||||
spy on most of the tcp protocols. All packets traversing the link will
|
||||
be captured.
|
||||
|
||||
NOTE: This program is totally unsupported. I haven't used it for 2
|
||||
years, and don't intend to fix the obvious bugs/limitations. I will,
|
||||
however, accept contributed patches - or even a total rewrite :-)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/dir.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sysexits.h>
|
||||
|
||||
int trans_num = 0;
|
||||
|
||||
#ifndef LOGIN
|
||||
#define LOGIN "/tmp/spy.in"
|
||||
#endif
|
||||
|
||||
#ifndef LOGOUT
|
||||
#define LOGOUT "/tmp/spy.out"
|
||||
#endif
|
||||
|
||||
#ifndef LOGCMD
|
||||
#define LOGCMD "/tmp/spy.cmd"
|
||||
#endif
|
||||
|
||||
FILE *cmd = NULL;
|
||||
FILE *login = NULL;
|
||||
FILE *logout = NULL;
|
||||
|
||||
#define STREQL(a, b) (strcmp(a, b) == 0)
|
||||
#define NIL (0)
|
||||
|
||||
char DestHost[256]; /* Remote system to connect to */
|
||||
char DestObj[256]; /* Remote object/service to connect to */
|
||||
|
||||
/* Signal handler for SIGPIPE (write on a disconnected socket) */
|
||||
abort()
|
||||
{
|
||||
if (cmd)
|
||||
{
|
||||
fprintf(cmd,"writing to disconnected socket!\n");
|
||||
fflush(cmd);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
main(argc, argv)
|
||||
int argc; /* # of command line arguments */
|
||||
char *argv[]; /* the command line arguments */
|
||||
{
|
||||
int client, /* Socket connected to client */
|
||||
server; /* Socket to use for server */
|
||||
|
||||
trans_num = 0;
|
||||
#ifndef NOLOG
|
||||
login = fopen(LOGIN,"w");
|
||||
logout = fopen(LOGOUT,"w");
|
||||
cmd = fopen(LOGCMD,"w");
|
||||
#endif
|
||||
|
||||
if (cmd)
|
||||
{
|
||||
fprintf(cmd,"Started server\n");
|
||||
fflush(cmd);
|
||||
}
|
||||
|
||||
/* Check usage */
|
||||
if(argc != 3)
|
||||
return;
|
||||
|
||||
strcpy(DestHost,argv[1]);
|
||||
strcpy(DestObj,argv[2]);
|
||||
|
||||
/* Time to attempt the connection */
|
||||
server = inet_conn(DestHost, DestObj);
|
||||
|
||||
if( server < 0 ) {
|
||||
exit(EX_CANTCREAT);
|
||||
}
|
||||
|
||||
/* Just to make the code more readable */
|
||||
client = 0;
|
||||
|
||||
/* We will abort gracefully when the client or remote system
|
||||
goes away */
|
||||
signal(SIGPIPE, abort);
|
||||
|
||||
/* Now just go and move raw data between client and
|
||||
remote system */
|
||||
dowork(client, server);
|
||||
/* ... NEVER RETURNS ... */
|
||||
}
|
||||
|
||||
dowork(client, server)
|
||||
int client, server;
|
||||
{
|
||||
|
||||
/* select(2) masks for client and remote */
|
||||
int ClientMask, ServerMask;
|
||||
|
||||
/* Combined ClientMask and ServerMask */
|
||||
int ReadMask;
|
||||
|
||||
/* Initialize select(2) masks */
|
||||
ClientMask = 1<<client;
|
||||
ServerMask = 1<<server;
|
||||
|
||||
ReadMask = ClientMask | ServerMask;
|
||||
|
||||
/* Now move raw data for the rest of our life between
|
||||
client and remote */
|
||||
for( ; ; ) {
|
||||
/* Local Variables */
|
||||
int SelectReadMask;/* select(2) mask modifiable by select(2) */
|
||||
int nready; /* status return from select(2) */
|
||||
|
||||
do {
|
||||
/* Intialize select(2) mask everytime
|
||||
as select(2) always modifies it */
|
||||
SelectReadMask = ReadMask;
|
||||
|
||||
/* Wait for data to be present to be moved */
|
||||
errno = 0;
|
||||
nready = select(32,&SelectReadMask,(int *)0,(int *)0,NIL);
|
||||
} while( nready < 0 && errno == EINTR );
|
||||
|
||||
/* select(2) failed, shouldn't happen. Exit abnormally */
|
||||
if( nready < 0 )
|
||||
exit(EX_SOFTWARE);
|
||||
|
||||
/* Favor the client (for no particular reason)
|
||||
if s/he is has data */
|
||||
if( SelectReadMask & ClientMask )
|
||||
{
|
||||
if (cmd)
|
||||
fprintf(cmd,"client %d\n",nready);
|
||||
xfer(client, server,login);
|
||||
}
|
||||
|
||||
/* Then check on the other guy */
|
||||
if( SelectReadMask & ServerMask )
|
||||
{
|
||||
if (cmd)
|
||||
fprintf(cmd,"server %d\n",nready);
|
||||
xfer(server, client,logout);
|
||||
}
|
||||
}
|
||||
|
||||
/* NEVER REACHED */
|
||||
}
|
||||
|
||||
#define BUFSIZE 20000 /* Max bytes to move at a time */
|
||||
|
||||
xfer(from, to,file)
|
||||
int from, to; /* Move data from "from" to "to" */
|
||||
FILE *file;
|
||||
{
|
||||
static char buf[BUFSIZE]; /* Buffer data to be moved */
|
||||
int nready; /* # bytes readable */
|
||||
int got; /* # bytes actually being moved */
|
||||
int ret;
|
||||
|
||||
/* Query the system how many bytes are ready to be read */
|
||||
ioctl(from, FIONREAD, &nready);
|
||||
|
||||
if (cmd)
|
||||
fprintf(cmd,"nready = %d\n",nready);
|
||||
|
||||
/* Only try to get the smaller of nready and BUFSIZE */
|
||||
got = read(from, buf, nready < BUFSIZE ? nready : BUFSIZE);
|
||||
|
||||
/* Zero bytes returned indicates end of stream, exit gracefully */
|
||||
if( got == 0 )
|
||||
{
|
||||
if (cmd)
|
||||
{
|
||||
fprintf(cmd,"read 0 bytes exiting\n");
|
||||
fflush(cmd);
|
||||
}
|
||||
if (login)
|
||||
fclose(login);
|
||||
if (logout)
|
||||
fclose(logout);
|
||||
if (cmd)
|
||||
fclose(cmd);
|
||||
exit(EX_OK);
|
||||
}
|
||||
|
||||
|
||||
if (file)
|
||||
{
|
||||
fprintf(file,"\nTransaction %d\n",trans_num);
|
||||
fwrite(buf,got,1,file);
|
||||
fflush(file);
|
||||
}
|
||||
trans_num++;
|
||||
|
||||
/* Now send it accross to the other side */
|
||||
ret = write(to, buf, got);
|
||||
|
||||
if (cmd)
|
||||
{
|
||||
fprintf(cmd,"wrote %d\n",ret);
|
||||
if (ret < 0)
|
||||
fprintf(cmd,"error = %s\n",strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
inet_conn(host, port)
|
||||
char *host;
|
||||
char *port;
|
||||
{
|
||||
/* Local Vars */
|
||||
int sock; /* Socket to use for the connection */
|
||||
struct hostent *hostent; /* Destination host entry */
|
||||
struct servent *servent; /* Destination service entry */
|
||||
struct sockaddr_in addr; /* Formated destination for connect */
|
||||
|
||||
/* Fetch the requested host and service entries */
|
||||
hostent = gethostbyname(host);
|
||||
if (isdigit(*port))
|
||||
servent = getservbyport(80, "tcp");
|
||||
else
|
||||
servent = getservbyname(port, "tcp");
|
||||
|
||||
|
||||
if (cmd)
|
||||
{
|
||||
fprintf(cmd,"inet_conn %s %s\n",host,port);
|
||||
|
||||
if (servent == NULL)
|
||||
fprintf(cmd,"servent is NIL\n");
|
||||
if (hostent == NULL)
|
||||
fprintf(cmd,"hostent is NIL\n");
|
||||
if (hostent->h_addrtype != AF_INET)
|
||||
fprintf(cmd,"not inet type\n");
|
||||
fflush(cmd);
|
||||
}
|
||||
|
||||
|
||||
/* No host entry, no service entry, or host is not
|
||||
Internet, error! */
|
||||
if( servent == NIL ||
|
||||
hostent == NIL ||
|
||||
hostent->h_addrtype != AF_INET )
|
||||
return -1;
|
||||
|
||||
/* Get a socket from the system to use for the connection */
|
||||
if( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
|
||||
return -1;
|
||||
|
||||
/* Make sure we start with a clean address structure ... */
|
||||
bzero(&addr, sizeof(addr));
|
||||
|
||||
/* ... then fill in the required fields */
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = servent->s_port;
|
||||
bcopy(hostent->h_addr, &addr.sin_addr, hostent->h_length);
|
||||
|
||||
/* Now try to connection to the destination */
|
||||
if( connect(sock, &addr, sizeof(addr)) < 0 ) {
|
||||
/* No go, release the socket, and then return error! */
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Success. Return the connected socket descriptor */
|
||||
if (cmd)
|
||||
fprintf(cmd,"returning %d\n",sock);
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
#endif
|
||||
|
||||
#include "includes.h"
|
||||
#include "nameserv.h"
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
@ -35,6 +34,7 @@ extern struct in_addr bcast_ip;
|
||||
extern pstring myhostname;
|
||||
|
||||
static BOOL got_bcast = False;
|
||||
struct in_addr ipzero;
|
||||
|
||||
int ServerFD= -1;
|
||||
|
||||
@ -124,6 +124,8 @@ int main(int argc,char *argv[])
|
||||
|
||||
TimeInit();
|
||||
|
||||
ipzero = *interpret_addr2("0.0.0.0");
|
||||
|
||||
setup_logging(argv[0],True);
|
||||
|
||||
charset_initialise();
|
||||
|
@ -201,14 +201,13 @@ _my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd,
|
||||
/*
|
||||
* Print command usage on stderr and die.
|
||||
*/
|
||||
void
|
||||
usage(char *name)
|
||||
static void usage(char *name)
|
||||
{
|
||||
fprintf(stderr, "Usage is : %s [username]\n", name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int real_uid;
|
||||
struct passwd *pwd;
|
||||
|
@ -44,7 +44,7 @@ unsigned int Ucrit_checkUsername(pstring username); /* added by OH */
|
||||
void Ucrit_addPid(int pid); /* added by OH */
|
||||
unsigned int Ucrit_checkPid(int pid); /* added by OH */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *f;
|
||||
pstring fname;
|
||||
|
@ -41,7 +41,7 @@
|
||||
extern FILE *dbf;
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
pstring configfile;
|
||||
int s;
|
||||
|
Loading…
x
Reference in New Issue
Block a user