1
0
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:
Andrew Tridgell 1996-06-04 06:42:03 +00:00
parent 81e398963d
commit a2c1623827
44 changed files with 7403 additions and 3822 deletions

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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"

View File

@ -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"

View File

@ -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)

View File

@ -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
View 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);

View File

@ -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

View File

@ -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")) {

View File

@ -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

View File

@ -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 */

View File

@ -295,5 +295,5 @@
** End of md4.c
*/
#else
void md4_dummy() {;}
void md4_dummy() {;}
#endif

View File

@ -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

View File

@ -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
View 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);
}

View File

@ -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));
}

View File

@ -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

View File

@ -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
View 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
View 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
View 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
View 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
View 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));
}

File diff suppressed because it is too large Load Diff

1072
source3/namework.c Normal file

File diff suppressed because it is too large Load Diff

601
source3/nmbd/nmbd.c Normal file
View 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);
}

View File

@ -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();
}
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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

View File

@ -297,8 +297,7 @@ get_smbpwnam(char *name)
return NULL;
}
#else
void
smbpass_dummy(void)
void smbpass_dummy(void)
{
} /* To avoid compiler complaints */
#endif

View 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;
}

View File

@ -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)

View File

@ -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));

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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));

View File

@ -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;

View File

@ -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;
}

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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;