mirror of
https://github.com/samba-team/samba.git
synced 2025-08-29 13:49:30 +03:00
dir.c: Fixed double slash issue.
includes.h: Changed to ifdef FAST_SHARE_MODES.
ipc.c: Changed lp_workgroup() to myworkgroup.
loadparm.c: Added new shared mem parameters. Added Luke's fix.
locking.c: Rewrite to do share modes better (both fast and slow modes).
nameannounce.c: Changed lp_workgroup() to myworkgroup. Added Luke's fix.
nameconf.c: Changed lp_workgroup() to myworkgroup.
namedbname.c: Improved debug.
namedbserver.c: Changed lp_workgroup() to myworkgroup.
namedbsubnet.c: Added Luke's fix - rewritten somewhat.
namedbwork.c: Changed lp_workgroup() to myworkgroup.
nameelect.c: Added Luke's fix - rewritten somewhat.
nameresp.c: Stoped shadowing global.
nameserv.c: Added Luke's fix - Improved debug.
nameservreply.c: Improved debug.
namework.c: Changed lp_workgroup() to myworkgroup.
nmbd.c: Added Luke's fix - Changed lp_workgroup() to myworkgroup.
pipes.c: Changed lp_workgroup() to myworkgroup.
proto.h: Added Luke's fix, added smb_shm_ proto's.
reply.c: Changed lp_workgroup() to myworkgroup.
server.c: Rewrite to do share modes better (both fast and slow modes).
shmem.c: Rewrite to do share modes better (both fast and slow modes).
smb.h: Rewrite to do share modes better (both fast and slow modes).
status.c: Rewrite to do share modes better (both fast and slow modes).
trans2.c: Fixed double slash issue.
util.c: Tidied up, created myworkgroup.
Jeremy Allison (jallison@whistle.com).
(This used to be commit 2a1711eaaf
)
This commit is contained in:
@ -481,6 +481,7 @@ char *mktemp(char *); /* No standard include */
|
||||
|
||||
|
||||
#ifdef FreeBSD
|
||||
#include <arpa/inet.h>
|
||||
#include <strings.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/in_systm.h>
|
||||
@ -970,7 +971,7 @@ typedef int mode_t;
|
||||
end of the platform specific sections
|
||||
********************************************************************/
|
||||
|
||||
#if defined(USE_MMAP) || FAST_SHARE_MODES
|
||||
#if defined(USE_MMAP) || defined(FAST_SHARE_MODES)
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
|
@ -149,6 +149,7 @@ char *lp_socket_address(void);
|
||||
char *lp_nis_home_map_name(void);
|
||||
BOOL lp_wins_support(void);
|
||||
BOOL lp_wins_proxy(void);
|
||||
BOOL lp_local_master(void);
|
||||
BOOL lp_domain_master(void);
|
||||
BOOL lp_domain_logons(void);
|
||||
BOOL lp_preferred_master(void);
|
||||
@ -176,6 +177,8 @@ int lp_maxpacket(void);
|
||||
int lp_keepalive(void);
|
||||
int lp_passwordlevel(void);
|
||||
int lp_readsize(void);
|
||||
int lp_shmem_size(void);
|
||||
int lp_shmem_hash_size(void);
|
||||
int lp_deadtime(void);
|
||||
int lp_maxprotocol(void);
|
||||
int lp_security(void);
|
||||
@ -266,12 +269,12 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ec
|
||||
BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
|
||||
BOOL start_share_mode_mgmt(void);
|
||||
BOOL stop_share_mode_mgmt(void);
|
||||
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_modes(void);
|
||||
BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *);
|
||||
BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token);
|
||||
int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode,
|
||||
min_share_mode_entry **old_shares);
|
||||
void del_share_mode(share_lock_token token, int fnum);
|
||||
BOOL set_share_mode(share_lock_token token, int fnum);
|
||||
|
||||
/*The following definitions come from mangle.c */
|
||||
|
||||
@ -309,7 +312,7 @@ void do_announce_host(int command,
|
||||
char *to_name , int to_type , struct in_addr to_ip,
|
||||
time_t announce_interval,
|
||||
char *server_name, int server_type, char *server_comment);
|
||||
void remove_my_servers(void);
|
||||
void announce_my_servers_removed(void);
|
||||
void announce_server(struct subnet_record *d, struct work_record *work,
|
||||
char *name, char *comment, time_t ttl, int server_type);
|
||||
void announce_host(time_t t);
|
||||
@ -394,7 +397,7 @@ void expire_servers(time_t t);
|
||||
struct subnet_record *find_subnet(struct in_addr bcast_ip);
|
||||
struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast);
|
||||
struct subnet_record *find_subnet_all(struct in_addr bcast_ip);
|
||||
void add_subnet_interfaces(void);
|
||||
void add_workgroup_to_subnet( struct subnet_record *d, char *group);
|
||||
void add_my_subnets(char *group);
|
||||
void write_browse_list(time_t t);
|
||||
|
||||
@ -406,7 +409,6 @@ struct work_record *remove_workgroup(struct subnet_record *d,
|
||||
struct work_record *find_workgroupstruct(struct subnet_record *d,
|
||||
fstring name, BOOL add);
|
||||
void dump_workgroups(void);
|
||||
int check_work_servertype(const char *work_name, int type_mask);
|
||||
|
||||
/*The following definitions come from nameelect.c */
|
||||
|
||||
@ -724,6 +726,11 @@ BOOL smb_shm_set_userdef_off(smb_shm_offset_t userdef_off);
|
||||
void * smb_shm_offset2addr(smb_shm_offset_t offset);
|
||||
BOOL smb_shm_lock(void);
|
||||
BOOL smb_shm_unlock(void);
|
||||
smb_shm_offset_t smb_shm_alloc(int size);
|
||||
smb_shm_offset_t smb_shm_addr2offset(void *addr);
|
||||
smb_shm_offset_t smb_shm_get_userdef_off(void);
|
||||
BOOL smb_shm_lock_hash_entry( unsigned int entry);
|
||||
BOOL smb_shm_unlock_hash_entry( unsigned int entry );
|
||||
BOOL smb_shm_get_usage(int *bytes_free,
|
||||
int *bytes_used,
|
||||
int *bytes_overhead);
|
||||
|
@ -36,11 +36,16 @@
|
||||
#define BUFFER_SIZE (0xFFFF)
|
||||
#define SAFETY_MARGIN 1024
|
||||
|
||||
/* size of shared memory used for share mode locking */
|
||||
/* Default size of shared memory used for share mode locking */
|
||||
#ifndef SHMEM_SIZE
|
||||
#define SHMEM_SIZE 102400
|
||||
#endif
|
||||
|
||||
/* Default number of hash buckets used in shared memory share mode */
|
||||
#ifndef SHMEM_HASH_SIZE
|
||||
#define SHMEM_HASH_SIZE 113
|
||||
#endif
|
||||
|
||||
#define NMB_PORT 137
|
||||
#define DGRAM_PORT 138
|
||||
#define SMB_PORT 139
|
||||
@ -295,8 +300,8 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
uint16 ref_count;
|
||||
int32 dev;
|
||||
int32 inode;
|
||||
uint32 dev;
|
||||
uint32 inode;
|
||||
int fd;
|
||||
int fd_readonly;
|
||||
int fd_writeonly;
|
||||
@ -320,7 +325,6 @@ typedef struct
|
||||
BOOL can_read;
|
||||
BOOL can_write;
|
||||
BOOL share_mode;
|
||||
BOOL share_pending;
|
||||
BOOL print_file;
|
||||
BOOL modified;
|
||||
char *name;
|
||||
@ -420,19 +424,40 @@ struct interface
|
||||
struct in_addr nmask;
|
||||
};
|
||||
|
||||
/* share mode record in shared memory */
|
||||
/* share mode record pointed to in shared memory hash bucket */
|
||||
typedef struct
|
||||
{
|
||||
smb_shm_offset_t next_offset; /* offset of next record in list in shared mem */
|
||||
smb_shm_offset_t next_offset; /* offset of next record in chain from hash bucket */
|
||||
int locking_version;
|
||||
int share_mode;
|
||||
struct timeval time;
|
||||
int pid;
|
||||
dev_t st_dev;
|
||||
ino_t st_ino;
|
||||
char file_name[1]; /* dynamically allocated with correct size */
|
||||
int32 st_dev;
|
||||
int32 st_ino;
|
||||
int num_share_mode_entries;
|
||||
smb_shm_offset_t share_mode_entries; /* Chain of share mode entries for this file */
|
||||
char file_name[1];
|
||||
} share_mode_record;
|
||||
|
||||
/* share mode entry pointed to by share_mode_record struct */
|
||||
typedef struct
|
||||
{
|
||||
smb_shm_offset_t next_share_mode_entry;
|
||||
int pid;
|
||||
int share_mode;
|
||||
struct timeval time;
|
||||
} share_mode_entry;
|
||||
|
||||
/* struct returned by get_share_modes */
|
||||
typedef struct
|
||||
{
|
||||
int pid;
|
||||
int share_mode;
|
||||
struct timeval time;
|
||||
} min_share_mode_entry;
|
||||
|
||||
/* Token returned by lock_share_entry (actually ignored by FAST_SHARE_MODES code) */
|
||||
typedef int share_lock_token;
|
||||
|
||||
/* Conversion to hash entry index from device and inode numbers. */
|
||||
#define HASH_ENTRY(dev,ino) ((( (uint32)(dev) )* ( (uint32)(ino) )) % lp_shmem_hash_size())
|
||||
|
||||
/* this is used for smbstatus */
|
||||
struct connect_record
|
||||
@ -798,12 +823,15 @@ char *Strstr(char *s, char *p);
|
||||
#define SV_TYPE_DOMAIN_ENUM 0x80000000
|
||||
#define SV_TYPE_ALL 0xFFFFFFFF
|
||||
|
||||
/* What server type are we currently - JHT Says we ARE 4.20 */
|
||||
/* what server type are we currently - JHT Says we ARE 4.20 */
|
||||
/* this was set by JHT in liaison with Jeremy Allison early 1997 */
|
||||
/* setting to 4.20 at same time as announcing ourselves as NT Server */
|
||||
/* History: */
|
||||
/* Version 4.0 - never made public */
|
||||
/* Version 4.10 - New to 1.9.16p2, lost in space 1.9.16p3 to 1.9.16p9 */
|
||||
/* - Reappeared in 1.9.16p11 with fixed smbd services */
|
||||
/* Version 4.20 - To indicate that nmbd and browsing now works better */
|
||||
|
||||
#define MAJOR_VERSION 0x04
|
||||
#define MINOR_VERSION 0x02
|
||||
|
||||
|
@ -73,6 +73,7 @@ pstring myhostname="";
|
||||
pstring user_socket_options="";
|
||||
pstring sesssetup_user="";
|
||||
pstring myname = "";
|
||||
fstring myworkgroup = "";
|
||||
|
||||
int smb_read_error = 0;
|
||||
|
||||
@ -3431,7 +3432,7 @@ BOOL is_vetoed_name(char *name)
|
||||
nameptr++;
|
||||
continue;
|
||||
}
|
||||
if(name_end = strchr(nameptr,'/'))
|
||||
if((name_end = strchr(nameptr,'/'))!=NULL)
|
||||
{
|
||||
*name_end = 0;
|
||||
}
|
||||
@ -3472,7 +3473,7 @@ BOOL is_vetoed_path(char *name)
|
||||
nameptr++;
|
||||
continue;
|
||||
}
|
||||
if(name_end = strchr(nameptr,'/'))
|
||||
if((name_end = strchr(nameptr,'/'))!=NULL)
|
||||
{
|
||||
*name_end = 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@
|
||||
#include "includes.h"
|
||||
|
||||
|
||||
#if FAST_SHARE_MODES
|
||||
#ifdef FAST_SHARE_MODES
|
||||
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
@ -32,7 +32,7 @@ extern int DEBUGLEVEL;
|
||||
#define SMB_SHM_MAGIC 0x53484100
|
||||
/* = "SHM" in hex */
|
||||
|
||||
#define SMB_SHM_VERSION 1
|
||||
#define SMB_SHM_VERSION 2
|
||||
|
||||
/* WARNING : offsets are used because mmap() does not guarantee that all processes have the
|
||||
shared memory mapped to the same address */
|
||||
@ -73,15 +73,109 @@ static pstring smb_shm_processreg_name = "";
|
||||
static struct SmbShmHeader *smb_shm_header_p = (struct SmbShmHeader *)0;
|
||||
static int smb_shm_times_locked = 0;
|
||||
|
||||
static BOOL smb_shm_initialize_called = False;
|
||||
|
||||
static BOOL smb_shm_global_lock(void)
|
||||
{
|
||||
if (smb_shm_fd < 0)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_global_lock : bad smb_shm_fd (%d)\n",smb_shm_fd));
|
||||
return False;
|
||||
}
|
||||
|
||||
smb_shm_times_locked++;
|
||||
|
||||
if(smb_shm_times_locked > 1)
|
||||
{
|
||||
DEBUG(2,("smb_shm_global_lock : locked %d times\n",smb_shm_times_locked));
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Do an exclusive wait lock on the first byte of the file */
|
||||
if (fcntl_lock(smb_shm_fd, F_SETLKW, 0, 1, F_WRLCK) == False)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_global_lock : fcntl_lock failed with code %d\n",errno));
|
||||
smb_shm_times_locked--;
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
|
||||
}
|
||||
|
||||
static BOOL smb_shm_global_unlock(void)
|
||||
{
|
||||
if (smb_shm_fd < 0)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_global_unlock : bad smb_shm_fd (%d)\n",smb_shm_fd));
|
||||
return False;
|
||||
}
|
||||
|
||||
if(smb_shm_times_locked == 0)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_global_unlock : shmem not locked\n",smb_shm_fd));
|
||||
return False;
|
||||
}
|
||||
|
||||
smb_shm_times_locked--;
|
||||
|
||||
if(smb_shm_times_locked > 0)
|
||||
{
|
||||
DEBUG(2,("smb_shm_global_unlock : still locked %d times\n",smb_shm_times_locked));
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Do a wait unlock on the first byte of the file */
|
||||
if (fcntl_lock(smb_shm_fd, F_SETLKW, 0, 1, F_UNLCK) == False)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_global_unlock : fcntl_lock failed with code %d\n",errno));
|
||||
smb_shm_times_locked++;
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to create the hash table for the share mode entries. Called
|
||||
* when smb shared memory is global locked.
|
||||
*/
|
||||
|
||||
BOOL smb_shm_create_hash_table( unsigned int size )
|
||||
{
|
||||
size *= sizeof(smb_shm_offset_t);
|
||||
|
||||
smb_shm_global_lock();
|
||||
smb_shm_header_p->userdef_off = smb_shm_alloc( size );
|
||||
|
||||
if(smb_shm_header_p->userdef_off == NULL_OFFSET)
|
||||
{
|
||||
DEBUG(0,("smb_shm_create_hash_table: Failed to create hash table of size %d\n",size));
|
||||
smb_shm_global_unlock();
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Clear hash buckets. */
|
||||
memset( smb_shm_offset2addr(smb_shm_header_p->userdef_off), '\0', size);
|
||||
smb_shm_global_unlock();
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *other_processes)
|
||||
{
|
||||
int smb_shm_processes_fd = -1;
|
||||
int nb_read;
|
||||
pid_t other_pid;
|
||||
int seek_back = -sizeof(other_pid);
|
||||
int free_slot = -1;
|
||||
int erased_slot;
|
||||
|
||||
#ifndef SECURE_SHARE_MODES
|
||||
smb_shm_processes_fd = open(processreg_file, O_RDWR | O_CREAT, 0666);
|
||||
#else /* SECURE_SHARE_MODES */
|
||||
smb_shm_processes_fd = open(processreg_file, O_RDWR | O_CREAT, 0600);
|
||||
#endif /* SECURE_SHARE_MODES */
|
||||
if ( smb_shm_processes_fd < 0 )
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_register_process : processreg_file open failed with code %d\n",errno));
|
||||
@ -99,9 +193,10 @@ static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *oth
|
||||
else
|
||||
{
|
||||
/* erase old pid */
|
||||
DEBUG(2,("smb_shm_register_process : erasing stale record for pid %d\n",other_pid));
|
||||
DEBUG(2,("smb_shm_register_process : erasing stale record for pid %d (seek_back = %d)\n",
|
||||
other_pid, seek_back));
|
||||
other_pid = (pid_t)0;
|
||||
erased_slot = lseek(smb_shm_processes_fd, -sizeof(other_pid), SEEK_CUR);
|
||||
erased_slot = lseek(smb_shm_processes_fd, seek_back, SEEK_CUR);
|
||||
write(smb_shm_processes_fd, &other_pid, sizeof(other_pid));
|
||||
if(free_slot < 0)
|
||||
free_slot = erased_slot;
|
||||
@ -109,7 +204,7 @@ static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *oth
|
||||
}
|
||||
else
|
||||
if(free_slot < 0)
|
||||
free_slot = lseek(smb_shm_processes_fd, -sizeof(other_pid), SEEK_CUR);
|
||||
free_slot = lseek(smb_shm_processes_fd, seek_back, SEEK_CUR);
|
||||
}
|
||||
if (nb_read < 0)
|
||||
{
|
||||
@ -141,6 +236,7 @@ static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid)
|
||||
int smb_shm_processes_fd = -1;
|
||||
int nb_read;
|
||||
pid_t other_pid;
|
||||
int seek_back = -sizeof(other_pid);
|
||||
int erased_slot;
|
||||
BOOL found = False;
|
||||
|
||||
@ -156,12 +252,14 @@ static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid)
|
||||
|
||||
while ((nb_read = read(smb_shm_processes_fd, &other_pid, sizeof(other_pid))) > 0)
|
||||
{
|
||||
DEBUG(2,("smb_shm_unregister_process : read record for pid %d\n",other_pid));
|
||||
if(other_pid == pid)
|
||||
{
|
||||
/* erase pid */
|
||||
DEBUG(2,("smb_shm_unregister_process : erasing record for pid %d\n",other_pid));
|
||||
DEBUG(2,("smb_shm_unregister_process : erasing record for pid %d (seek_val = %d)\n",
|
||||
other_pid, seek_back));
|
||||
other_pid = (pid_t)0;
|
||||
erased_slot = lseek(smb_shm_processes_fd, -sizeof(other_pid), SEEK_CUR);
|
||||
erased_slot = lseek(smb_shm_processes_fd, seek_back, SEEK_CUR);
|
||||
if(write(smb_shm_processes_fd, &other_pid, sizeof(other_pid)) < 0)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file write failed with code %d\n",errno));
|
||||
@ -257,6 +355,8 @@ static BOOL smb_shm_initialize(int size)
|
||||
|
||||
smb_shm_header_p->consistent = True;
|
||||
|
||||
smb_shm_initialize_called = True;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -291,7 +391,11 @@ BOOL smb_shm_open( char *file_name, int size)
|
||||
DEBUG(2,("smb_shm_open : using shmem file %s to be of size %d\n",file_name,size));
|
||||
|
||||
old_umask = umask(0);
|
||||
#ifndef SECURE_SHARE_MODES
|
||||
smb_shm_fd = open(file_name, O_RDWR | O_CREAT, 0666);
|
||||
#else /* SECURE_SHARE_MODES */
|
||||
smb_shm_fd = open(file_name, O_RDWR | O_CREAT, 0600);
|
||||
#endif /* SECURE_SHARE_MODE */
|
||||
umask(old_umask);
|
||||
if ( smb_shm_fd < 0 )
|
||||
{
|
||||
@ -299,16 +403,16 @@ BOOL smb_shm_open( char *file_name, int size)
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!smb_shm_lock())
|
||||
if (!smb_shm_global_lock())
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_open : can't do smb_shm_lock\n"));
|
||||
DEBUG(0,("ERROR smb_shm_open : can't do smb_shm_global_lock\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if( (filesize = lseek(smb_shm_fd, 0, SEEK_END)) < 0)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_open : lseek failed with code %d\n",errno));
|
||||
smb_shm_unlock();
|
||||
smb_shm_global_unlock();
|
||||
close(smb_shm_fd);
|
||||
return False;
|
||||
}
|
||||
@ -332,7 +436,7 @@ BOOL smb_shm_open( char *file_name, int size)
|
||||
|
||||
if (! smb_shm_register_process(smb_shm_processreg_name, getpid(), &other_processes))
|
||||
{
|
||||
smb_shm_unlock();
|
||||
smb_shm_global_unlock();
|
||||
close(smb_shm_fd);
|
||||
return False;
|
||||
}
|
||||
@ -344,7 +448,7 @@ BOOL smb_shm_open( char *file_name, int size)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_open : ftruncate failed with code %d\n",errno));
|
||||
smb_shm_unregister_process(smb_shm_processreg_name, getpid());
|
||||
smb_shm_unlock();
|
||||
smb_shm_global_unlock();
|
||||
close(smb_shm_fd);
|
||||
return False;
|
||||
}
|
||||
@ -369,7 +473,7 @@ BOOL smb_shm_open( char *file_name, int size)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_open : mmap failed with code %d\n",errno));
|
||||
smb_shm_unregister_process(smb_shm_processreg_name, getpid());
|
||||
smb_shm_unlock();
|
||||
smb_shm_global_unlock();
|
||||
close(smb_shm_fd);
|
||||
return False;
|
||||
}
|
||||
@ -378,6 +482,8 @@ BOOL smb_shm_open( char *file_name, int size)
|
||||
if (created_new || !other_processes)
|
||||
{
|
||||
smb_shm_initialize(size);
|
||||
/* Create the hash buckets for the share file entries. */
|
||||
smb_shm_create_hash_table( lp_shmem_hash_size() );
|
||||
}
|
||||
else if (!smb_shm_validate_header(size) )
|
||||
{
|
||||
@ -385,12 +491,12 @@ BOOL smb_shm_open( char *file_name, int size)
|
||||
DEBUG(0,("ERROR smb_shm_open : corrupt shared mem file, remove it manually\n"));
|
||||
munmap((caddr_t)smb_shm_header_p, size);
|
||||
smb_shm_unregister_process(smb_shm_processreg_name, getpid());
|
||||
smb_shm_unlock();
|
||||
smb_shm_global_unlock();
|
||||
close(smb_shm_fd);
|
||||
return False;
|
||||
}
|
||||
|
||||
smb_shm_unlock();
|
||||
smb_shm_global_unlock();
|
||||
return True;
|
||||
|
||||
}
|
||||
@ -399,17 +505,22 @@ BOOL smb_shm_open( char *file_name, int size)
|
||||
BOOL smb_shm_close( void )
|
||||
{
|
||||
|
||||
if(smb_shm_initialize_called == False)
|
||||
return True;
|
||||
|
||||
DEBUG(2,("smb_shm_close\n"));
|
||||
if(smb_shm_times_locked > 0)
|
||||
DEBUG(0,("WARNING smb_shm_close : shmem was still locked %d times\n",smb_shm_times_locked));;
|
||||
if ( munmap((caddr_t)smb_shm_header_p, smb_shm_header_p->total_size) < 0)
|
||||
if ((smb_shm_header_p != NULL) &&
|
||||
(munmap((caddr_t)smb_shm_header_p, smb_shm_header_p->total_size) < 0))
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_close : munmap failed with code %d\n",errno));
|
||||
}
|
||||
|
||||
smb_shm_lock();
|
||||
smb_shm_global_lock();
|
||||
DEBUG(2,("calling smb_shm_unregister_process(%s, %d)\n", smb_shm_processreg_name, getpid()));
|
||||
smb_shm_unregister_process(smb_shm_processreg_name, getpid());
|
||||
smb_shm_unlock();
|
||||
smb_shm_global_unlock();
|
||||
|
||||
close(smb_shm_fd);
|
||||
|
||||
@ -438,9 +549,12 @@ smb_shm_offset_t smb_shm_alloc(int size)
|
||||
return NULL_OFFSET;
|
||||
}
|
||||
|
||||
smb_shm_global_lock();
|
||||
|
||||
if( !smb_shm_header_p->consistent)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_alloc : shmem not consistent\n"));
|
||||
smb_shm_global_unlock();
|
||||
return NULL_OFFSET;
|
||||
}
|
||||
|
||||
@ -463,6 +577,7 @@ smb_shm_offset_t smb_shm_alloc(int size)
|
||||
if ( scanner_p == EOList_Addr )
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_alloc : alloc of %d bytes failed, no free space found\n",size));
|
||||
smb_shm_global_unlock();
|
||||
return (NULL_OFFSET);
|
||||
}
|
||||
|
||||
@ -516,6 +631,7 @@ smb_shm_offset_t smb_shm_alloc(int size)
|
||||
|
||||
DEBUG(2,("smb_shm_alloc : request for %d bytes, allocated %d bytes at offset %d\n",size,scanner_p->size*CellSize,result_offset ));
|
||||
|
||||
smb_shm_global_unlock();
|
||||
return ( result_offset );
|
||||
}
|
||||
|
||||
@ -534,9 +650,12 @@ BOOL smb_shm_free(smb_shm_offset_t offset)
|
||||
return False;
|
||||
}
|
||||
|
||||
smb_shm_global_lock();
|
||||
|
||||
if( !smb_shm_header_p->consistent)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_free : shmem not consistent\n"));
|
||||
smb_shm_global_unlock();
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -545,6 +664,7 @@ BOOL smb_shm_free(smb_shm_offset_t offset)
|
||||
if (header_p->next != SMB_SHM_NOT_FREE_OFF)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_free : bad offset (%d)\n",offset));
|
||||
smb_shm_global_unlock();
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -577,6 +697,7 @@ BOOL smb_shm_free(smb_shm_offset_t offset)
|
||||
smb_shm_solve_neighbors( header_p ); /* if neighbors then link them */
|
||||
|
||||
smb_shm_header_p->consistent = True;
|
||||
smb_shm_global_unlock();
|
||||
return True;
|
||||
}
|
||||
else
|
||||
@ -590,6 +711,7 @@ BOOL smb_shm_free(smb_shm_offset_t offset)
|
||||
smb_shm_solve_neighbors(prev_p) ;
|
||||
|
||||
smb_shm_header_p->consistent = True;
|
||||
smb_shm_global_unlock();
|
||||
return True;
|
||||
}
|
||||
}
|
||||
@ -633,68 +755,71 @@ smb_shm_offset_t smb_shm_addr2offset(void *addr)
|
||||
return (smb_shm_offset_t)((char *)addr - (char *)smb_shm_header_p);
|
||||
}
|
||||
|
||||
BOOL smb_shm_lock(void)
|
||||
/*******************************************************************
|
||||
Lock a particular hash bucket entry.
|
||||
******************************************************************/
|
||||
|
||||
BOOL smb_shm_lock_hash_entry( unsigned int entry)
|
||||
{
|
||||
if (smb_shm_fd < 0)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_lock : bad smb_shm_fd (%d)\n",smb_shm_fd));
|
||||
int start = (smb_shm_header_p->userdef_off + (entry * sizeof(smb_shm_offset_t)));
|
||||
|
||||
if (smb_shm_fd < 0)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_lock_hash_entry : bad smb_shm_fd (%d)\n",smb_shm_fd));
|
||||
return False;
|
||||
}
|
||||
|
||||
smb_shm_times_locked++;
|
||||
|
||||
if(smb_shm_times_locked > 1)
|
||||
{
|
||||
DEBUG(2,("smb_shm_lock : locked %d times\n",smb_shm_times_locked));
|
||||
return True;
|
||||
}
|
||||
|
||||
if (lockf(smb_shm_fd, F_LOCK, 0) < 0)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_lock : lockf failed with code %d\n",errno));
|
||||
smb_shm_times_locked--;
|
||||
}
|
||||
|
||||
if(entry >= lp_shmem_hash_size())
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_lock_hash_entry : hash entry size too big (%d)\n", entry));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
|
||||
}
|
||||
|
||||
/* Do an exclusive wait lock on the 4 byte region mapping into this entry */
|
||||
if (fcntl_lock(smb_shm_fd, F_SETLKW, start, sizeof(smb_shm_offset_t), F_WRLCK) == False)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_lock_hash_entry : fcntl_lock failed with code %d\n",errno));
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(9,("smb_shm_lock_hash_entry: locked hash bucket %d\n", entry));
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Unlock a particular hash bucket entry.
|
||||
******************************************************************/
|
||||
|
||||
|
||||
BOOL smb_shm_unlock(void)
|
||||
BOOL smb_shm_unlock_hash_entry( unsigned int entry )
|
||||
{
|
||||
if (smb_shm_fd < 0)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_unlock : bad smb_shm_fd (%d)\n",smb_shm_fd));
|
||||
int start = (smb_shm_header_p->userdef_off + (entry * sizeof(smb_shm_offset_t)));
|
||||
|
||||
if (smb_shm_fd < 0)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_unlock_hash_entry : bad smb_shm_fd (%d)\n",smb_shm_fd));
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
if(smb_shm_times_locked == 0)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_unlock : shmem not locked\n",smb_shm_fd));
|
||||
if(entry >= lp_shmem_hash_size())
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_unlock_hash_entry : hash entry size too big (%d)\n", entry));
|
||||
return False;
|
||||
}
|
||||
|
||||
smb_shm_times_locked--;
|
||||
|
||||
if(smb_shm_times_locked > 0)
|
||||
{
|
||||
DEBUG(2,("smb_shm_unlock : still locked %d times\n",smb_shm_times_locked));
|
||||
return True;
|
||||
}
|
||||
|
||||
if (lockf(smb_shm_fd, F_ULOCK, 0) < 0)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_unlock : lockf failed with code %d\n",errno));
|
||||
smb_shm_times_locked++;
|
||||
}
|
||||
|
||||
/* Do a wait lock on the 4 byte region mapping into this entry */
|
||||
if (fcntl_lock(smb_shm_fd, F_SETLKW, start, sizeof(smb_shm_offset_t), F_UNLCK) == False)
|
||||
{
|
||||
DEBUG(0,("ERROR smb_shm_unlock_hash_entry : fcntl_lock failed with code %d\n",errno));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
|
||||
}
|
||||
|
||||
DEBUG(9,("smb_shm_unlock_hash_entry: unlocked hash bucket %d\n", entry));
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Gather statistics on shared memory usage.
|
||||
******************************************************************/
|
||||
|
||||
BOOL smb_shm_get_usage(int *bytes_free,
|
||||
int *bytes_used,
|
||||
@ -716,4 +841,4 @@ BOOL smb_shm_get_usage(int *bytes_free,
|
||||
#else /* FAST_SHARE_MODES */
|
||||
int shmem_dummy_procedure(void)
|
||||
{return 0;}
|
||||
#endif
|
||||
#endif /* FAST_SHARE_MODES */
|
||||
|
@ -35,6 +35,7 @@ extern BOOL CanRecurse;
|
||||
extern struct in_addr ipzero;
|
||||
|
||||
extern pstring myname;
|
||||
extern fstring myworkgroup;
|
||||
|
||||
extern int ClientDGRAM;
|
||||
extern int ClientNMB;
|
||||
@ -185,9 +186,9 @@ void do_announce_host(int command,
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
remove all samba's server entries
|
||||
****************************************************************************/
|
||||
void remove_my_servers(void)
|
||||
announce all samba's server entries as 'gone'.
|
||||
****************************************************************************/
|
||||
void announce_my_servers_removed(void)
|
||||
{
|
||||
struct subnet_record *d;
|
||||
for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
|
||||
@ -372,7 +373,7 @@ static time_t announce_timer_last=0;
|
||||
|
||||
void reset_announce_timer()
|
||||
{
|
||||
announce_timer_last = 0;
|
||||
announce_timer_last = time(NULL) - (CHECK_TIME_MST_ANNOUNCE * 60);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -396,7 +397,7 @@ void announce_master(time_t t)
|
||||
return;
|
||||
}
|
||||
|
||||
if(wins_subnet == 0)
|
||||
if(wins_subnet == NULL)
|
||||
{
|
||||
DEBUG(10,("announce_master: no wins subnet, ignoring.\n"));
|
||||
return;
|
||||
@ -412,19 +413,19 @@ void announce_master(time_t t)
|
||||
if (AM_MASTER(work))
|
||||
{
|
||||
am_master = True;
|
||||
DEBUG(4,( "announce_master: am_master = %d for \
|
||||
workgroup %s\n", am_master, work->work_group));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(4,( "announce_master: am_master = %d for workgroup %s\n", am_master, lp_workgroup()));
|
||||
|
||||
if (!am_master) return; /* only proceed if we are a master browser */
|
||||
|
||||
/* Note that we don't do this if we are domain master browser
|
||||
and that we *only* do this on the WINS subnet. */
|
||||
|
||||
/* Try and find our workgroup on the WINS subnet */
|
||||
work = find_workgroupstruct(wins_subnet, lp_workgroup(), False);
|
||||
work = find_workgroupstruct(wins_subnet, myworkgroup, False);
|
||||
|
||||
if (work)
|
||||
{
|
||||
@ -488,7 +489,7 @@ in our own WINS database.\n", work->work_group));
|
||||
|
||||
/* Check that this isn't one of our addresses (ie. we are not domain master
|
||||
ourselves) */
|
||||
if(ismyip(nr->ip_flgs[0].ip))
|
||||
if(ismyip(nr->ip_flgs[0].ip) || ip_equal(nr->ip_flgs[0].ip, ipzero))
|
||||
{
|
||||
DEBUG(4, ("announce_master: domain master ip found (%s) for workgroup %s \
|
||||
is one of our interfaces.\n", work->work_group, inet_ntoa(nr->ip_flgs[0].ip) ));
|
||||
@ -535,7 +536,7 @@ void announce_remote(time_t t)
|
||||
if (!*s) return;
|
||||
|
||||
comment = lp_serverstring();
|
||||
workgroup = lp_workgroup();
|
||||
workgroup = myworkgroup;
|
||||
|
||||
for (ptr=s; next_token(&ptr,s2,NULL); ) {
|
||||
/* the entries are of the form a.b.c.d/WORKGROUP with
|
||||
|
@ -35,6 +35,8 @@
|
||||
#include "includes.h"
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
extern fstring myworkgroup;
|
||||
|
||||
#if 0
|
||||
struct smbbrowse_parms
|
||||
{
|
||||
@ -104,7 +106,7 @@ static struct smbbrowse *new_workgroup(struct smbbrowse *model,
|
||||
StrnCpy(new->work_name, workgroup_name, 15);
|
||||
strupper(new->work_name);
|
||||
|
||||
if (strequal(lp_workgroup(), workgroup_name))
|
||||
if (strequal(myworkgroup, workgroup_name))
|
||||
StrnCpy(new->browsing_alias, default_name, 15);
|
||||
else
|
||||
sprintf(new->browsing_alias, "%.14s%x", default_name, nexttoken);
|
||||
@ -289,7 +291,7 @@ static void default_smbbrowse_conf(char *default_name)
|
||||
struct smbbrowse *w;
|
||||
|
||||
/* The workgroup specified in smb.conf */
|
||||
w = new_workgroup((struct smbbrowse *)NULL, lp_workgroup(), default_name);
|
||||
w = new_workgroup((struct smbbrowse *)NULL, myworkgroup, default_name);
|
||||
w->should_local_master = lp_preferred_master();
|
||||
w->should_domain_master = lp_domain_master();
|
||||
w->should_workgroup_member = True;
|
||||
|
@ -153,11 +153,13 @@ struct name_record *find_name(struct name_record *n,
|
||||
{
|
||||
continue;
|
||||
}
|
||||
DEBUG(9,("find_name: found name %s\n", name->name));
|
||||
DEBUG(9,("find_name: found name %s(%02x)\n",
|
||||
name->name, name->name_type));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
DEBUG(9,("find_name: name %s NOT FOUND\n", name->name));
|
||||
DEBUG(9,("find_name: name %s(%02x) NOT FOUND\n", name->name,
|
||||
name->name_type));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -528,7 +530,6 @@ struct name_record *dns_name_search(struct nmb_name *question, int Time)
|
||||
{
|
||||
int name_type = question->name_type;
|
||||
char *qname = question->name;
|
||||
char *r;
|
||||
BOOL dns_type = (name_type == 0x20 || name_type == 0);
|
||||
struct in_addr dns_ip;
|
||||
|
||||
|
@ -37,6 +37,7 @@ extern int ClientDGRAM;
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
extern pstring myname;
|
||||
extern fstring myworkgroup;
|
||||
|
||||
/* this is our domain/workgroup/server database */
|
||||
extern struct subnet_record *subnetlist;
|
||||
@ -161,7 +162,7 @@ struct server_record *add_server_entry(struct subnet_record *d,
|
||||
}
|
||||
|
||||
|
||||
if (strequal(lp_workgroup(),work->work_group))
|
||||
if (strequal(myworkgroup,work->work_group))
|
||||
{
|
||||
if (servertype)
|
||||
servertype |= SV_TYPE_LOCAL_LIST_ONLY;
|
||||
|
@ -40,6 +40,7 @@ extern struct in_addr wins_ip;
|
||||
extern struct in_addr ipzero;
|
||||
|
||||
extern pstring myname;
|
||||
extern fstring myworkgroup;
|
||||
|
||||
BOOL updatedlists = True;
|
||||
int updatecount = 0;
|
||||
@ -52,15 +53,10 @@ struct subnet_record *subnetlist = NULL;
|
||||
|
||||
/* WINS subnet - keep this separate so enumeration code doesn't
|
||||
run onto it by mistake. */
|
||||
struct subnet_record *wins_subnet = 0;
|
||||
struct subnet_record *wins_subnet = NULL;
|
||||
|
||||
extern uint16 nb_type; /* samba's NetBIOS name type */
|
||||
|
||||
/* Forward references. */
|
||||
static struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
|
||||
struct in_addr mask_ip,
|
||||
char *name, BOOL add, BOOL lmhosts);
|
||||
|
||||
/****************************************************************************
|
||||
add a domain into the list
|
||||
**************************************************************************/
|
||||
@ -129,6 +125,7 @@ struct subnet_record *find_subnet_all(struct in_addr bcast_ip)
|
||||
struct subnet_record *d = find_subnet(bcast_ip);
|
||||
if(!d)
|
||||
return wins_subnet;
|
||||
return d;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -156,121 +153,122 @@ static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
add the remote interfaces from lp_interfaces()
|
||||
to the netbios subnet database.
|
||||
****************************************************************************/
|
||||
void add_subnet_interfaces(void)
|
||||
{
|
||||
struct interface *i;
|
||||
|
||||
/* loop on all local interfaces */
|
||||
for (i = local_interfaces; i; i = i->next)
|
||||
{
|
||||
/* add the interface into our subnet database */
|
||||
if (!find_subnet(i->bcast))
|
||||
{
|
||||
make_subnet(i->bcast,i->nmask, True);
|
||||
}
|
||||
}
|
||||
|
||||
/* add the pseudo-ip interface for WINS: 255.255.255.255 */
|
||||
if (lp_wins_support() || (*lp_wins_server()))
|
||||
{
|
||||
struct in_addr wins_bcast = wins_ip;
|
||||
struct in_addr wins_nmask = ipzero;
|
||||
wins_subnet = make_subnet(wins_bcast, wins_nmask, False);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
add the default workgroup into the subnet lists.
|
||||
**************************************************************************/
|
||||
void add_my_subnets(char *group)
|
||||
{
|
||||
struct interface *i;
|
||||
|
||||
/* add or find domain on our local subnet, in the default workgroup */
|
||||
|
||||
if (*group == '*') return;
|
||||
|
||||
/* the coding choice is up to you, andrew: i can see why you don't want
|
||||
global access to the local_interfaces structure: so it can't get
|
||||
messed up! */
|
||||
for (i = local_interfaces; i; i = i->next)
|
||||
{
|
||||
add_subnet_entry(i->bcast,i->nmask,group, True, False);
|
||||
}
|
||||
|
||||
/* If we are setup as a domain master browser, and are using
|
||||
WINS, then we must add the workgroup to the WINS subnet. This
|
||||
is used as a place to keep collated server lists. */
|
||||
|
||||
if(lp_domain_master() && (lp_wins_support() || lp_wins_server()))
|
||||
if(find_workgroupstruct(wins_subnet, group, True) == 0)
|
||||
DEBUG(0, ("add_my_subnets: Failed to add workgroup %s to \
|
||||
WINS subnet.\n", group));
|
||||
else
|
||||
DEBUG(3,("add_my_subnets: Added workgroup %s to WINS subnet.\n",
|
||||
group));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
add a domain entry. creates a workgroup, if necessary, and adds the domain
|
||||
to the named a workgroup.
|
||||
****************************************************************************/
|
||||
static struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
|
||||
struct in_addr mask_ip,
|
||||
char *name, BOOL add, BOOL lmhosts)
|
||||
struct in_addr mask_ip, char *name,
|
||||
BOOL create_subnets, BOOL add)
|
||||
{
|
||||
struct subnet_record *d;
|
||||
|
||||
/* XXXX andrew: struct in_addr ip appears not to be referenced at all except
|
||||
in the DEBUG comment. i assume that the DEBUG comment below actually
|
||||
intends to refer to bcast_ip? i don't know.
|
||||
|
||||
struct in_addr ip = wins_ip;
|
||||
|
||||
*/
|
||||
struct subnet_record *d = NULL;
|
||||
|
||||
if (zero_ip(bcast_ip))
|
||||
bcast_ip = *iface_bcast(bcast_ip);
|
||||
|
||||
/* add the domain into our domain database */
|
||||
/* Note that we never add into the WINS subnet as add_subnet_entry
|
||||
is only called to add our local interfaces. */
|
||||
if ((d = find_subnet(bcast_ip)) ||
|
||||
(d = make_subnet(bcast_ip, mask_ip, True)))
|
||||
{
|
||||
struct work_record *w = find_workgroupstruct(d, name, add);
|
||||
|
||||
if (!w) return NULL;
|
||||
/* Note that we should also add into the WINS subnet as add_subnet_entry
|
||||
should be called to add NetBIOS names and server entries on all
|
||||
interfaces, including the WINS interface
|
||||
*/
|
||||
|
||||
/* 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_my_name_entry(d,name,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
|
||||
add_my_name_entry(d,name,0x0 ,nb_type|NB_ACTIVE|NB_GROUP);
|
||||
}
|
||||
/* add samba server name to workgroup list. don't add
|
||||
lmhosts server entries to local interfaces */
|
||||
if (strequal(lp_workgroup(), name))
|
||||
{
|
||||
add_server_entry(d,w,myname,w->ServerType,0,lp_serverstring(),True);
|
||||
DEBUG(3,("Added server name entry %s at %s\n",
|
||||
name,inet_ntoa(bcast_ip)));
|
||||
}
|
||||
|
||||
return d;
|
||||
if(create_subnets == True)
|
||||
{
|
||||
/* Create new subnets. */
|
||||
if((d = make_subnet(bcast_ip, mask_ip, add)) == NULL)
|
||||
{
|
||||
DEBUG(0,("add_subnet_entry: Unable to create subnet %s\n",
|
||||
inet_ntoa(bcast_ip) ));
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
return d;
|
||||
}
|
||||
if(ip_equal(bcast_ip, wins_ip))
|
||||
return wins_subnet;
|
||||
return find_subnet(bcast_ip);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Add a workgroup into a subnet, and if it's our primary workgroup,
|
||||
add the required names to it.
|
||||
**************************************************************************/
|
||||
|
||||
void add_workgroup_to_subnet( struct subnet_record *d, char *group)
|
||||
{
|
||||
struct work_record *w = NULL;
|
||||
|
||||
DEBUG(5,("add_workgroup_to_subnet: Adding workgroup %s to subnet %s\n",
|
||||
group, inet_ntoa(d->bcast_ip)));
|
||||
|
||||
/* This next statement creates the workgroup struct if it doesn't
|
||||
already exist.
|
||||
*/
|
||||
if((w = find_workgroupstruct(d, group, True)) == NULL)
|
||||
{
|
||||
DEBUG(0,("add_workgroup_to_subnet: Unable to add workgroup %s to subnet %s\n",
|
||||
group, inet_ntoa(d->bcast_ip) ));
|
||||
return;
|
||||
}
|
||||
|
||||
/* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
|
||||
or register with WINS server, if it's our workgroup
|
||||
*/
|
||||
if (strequal(myworkgroup, group))
|
||||
{
|
||||
add_my_name_entry(d,group,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
|
||||
add_my_name_entry(d,group,0x0 ,nb_type|NB_ACTIVE|NB_GROUP);
|
||||
/* add samba server name to workgroup list. */
|
||||
add_server_entry(d,w,myname,w->ServerType,0,lp_serverstring(),True);
|
||||
DEBUG(3,("add_workgroup_to_subnet: Added server name entry %s to subnet %s\n",
|
||||
myname, inet_ntoa(d->bcast_ip)));
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
create subnet / workgroup / server entries
|
||||
|
||||
- add or create the subnet lists
|
||||
- add or create the workgroup entries in each subnet entry
|
||||
- register appropriate NetBIOS names for the workgroup entries
|
||||
|
||||
**************************************************************************/
|
||||
void add_my_subnets(char *group)
|
||||
{
|
||||
static BOOL create_subnets = True;
|
||||
struct subnet_record *d = NULL;
|
||||
struct interface *i = NULL;
|
||||
|
||||
if (*group == '*') return;
|
||||
|
||||
/* Create subnets from all the local interfaces and thread them onto
|
||||
the linked list.
|
||||
*/
|
||||
for (i = local_interfaces; i; i = i->next)
|
||||
{
|
||||
add_subnet_entry(i->bcast,i->nmask,group, create_subnets, True);
|
||||
}
|
||||
|
||||
/* If we are using WINS, then we must add the workgroup to the WINS
|
||||
subnet. This is used as a place to keep collated server lists.
|
||||
*/
|
||||
|
||||
/* Create the WINS subnet if we are using WINS - but don't thread it
|
||||
onto the linked subnet list.
|
||||
*/
|
||||
if (lp_wins_support() || lp_wins_server())
|
||||
{
|
||||
struct in_addr wins_nmask = ipzero;
|
||||
wins_subnet = add_subnet_entry(wins_ip, wins_nmask, group, create_subnets, False);
|
||||
}
|
||||
|
||||
/* Ensure we only create the subnets once. */
|
||||
create_subnets = False;
|
||||
|
||||
/* Now we have created all the subnets - we can add the names
|
||||
that make us a client member in the workgroup.
|
||||
*/
|
||||
for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
|
||||
add_workgroup_to_subnet(d, group);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
write out browse.dat
|
||||
|
@ -40,6 +40,8 @@ extern struct subnet_record *subnetlist;
|
||||
|
||||
extern struct in_addr wins_ip;
|
||||
|
||||
extern fstring myworkgroup;
|
||||
|
||||
int workgroup_count = 0; /* unique index key: one for each workgroup */
|
||||
|
||||
|
||||
@ -192,8 +194,8 @@ struct work_record *find_workgroupstruct(struct subnet_record *d,
|
||||
if ((work = make_workgroup(name)))
|
||||
{
|
||||
if (!ip_equal(d->bcast_ip, wins_ip) &&
|
||||
lp_preferred_master() &&
|
||||
strequal(lp_workgroup(), name))
|
||||
lp_preferred_master() && lp_local_master() &&
|
||||
strequal(myworkgroup, name))
|
||||
{
|
||||
DEBUG(3, ("preferred master startup for %s\n", work->work_group));
|
||||
work->needelection = True;
|
||||
|
@ -40,6 +40,7 @@ extern int DEBUGLEVEL;
|
||||
extern pstring scope;
|
||||
|
||||
extern pstring myname;
|
||||
extern fstring myworkgroup;
|
||||
extern struct in_addr ipzero;
|
||||
extern struct in_addr wins_ip;
|
||||
|
||||
@ -57,55 +58,59 @@ extern uint16 nb_type; /* samba's NetBIOS name type */
|
||||
******************************************************************/
|
||||
void check_master_browser(time_t t)
|
||||
{
|
||||
static time_t lastrun=0;
|
||||
struct subnet_record *d;
|
||||
static time_t lastrun=0;
|
||||
struct subnet_record *d;
|
||||
|
||||
if (!lastrun) lastrun = t;
|
||||
if (t < lastrun + CHECK_TIME_MST_BROWSE * 60) return;
|
||||
if (!lastrun) lastrun = t;
|
||||
if (t < lastrun + CHECK_TIME_MST_BROWSE * 60) return;
|
||||
|
||||
lastrun = t;
|
||||
lastrun = t;
|
||||
|
||||
dump_workgroups();
|
||||
dump_workgroups();
|
||||
|
||||
for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
|
||||
{
|
||||
struct work_record *work;
|
||||
for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
|
||||
{
|
||||
struct work_record *work;
|
||||
|
||||
for (work = d->workgrouplist; work; work = work->next)
|
||||
{
|
||||
if (strequal(work->work_group, lp_workgroup()) && !AM_MASTER(work))
|
||||
{
|
||||
if (lp_preferred_master())
|
||||
{
|
||||
/* preferred master - not a master browser. force
|
||||
becoming a master browser, hence the log message.
|
||||
*/
|
||||
for (work = d->workgrouplist; work; work = work->next)
|
||||
{
|
||||
if (strequal(work->work_group, myworkgroup) && !AM_MASTER(work))
|
||||
{
|
||||
if (lp_local_master())
|
||||
{
|
||||
/* potential master browser - not a master browser. force
|
||||
becoming a master browser, hence the log message.
|
||||
*/
|
||||
|
||||
DEBUG(0,("%s preferred master for %s %s - force election\n",
|
||||
timestring(), work->work_group,
|
||||
inet_ntoa(d->bcast_ip)));
|
||||
DEBUG(0,("%s potential master for %s %s - force election\n",
|
||||
timestring(), work->work_group,
|
||||
inet_ntoa(d->bcast_ip)));
|
||||
|
||||
browser_gone(work->work_group, d->bcast_ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if we are not the browse master of a workgroup,
|
||||
and we can't find a browser on the subnet, do
|
||||
something about it.
|
||||
*/
|
||||
browser_gone(work->work_group, d->bcast_ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if we are not the browse master of a workgroup,
|
||||
and we can't find a browser on the subnet, do
|
||||
something about it.
|
||||
*/
|
||||
|
||||
queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
|
||||
work->work_group,0x1d,0,0,0,NULL,NULL,
|
||||
True,False,d->bcast_ip,d->bcast_ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
|
||||
work->work_group,0x1d,0,0,0,NULL,NULL,
|
||||
True,False,d->bcast_ip,d->bcast_ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
what to do if a master browser DOESN't exist
|
||||
what to do if a master browser DOESN't exist.
|
||||
|
||||
option 1: force an election, and participate in it
|
||||
option 2: force an election, and let everyone else participate.
|
||||
|
||||
******************************************************************/
|
||||
void browser_gone(char *work_name, struct in_addr ip)
|
||||
{
|
||||
@ -119,24 +124,37 @@ void browser_gone(char *work_name, struct in_addr ip)
|
||||
if (ip_equal(d->bcast_ip,wins_ip))
|
||||
return;
|
||||
|
||||
if (strequal(work->work_group, lp_workgroup()))
|
||||
if (strequal(work->work_group, myworkgroup))
|
||||
{
|
||||
|
||||
if (lp_local_master())
|
||||
{
|
||||
/* we have discovered that there is no local master
|
||||
browser, and we are configured to initiate
|
||||
an election under exactly such circumstances.
|
||||
*/
|
||||
DEBUG(2,("Forcing election on %s %s\n",
|
||||
work->work_group,inet_ntoa(d->bcast_ip)));
|
||||
|
||||
/* we can attempt to become master browser */
|
||||
work->needelection = True;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* local interfaces: force an election */
|
||||
send_election(d, work->work_group, 0, 0, myname);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we need to force an election, because we are configured
|
||||
not to _become_ the local master, but we still _need_ one,
|
||||
having detected that one doesn't exist.
|
||||
*/
|
||||
|
||||
/* only removes workgroup completely on a local interface
|
||||
persistent lmhosts entries on a local interface _will_ be removed).
|
||||
*/
|
||||
remove_workgroup(d, work,True);
|
||||
/* local interfaces: force an election */
|
||||
send_election(d, work->work_group, 0, 0, myname);
|
||||
|
||||
/* only removes workgroup completely on a local interface
|
||||
persistent lmhosts entries on a local interface _will_ be removed).
|
||||
*/
|
||||
remove_workgroup(d, work,True);
|
||||
add_workgroup_to_subnet(d, work->work_group);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,15 +217,15 @@ void name_unregister_work(struct subnet_record *d, char *name, int name_type)
|
||||
{
|
||||
remove_type_local |= SV_TYPE_MASTER_BROWSER;
|
||||
}
|
||||
if (AM_MASTER(work) && strequal(name, lp_workgroup()) && name_type == 0x1d)
|
||||
if (AM_MASTER(work) && strequal(name, myworkgroup) && name_type == 0x1d)
|
||||
{
|
||||
remove_type_local |= SV_TYPE_MASTER_BROWSER;
|
||||
}
|
||||
if (AM_DOMMST(work) && strequal(name, lp_workgroup()) && name_type == 0x1b)
|
||||
if (AM_DOMMST(work) && strequal(name, myworkgroup) && name_type == 0x1b)
|
||||
{
|
||||
remove_type_domain |= SV_TYPE_DOMAIN_MASTER;
|
||||
}
|
||||
if (AM_DOMMEM(work) && strequal(name, lp_workgroup()) && name_type == 0x1c)
|
||||
if (AM_DOMMEM(work) && strequal(name, myworkgroup) && name_type == 0x1c)
|
||||
{
|
||||
remove_type_logon|= SV_TYPE_DOMAIN_MEMBER;
|
||||
}
|
||||
@ -228,47 +246,48 @@ void name_unregister_work(struct subnet_record *d, char *name, int name_type)
|
||||
void name_register_work(struct subnet_record *d, char *name, int name_type,
|
||||
int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast)
|
||||
{
|
||||
enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ?
|
||||
enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ?
|
||||
SELF : REGISTER;
|
||||
|
||||
if (source == SELF)
|
||||
{
|
||||
struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
|
||||
if (source == SELF)
|
||||
{
|
||||
struct work_record *work = find_workgroupstruct(d,
|
||||
myworkgroup, False);
|
||||
|
||||
add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
|
||||
add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
|
||||
|
||||
if (work)
|
||||
{
|
||||
int add_type_local = False;
|
||||
int add_type_domain = False;
|
||||
int add_type_logon = False;
|
||||
if (work)
|
||||
{
|
||||
int add_type_local = False;
|
||||
int add_type_domain = False;
|
||||
int add_type_logon = False;
|
||||
|
||||
DEBUG(4,("checking next stage: name_register_work %s\n", name));
|
||||
DEBUG(4,("checking next stage: name_register_work %s\n", name));
|
||||
|
||||
/* work out what to become, from the name type being added */
|
||||
/* work out what to become, from the name type being added */
|
||||
|
||||
if (ms_browser_name(name, name_type))
|
||||
{
|
||||
add_type_local = True;
|
||||
}
|
||||
if (strequal(name, lp_workgroup()) && name_type == 0x1d)
|
||||
{
|
||||
add_type_local = True;
|
||||
}
|
||||
if (strequal(name, lp_workgroup()) && name_type == 0x1b)
|
||||
{
|
||||
add_type_domain = True;
|
||||
}
|
||||
if (strequal(name, lp_workgroup()) && name_type == 0x1c)
|
||||
{
|
||||
add_type_logon = True;
|
||||
}
|
||||
if (ms_browser_name(name, name_type))
|
||||
{
|
||||
add_type_local = True;
|
||||
}
|
||||
if (strequal(name, myworkgroup) && name_type == 0x1d)
|
||||
{
|
||||
add_type_local = True;
|
||||
}
|
||||
if (strequal(name, myworkgroup) && name_type == 0x1b)
|
||||
{
|
||||
add_type_domain = True;
|
||||
}
|
||||
if (strequal(name, myworkgroup) && name_type == 0x1c)
|
||||
{
|
||||
add_type_logon = True;
|
||||
}
|
||||
|
||||
if (add_type_local ) become_local_master (d, work);
|
||||
if (add_type_domain) become_domain_master(d, work);
|
||||
if (add_type_logon ) become_logon_server (d, work);
|
||||
}
|
||||
}
|
||||
if (add_type_local ) become_local_master (d, work);
|
||||
if (add_type_domain) become_domain_master(d, work);
|
||||
if (add_type_logon ) become_logon_server (d, work);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -303,17 +322,18 @@ void become_local_master(struct subnet_record *d, struct work_record *work)
|
||||
*/
|
||||
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
|
||||
|
||||
if (!work || !d) return;
|
||||
if (!work || !d)
|
||||
return;
|
||||
|
||||
DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
|
||||
work->work_group,inet_ntoa(d->bcast_ip),work->mst_state));
|
||||
work->work_group,inet_ntoa(d->bcast_ip),work->mst_state));
|
||||
|
||||
switch (work->mst_state)
|
||||
{
|
||||
case MST_POTENTIAL: /* while we were nothing but a server... */
|
||||
{
|
||||
DEBUG(3,("go to first stage: register ^1^2__MSBROWSE__^2^1\n"));
|
||||
work->mst_state = MST_BACK; /* ... an election win was successful */
|
||||
work->mst_state = MST_BACK; /* an election win was successful */
|
||||
|
||||
work->ElectionCriterion |= 0x5;
|
||||
|
||||
@ -322,7 +342,7 @@ void become_local_master(struct subnet_record *d, struct work_record *work)
|
||||
add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
|
||||
|
||||
/* add special browser name */
|
||||
add_my_name_entry(d,MSBROWSE ,0x01,nb_type|NB_ACTIVE|NB_GROUP);
|
||||
add_my_name_entry(d,MSBROWSE,0x01,nb_type|NB_ACTIVE|NB_GROUP);
|
||||
|
||||
/* DON'T do anything else after calling add_my_name_entry() */
|
||||
break;
|
||||
@ -331,7 +351,7 @@ void become_local_master(struct subnet_record *d, struct work_record *work)
|
||||
case MST_BACK: /* while nothing had happened except we won an election... */
|
||||
{
|
||||
DEBUG(3,("go to second stage: register as master browser\n"));
|
||||
work->mst_state = MST_MSB; /* ... registering MSBROWSE was successful */
|
||||
work->mst_state = MST_MSB; /* registering MSBROWSE was successful */
|
||||
|
||||
/* add server entry on successful registration of MSBROWSE */
|
||||
add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
|
||||
@ -346,49 +366,33 @@ void become_local_master(struct subnet_record *d, struct work_record *work)
|
||||
case MST_MSB: /* while we were still only registered MSBROWSE state... */
|
||||
{
|
||||
DEBUG(3,("2nd stage complete: registered as master browser\n"));
|
||||
work->mst_state = MST_BROWSER; /* ... registering WORKGROUP(1d) succeeded */
|
||||
work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
|
||||
|
||||
/* update our server status */
|
||||
work->ServerType |= SV_TYPE_MASTER_BROWSER;
|
||||
|
||||
DEBUG(3,("become_local_master: updating our server %s to type %x\n", myname, work->ServerType));
|
||||
DEBUG(3,("become_local_master: updating our server %s to type %x\n",
|
||||
myname, work->ServerType));
|
||||
|
||||
add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
|
||||
|
||||
if (work->serverlist == NULL) /* no servers! */
|
||||
{
|
||||
/* ask all servers on our local net to announce to us */
|
||||
/* XXXX OOPS! add_server_entry will always add one entry - our own. */
|
||||
/* XXXX OOPS! add_server_entry always adds one entry - ours. */
|
||||
announce_request(work, d->bcast_ip);
|
||||
}
|
||||
|
||||
/* If we have WINS support or are a WINS server we must add
|
||||
the workgroup we just became master browser for to the
|
||||
WINS subnet. This is needed so we have somewhere to save
|
||||
server lists when we do browser synchronization. */
|
||||
if(wins_subnet != 0)
|
||||
{
|
||||
if(find_workgroupstruct(wins_subnet, work->work_group, True) == 0)
|
||||
DEBUG(0, ("become_local_master: \
|
||||
Failed to add workgroup %s to WINS subnet.\n",
|
||||
work->work_group));
|
||||
else
|
||||
DEBUG(3, ("become_local_master: Added workgroup %s to WINS subnet.\n",
|
||||
work->work_group));
|
||||
|
||||
/* Reset the announce master timer so that we do an announce as soon as possible
|
||||
now we are a master. */
|
||||
reset_announce_timer();
|
||||
}
|
||||
/* Reset the announce master timer so that we do an announce as soon as possible
|
||||
now we are a master. */
|
||||
reset_announce_timer();
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case MST_BROWSER:
|
||||
{
|
||||
/* don't have to do anything: just report success */
|
||||
DEBUG(3,("3rd stage: become master browser!\n"));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -438,7 +442,7 @@ void become_domain_master(struct subnet_record *d, struct work_record *work)
|
||||
work->dom_state = DOMAIN_WAIT;
|
||||
|
||||
/* XXXX the 0x1b is domain master browser name */
|
||||
add_my_name_entry(d, lp_workgroup(),0x1b,nb_type|NB_ACTIVE|NB_GROUP);
|
||||
add_my_name_entry(d, myworkgroup,0x1b,nb_type|NB_ACTIVE|NB_GROUP);
|
||||
|
||||
/* DON'T do anything else after calling add_my_name_entry() */
|
||||
break;
|
||||
@ -505,7 +509,7 @@ void become_logon_server(struct subnet_record *d, struct work_record *work)
|
||||
work->log_state = LOGON_WAIT;
|
||||
|
||||
/* XXXX the 0x1c is apparently something to do with domain logons */
|
||||
add_my_name_entry(d, lp_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP);
|
||||
add_my_name_entry(d, myworkgroup,0x1c,nb_type|NB_ACTIVE|NB_GROUP);
|
||||
|
||||
/* DON'T do anything else after calling add_my_name_entry() */
|
||||
break;
|
||||
@ -749,7 +753,7 @@ void process_election(struct packet_struct *p,char *buf)
|
||||
|
||||
for (work = d->workgrouplist; work; work = work->next)
|
||||
{
|
||||
if (!strequal(work->work_group, lp_workgroup()))
|
||||
if (!strequal(work->work_group, myworkgroup))
|
||||
continue;
|
||||
|
||||
if (win_election(work, version,criterion,timeup,name)) {
|
||||
|
@ -263,13 +263,13 @@ struct response_record *queue_netbios_pkt_wins(
|
||||
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());
|
||||
struct in_addr real_wins_ip;
|
||||
real_wins_ip = *interpret_addr2(lp_wins_server());
|
||||
|
||||
if (!zero_ip(wins_ip))
|
||||
if (!zero_ip(real_wins_ip))
|
||||
{
|
||||
bcast = False;
|
||||
send_ip = wins_ip;
|
||||
send_ip = real_wins_ip;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -37,6 +37,7 @@ extern int DEBUGLEVEL;
|
||||
|
||||
extern pstring scope;
|
||||
extern pstring myname;
|
||||
extern fstring myworkgroup;
|
||||
extern struct in_addr ipzero;
|
||||
extern struct in_addr wins_ip;
|
||||
|
||||
@ -141,6 +142,9 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(4,("add_my_name_entry registering name %s with WINS server.\n",
|
||||
name));
|
||||
|
||||
/* a time-to-live allows us to refresh this name with the WINS server. */
|
||||
queue_netbios_pkt_wins(ClientNMB,
|
||||
re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
|
||||
@ -179,33 +183,32 @@ void add_domain_names(time_t t)
|
||||
|
||||
for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
|
||||
{
|
||||
work = find_workgroupstruct(d, lp_workgroup(), False);
|
||||
work = find_workgroupstruct(d, myworkgroup, False);
|
||||
if (lp_domain_logons() && work && work->log_state == LOGON_NONE)
|
||||
{
|
||||
make_nmb_name(&n,lp_workgroup(),0x1c,scope);
|
||||
make_nmb_name(&n,myworkgroup,0x1c,scope);
|
||||
if (!find_name(d->namelist, &n, FIND_SELF))
|
||||
{
|
||||
/* logon servers are group names - we don't expect this to fail. */
|
||||
DEBUG(0,("%s attempting to become logon server for %s %s\n",
|
||||
timestring(), lp_workgroup(), inet_ntoa(d->bcast_ip)));
|
||||
timestring(), myworkgroup, inet_ntoa(d->bcast_ip)));
|
||||
become_logon_server(d, work);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(wins_subnet != 0)
|
||||
work = find_workgroupstruct(wins_subnet, lp_workgroup(), False);
|
||||
for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
|
||||
{
|
||||
work = find_workgroupstruct(d, myworkgroup, True);
|
||||
|
||||
if (lp_domain_master() && work && work->dom_state == DOMAIN_NONE)
|
||||
{
|
||||
|
||||
DEBUG(0,("add_domain_names:Checking for domain master on workgroup %s\n", lp_workgroup()));
|
||||
|
||||
make_nmb_name(&n,lp_workgroup(),0x1b,scope);
|
||||
if (!find_name(wins_subnet->namelist, &n, FIND_SELF))
|
||||
if (lp_domain_master() && work && work->dom_state == DOMAIN_NONE)
|
||||
{
|
||||
make_nmb_name(&n,myworkgroup,0x1b,scope);
|
||||
if (!find_name(d->namelist, &n, FIND_SELF))
|
||||
{
|
||||
DEBUG(0,("add_domain_names: attempting to become domain master browser on workgroup %s\n",
|
||||
lp_workgroup()));
|
||||
DEBUG(0,("%s add_domain_names: attempting to become domain master \
|
||||
browser on workgroup %s %s\n",
|
||||
timestring(), myworkgroup, inet_ntoa(d->bcast_ip)));
|
||||
|
||||
if (lp_wins_support())
|
||||
{
|
||||
@ -216,8 +219,8 @@ void add_domain_names(time_t t)
|
||||
*/
|
||||
|
||||
DEBUG(1,("%s initiating becoming domain master for %s\n",
|
||||
timestring(), lp_workgroup()));
|
||||
become_domain_master(wins_subnet, work);
|
||||
timestring(), myworkgroup));
|
||||
become_domain_master(d, work);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -228,15 +231,17 @@ void add_domain_names(time_t t)
|
||||
NetBIOS name 0x1b.
|
||||
*/
|
||||
|
||||
DEBUG(0,("add_domain_names:querying WINS for domain master on workgroup %s\n", lp_workgroup()));
|
||||
DEBUG(0,("add_domain_names:querying WINS for domain master \
|
||||
on workgroup %s\n", myworkgroup));
|
||||
|
||||
queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,NAME_QUERY_DOMAIN,
|
||||
lp_workgroup(), 0x1b,
|
||||
myworkgroup, 0x1b,
|
||||
0, 0,0,NULL,NULL,
|
||||
False, False, ipzero, ipzero);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -255,7 +260,6 @@ void add_my_names(void)
|
||||
for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
|
||||
{
|
||||
BOOL wins = (lp_wins_support() && (d == wins_subnet));
|
||||
struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
|
||||
|
||||
add_my_name_entry(d, myname,0x20,nb_type|NB_ACTIVE);
|
||||
add_my_name_entry(d, myname,0x03,nb_type|NB_ACTIVE);
|
||||
|
@ -528,7 +528,8 @@ void reply_name_query(struct packet_struct *p)
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(3,("Name query "));
|
||||
DEBUG(3,("Name query from %s for name %s<0x%x>\n",
|
||||
inet_ntoa(p->ip), question->name, question->name_type));
|
||||
|
||||
if (search == 0)
|
||||
{
|
||||
|
@ -37,6 +37,7 @@ extern pstring scope;
|
||||
extern BOOL CanRecurse;
|
||||
|
||||
extern pstring myname;
|
||||
extern fstring myworkgroup;
|
||||
|
||||
extern int ClientNMB;
|
||||
extern int ClientDGRAM;
|
||||
@ -603,7 +604,7 @@ static void process_reset_browser(struct packet_struct *p,char *buf)
|
||||
struct work_record *work;
|
||||
for (work=d->workgrouplist;work;work=remove_workgroup(d,work,True));
|
||||
}
|
||||
add_my_subnets(lp_workgroup());
|
||||
add_my_subnets(myworkgroup);
|
||||
}
|
||||
|
||||
/* stop browsing altogether. i don't think this is a good idea! */
|
||||
@ -639,7 +640,7 @@ static void process_announce_request(struct packet_struct *p,char *buf)
|
||||
this workgroup before announcing, particularly as we only
|
||||
respond on local interfaces anyway.
|
||||
|
||||
if (strequal(dgram->dest_name, lp_workgroup()) return; ???
|
||||
if (strequal(dgram->dest_name, myworkgroup) return; ???
|
||||
*/
|
||||
|
||||
if (!d)
|
||||
|
@ -40,6 +40,7 @@ int ClientDGRAM = -1;
|
||||
extern pstring myhostname;
|
||||
static pstring host_file;
|
||||
extern pstring myname;
|
||||
extern fstring myworkgroup;
|
||||
|
||||
/* are we running as a daemon ? */
|
||||
static BOOL is_daemon = False;
|
||||
@ -67,7 +68,7 @@ static int sig_term()
|
||||
|
||||
/* announce all server entries as 0 time-to-live, 0 type */
|
||||
/* XXXX don't care if we never receive a response back... yet */
|
||||
remove_my_servers();
|
||||
announce_my_servers_removed();
|
||||
|
||||
/* XXXX other things: if we are a master browser, force an election? */
|
||||
|
||||
@ -203,9 +204,6 @@ BOOL reload_services(BOOL test)
|
||||
reload_services(True);
|
||||
}
|
||||
|
||||
load_interfaces();
|
||||
add_subnet_interfaces();
|
||||
|
||||
/* Do a sanity check for a misconfigured nmbd */
|
||||
if(lp_wins_support() && *lp_wins_server()) {
|
||||
DEBUG(0,("ERROR: both 'wins support = true' and 'wins server = <server>' \
|
||||
@ -502,6 +500,8 @@ static void usage(char *pname)
|
||||
|
||||
reload_services(True);
|
||||
|
||||
strcpy(myworkgroup, lp_workgroup());
|
||||
|
||||
set_samba_nb_type();
|
||||
|
||||
if (!is_daemon && !is_a_socket(0)) {
|
||||
@ -549,15 +549,16 @@ static void usage(char *pname)
|
||||
DEBUG(3,("Loaded hosts file\n"));
|
||||
}
|
||||
|
||||
load_interfaces();
|
||||
add_my_subnets(myworkgroup);
|
||||
|
||||
add_my_names();
|
||||
|
||||
if (strequal(lp_workgroup(),"*")) {
|
||||
if (strequal(myworkgroup,"*")) {
|
||||
DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
add_my_subnets(lp_workgroup());
|
||||
|
||||
DEBUG(3,("Checked names\n"));
|
||||
|
||||
load_netbios_names();
|
||||
|
@ -152,8 +152,11 @@ typedef struct
|
||||
int os_level;
|
||||
int max_ttl;
|
||||
int ReadSize;
|
||||
int shmem_size;
|
||||
int shmem_hash_size;
|
||||
BOOL bWINSsupport;
|
||||
BOOL bWINSproxy;
|
||||
BOOL bLocalMaster;
|
||||
BOOL bPreferredMaster;
|
||||
BOOL bDomainMaster;
|
||||
BOOL bDomainLogons;
|
||||
@ -427,6 +430,8 @@ struct parm_struct
|
||||
{"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL},
|
||||
{"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL},
|
||||
{"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL},
|
||||
{"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL},
|
||||
{"shared file entries", P_INTEGER, P_GLOBAL, &Globals.shmem_hash_size, NULL},
|
||||
#ifdef KANJI
|
||||
{"coding system", P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system},
|
||||
#endif /* KANJI */
|
||||
@ -437,6 +442,7 @@ struct parm_struct
|
||||
{"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},
|
||||
{"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL},
|
||||
{"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL},
|
||||
{"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL},
|
||||
{"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL},
|
||||
@ -601,15 +607,11 @@ static void init_globals(void)
|
||||
Globals.bSyslogOnly = False;
|
||||
Globals.os_level = 0;
|
||||
Globals.max_ttl = 60*60*4; /* 2 hours default */
|
||||
Globals.bPreferredMaster = True;
|
||||
Globals.bDomainMaster = False;
|
||||
Globals.bDomainLogons = False;
|
||||
Globals.bBrowseList = True;
|
||||
Globals.bWINSsupport = False;
|
||||
Globals.bWINSproxy = False;
|
||||
Globals.ReadSize = 16*1024;
|
||||
Globals.shmem_size = SHMEM_SIZE;
|
||||
Globals.shmem_hash_size = SHMEM_HASH_SIZE;
|
||||
Globals.bUnixRealname = False;
|
||||
#ifdef NETGROUP
|
||||
#if (defined(NETGROUP) && defined(AUTOMOUNT))
|
||||
Globals.bNISHomeMap = False;
|
||||
string_set(&Globals.szNISHomeMapName, "auto.home");
|
||||
#endif
|
||||
@ -617,6 +619,25 @@ static void init_globals(void)
|
||||
coding_system = interpret_coding_system (KANJI, SJIS_CODE);
|
||||
#endif /* KANJI */
|
||||
|
||||
/* these parameters are set to defaults that are more appropriate
|
||||
for the increasing samba install base:
|
||||
|
||||
as a member of the workgroup, that will possibly become a
|
||||
_local_ master browser (lm = True). this is opposed to a forced
|
||||
local master browser startup (pm = True).
|
||||
|
||||
doesn't provide WINS server service by default (wsupp = False),
|
||||
and doesn't provide domain master browser services by default, either.
|
||||
|
||||
*/
|
||||
|
||||
Globals.bPreferredMaster = False;
|
||||
Globals.bLocalMaster = True;
|
||||
Globals.bDomainMaster = False;
|
||||
Globals.bDomainLogons = False;
|
||||
Globals.bBrowseList = True;
|
||||
Globals.bWINSsupport = False;
|
||||
Globals.bWINSproxy = False;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
@ -771,6 +792,7 @@ FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
|
||||
|
||||
FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
|
||||
FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
|
||||
FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
|
||||
FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
|
||||
FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
|
||||
FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
|
||||
@ -799,6 +821,8 @@ FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
|
||||
FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
|
||||
FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
|
||||
FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
|
||||
FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
|
||||
FN_GLOBAL_INTEGER(lp_shmem_hash_size,&Globals.shmem_hash_size)
|
||||
FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
|
||||
FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
|
||||
FN_GLOBAL_INTEGER(lp_security,&Globals.security)
|
||||
|
@ -433,6 +433,7 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo
|
||||
BOOL isrootdir;
|
||||
pstring filename;
|
||||
BOOL matched;
|
||||
BOOL needslash;
|
||||
|
||||
*path = *pathreal = *filename = 0;
|
||||
|
||||
@ -440,6 +441,9 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo
|
||||
strequal(Connections[cnum].dirpath,".") ||
|
||||
strequal(Connections[cnum].dirpath,"/"));
|
||||
|
||||
needslash =
|
||||
( Connections[cnum].dirpath[strlen(Connections[cnum].dirpath) -1] != '/');
|
||||
|
||||
if (!Connections[cnum].dirptr)
|
||||
return(False);
|
||||
|
||||
@ -467,7 +471,8 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo
|
||||
strcpy(fname,filename);
|
||||
*path = 0;
|
||||
strcpy(path,Connections[cnum].dirpath);
|
||||
strcat(path,"/");
|
||||
if(needslash)
|
||||
strcat(path,"/");
|
||||
strcpy(pathreal,path);
|
||||
strcat(path,fname);
|
||||
strcat(pathreal,dname);
|
||||
|
@ -37,6 +37,7 @@ extern files_struct Files[];
|
||||
extern connection_struct Connections[];
|
||||
|
||||
extern fstring local_machine;
|
||||
extern fstring myworkgroup;
|
||||
|
||||
#define NERR_Success 0
|
||||
#define NERR_badpass 86
|
||||
@ -812,7 +813,7 @@ static int get_server_info(uint32 servertype,
|
||||
if (!next_token(&ptr,s->comment, NULL)) continue;
|
||||
if (!next_token(&ptr,s->domain , NULL)) {
|
||||
/* this allows us to cope with an old nmbd */
|
||||
strcpy(s->domain,lp_workgroup());
|
||||
strcpy(s->domain,myworkgroup);
|
||||
}
|
||||
|
||||
if (sscanf(stype,"%X",&s->type) != 1) {
|
||||
@ -982,7 +983,7 @@ static BOOL api_RNetServerEnum(int cnum, uint16 vuid, char *param, char *data,
|
||||
if (strcmp(str1, "WrLehDz") == 0) {
|
||||
StrnCpy(domain, p, sizeof(fstring)-1);
|
||||
} else {
|
||||
StrnCpy(domain, lp_workgroup(), sizeof(fstring)-1);
|
||||
StrnCpy(domain, myworkgroup, sizeof(fstring)-1);
|
||||
}
|
||||
|
||||
if (lp_browse_list())
|
||||
@ -1668,7 +1669,7 @@ static BOOL api_RNetServerGetInfo(int cnum,uint16 vuid, char *param,char *data,
|
||||
|
||||
strcpy(comment,lp_serverstring());
|
||||
|
||||
if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) {
|
||||
if ((count=get_server_info(SV_TYPE_ALL,&servers,myworkgroup))>0) {
|
||||
for (i=0;i<count;i++)
|
||||
if (strequal(servers[i].name,local_machine))
|
||||
{
|
||||
@ -1754,7 +1755,7 @@ static BOOL api_NetWkstaGetInfo(int cnum,uint16 vuid, char *param,char *data,
|
||||
p += 4;
|
||||
|
||||
SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* login domain */
|
||||
strcpy(p2,lp_workgroup());
|
||||
strcpy(p2,myworkgroup);
|
||||
strupper(p2);
|
||||
p2 = skip_string(p2,1);
|
||||
p += 4;
|
||||
@ -1764,7 +1765,7 @@ static BOOL api_NetWkstaGetInfo(int cnum,uint16 vuid, char *param,char *data,
|
||||
p += 2;
|
||||
|
||||
SIVAL(p,0,PTR_DIFF(p2,*rdata));
|
||||
strcpy(p2,lp_workgroup()); /* don't know. login domain?? */
|
||||
strcpy(p2,myworkgroup); /* don't know. login domain?? */
|
||||
p2 = skip_string(p2,1);
|
||||
p += 4;
|
||||
|
||||
@ -2228,7 +2229,7 @@ static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data,
|
||||
strcpy(mypath,"\\\\");
|
||||
strcat(mypath,local_machine);
|
||||
strupper(mypath);
|
||||
PACKS(&desc,"z",mypath); /* computer */
|
||||
PACKS(&desc,"z",mypath); /* computer */
|
||||
}
|
||||
PACKS(&desc,"z",myworkgroup);/* domain */
|
||||
PACKS(&desc,"z",lp_logon_script()); /* script path */
|
||||
|
@ -42,6 +42,7 @@ extern files_struct Files[];
|
||||
extern BOOL case_sensitive;
|
||||
extern pstring sesssetup_user;
|
||||
extern int Client;
|
||||
extern fstring myworkgroup;
|
||||
|
||||
/* this macro should always be used to extract an fnum (smb_fid) from
|
||||
a packet to ensure chaining works correctly */
|
||||
@ -250,7 +251,7 @@ static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
|
||||
{
|
||||
uint32 dword1;
|
||||
uint16 word1;
|
||||
char * workgroup = lp_workgroup();
|
||||
char * workgroup = myworkgroup;
|
||||
int wglen = strlen(workgroup);
|
||||
int i;
|
||||
|
||||
|
@ -40,6 +40,7 @@ extern BOOL case_sensitive;
|
||||
extern BOOL case_preserve;
|
||||
extern BOOL short_case_preserve;
|
||||
extern pstring sesssetup_user;
|
||||
extern fstring myworkgroup;
|
||||
extern int Client;
|
||||
|
||||
/* this macro should always be used to extract an fnum (smb_fid) from
|
||||
@ -480,7 +481,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
|
||||
p = smb_buf(outbuf);
|
||||
strcpy(p,"Unix"); p = skip_string(p,1);
|
||||
strcpy(p,"Samba "); strcat(p,VERSION); p = skip_string(p,1);
|
||||
strcpy(p,lp_workgroup()); p = skip_string(p,1);
|
||||
strcpy(p,myworkgroup); p = skip_string(p,1);
|
||||
set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
|
||||
/* perhaps grab OS version here?? */
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
pstring servicesf = CONFIGFILE;
|
||||
extern pstring debugf;
|
||||
extern pstring sesssetup_user;
|
||||
extern fstring myworkgroup;
|
||||
|
||||
char *InBuffer = NULL;
|
||||
char *OutBuffer = NULL;
|
||||
@ -33,8 +34,6 @@ char *last_inbuf = NULL;
|
||||
int am_parent = 1;
|
||||
int atexit_set = 0;
|
||||
|
||||
BOOL share_mode_pending = False;
|
||||
|
||||
/* the last message the was processed */
|
||||
int last_message = -1;
|
||||
|
||||
@ -113,6 +112,7 @@ static int find_free_connection(int hash);
|
||||
void *dflt_sig(void)
|
||||
{
|
||||
exit_server("caught signal");
|
||||
return 0; /* Keep -Wall happy :-) */
|
||||
}
|
||||
/****************************************************************************
|
||||
Send a SIGTERM to our process group.
|
||||
@ -837,8 +837,8 @@ file_fd_struct *fd_get_already_open(struct stat *sbuf)
|
||||
for(i = 0; i <= max_file_fd_used; i++) {
|
||||
fd_ptr = &FileFd[i];
|
||||
if((fd_ptr->ref_count > 0) &&
|
||||
(((int32)sbuf->st_dev) == fd_ptr->dev) &&
|
||||
(((int32)sbuf->st_ino) == fd_ptr->inode)) {
|
||||
(((uint32)sbuf->st_dev) == fd_ptr->dev) &&
|
||||
(((uint32)sbuf->st_ino) == fd_ptr->inode)) {
|
||||
fd_ptr->ref_count++;
|
||||
DEBUG(3,
|
||||
("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
|
||||
@ -861,8 +861,8 @@ file_fd_struct *fd_get_new()
|
||||
for(i = 0; i < MAX_OPEN_FILES; i++) {
|
||||
fd_ptr = &FileFd[i];
|
||||
if(fd_ptr->ref_count == 0) {
|
||||
fd_ptr->dev = (int32)-1;
|
||||
fd_ptr->inode = (int32)-1;
|
||||
fd_ptr->dev = (uint32)-1;
|
||||
fd_ptr->inode = (uint32)-1;
|
||||
fd_ptr->fd = -1;
|
||||
fd_ptr->fd_readonly = -1;
|
||||
fd_ptr->fd_writeonly = -1;
|
||||
@ -927,8 +927,8 @@ int fd_attempt_close(file_fd_struct *fd_ptr)
|
||||
fd_ptr->fd_readonly = -1;
|
||||
fd_ptr->fd_writeonly = -1;
|
||||
fd_ptr->real_open_flags = -1;
|
||||
fd_ptr->dev = -1;
|
||||
fd_ptr->inode = -1;
|
||||
fd_ptr->dev = (uint32)-1;
|
||||
fd_ptr->inode = (uint32)-1;
|
||||
}
|
||||
}
|
||||
return fd_ptr->ref_count;
|
||||
@ -1124,8 +1124,8 @@ void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *s
|
||||
sbuf = &statbuf;
|
||||
}
|
||||
/* Set the correct entries in fd_ptr. */
|
||||
fd_ptr->dev = (int32)sbuf->st_dev;
|
||||
fd_ptr->inode = (int32)sbuf->st_ino;
|
||||
fd_ptr->dev = (uint32)sbuf->st_dev;
|
||||
fd_ptr->inode = (uint32)sbuf->st_ino;
|
||||
|
||||
Files[fnum].fd_ptr = fd_ptr;
|
||||
Connections[cnum].num_files_open++;
|
||||
@ -1141,7 +1141,6 @@ void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *s
|
||||
Files[fnum].can_read = ((flags & O_WRONLY)==0);
|
||||
Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
|
||||
Files[fnum].share_mode = 0;
|
||||
Files[fnum].share_pending = False;
|
||||
Files[fnum].print_file = Connections[cnum].printer;
|
||||
Files[fnum].modified = False;
|
||||
Files[fnum].cnum = cnum;
|
||||
@ -1241,38 +1240,49 @@ close a file - possibly invalidating the read prediction
|
||||
****************************************************************************/
|
||||
void close_file(int fnum)
|
||||
{
|
||||
int cnum = Files[fnum].cnum;
|
||||
invalidate_read_prediction(Files[fnum].fd_ptr->fd);
|
||||
Files[fnum].open = False;
|
||||
files_struct *fs_p = &Files[fnum];
|
||||
int cnum = fs_p->cnum;
|
||||
uint32 dev = fs_p->fd_ptr->dev;
|
||||
uint32 inode = fs_p->fd_ptr->inode;
|
||||
share_lock_token token;
|
||||
|
||||
invalidate_read_prediction(fs_p->fd_ptr->fd);
|
||||
fs_p->open = False;
|
||||
Connections[cnum].num_files_open--;
|
||||
if(Files[fnum].wbmpx_ptr)
|
||||
if(fs_p->wbmpx_ptr)
|
||||
{
|
||||
free((char *)Files[fnum].wbmpx_ptr);
|
||||
Files[fnum].wbmpx_ptr = NULL;
|
||||
free((char *)fs_p->wbmpx_ptr);
|
||||
fs_p->wbmpx_ptr = NULL;
|
||||
}
|
||||
|
||||
#if USE_MMAP
|
||||
if(Files[fnum].mmap_ptr)
|
||||
if(fs_p->mmap_ptr)
|
||||
{
|
||||
munmap(Files[fnum].mmap_ptr,Files[fnum].mmap_size);
|
||||
Files[fnum].mmap_ptr = NULL;
|
||||
munmap(fs_p->mmap_ptr,fs_p->mmap_size);
|
||||
fs_p->mmap_ptr = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (lp_share_modes(SNUM(cnum)))
|
||||
del_share_mode(fnum);
|
||||
{
|
||||
lock_share_entry( cnum, dev, inode, &token);
|
||||
del_share_mode(token, fnum);
|
||||
}
|
||||
|
||||
fd_attempt_close(Files[fnum].fd_ptr);
|
||||
fd_attempt_close(fs_p->fd_ptr);
|
||||
|
||||
if (lp_share_modes(SNUM(cnum)))
|
||||
unlock_share_entry( cnum, dev, inode, token);
|
||||
|
||||
/* NT uses smbclose to start a print - weird */
|
||||
if (Files[fnum].print_file)
|
||||
if (fs_p->print_file)
|
||||
print_file(fnum);
|
||||
|
||||
/* check for magic scripts */
|
||||
check_magic(fnum,cnum);
|
||||
|
||||
DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
|
||||
timestring(),Connections[cnum].user,Files[fnum].name,
|
||||
timestring(),Connections[cnum].user,fs_p->name,
|
||||
Connections[cnum].num_files_open));
|
||||
}
|
||||
|
||||
@ -1334,17 +1344,44 @@ return True if sharing doesn't prevent the operation
|
||||
********************************************************************/
|
||||
BOOL check_file_sharing(int cnum,char *fname)
|
||||
{
|
||||
int pid=0;
|
||||
int share_mode = get_share_mode_byname(cnum,fname,&pid);
|
||||
int i;
|
||||
int ret = False;
|
||||
min_share_mode_entry *old_shares = 0;
|
||||
int num_share_modes;
|
||||
struct stat sbuf;
|
||||
share_lock_token token;
|
||||
int pid = getpid();
|
||||
|
||||
if (!pid || !share_mode) return(True);
|
||||
|
||||
if (share_mode == DENY_DOS)
|
||||
return(pid == getpid());
|
||||
if(!lp_share_modes(SNUM(cnum)))
|
||||
return True;
|
||||
|
||||
if (stat(fname,&sbuf) == -1) return(True);
|
||||
|
||||
lock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &token);
|
||||
num_share_modes = get_share_modes(cnum, token,
|
||||
(uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &old_shares);
|
||||
|
||||
for( i = 0; i < num_share_modes; i++)
|
||||
{
|
||||
if (old_shares[i].share_mode != DENY_DOS)
|
||||
goto free_and_exit;
|
||||
|
||||
if(old_shares[i].pid != pid);
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
/* XXXX exactly what share mode combinations should be allowed for
|
||||
deleting/renaming? */
|
||||
return(False);
|
||||
/* If we got here then either there were no share modes or
|
||||
all share modes were DENY_DOS and the pid == getpid() */
|
||||
ret = True;
|
||||
|
||||
free_and_exit:
|
||||
|
||||
unlock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, token);
|
||||
if(old_shares != NULL)
|
||||
free((char *)old_shares);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1373,25 +1410,31 @@ open a file with a share mode
|
||||
void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
|
||||
int mode,int *Access,int *action)
|
||||
{
|
||||
files_struct *fs_p = &Files[fnum];
|
||||
int flags=0;
|
||||
int flags2=0;
|
||||
int deny_mode = (share_mode>>4)&7;
|
||||
struct stat sbuf;
|
||||
BOOL file_existed = file_exist(fname,&sbuf);
|
||||
BOOL share_locked = False;
|
||||
BOOL fcbopen = False;
|
||||
int share_pid=0;
|
||||
share_lock_token token;
|
||||
uint32 dev = 0;
|
||||
uint32 inode = 0;
|
||||
|
||||
Files[fnum].open = False;
|
||||
Files[fnum].fd_ptr = 0;
|
||||
fs_p->open = False;
|
||||
fs_p->fd_ptr = 0;
|
||||
|
||||
/* this is for OS/2 EAs - try and say we don't support them */
|
||||
if (strstr(fname,".+,;=[].")) {
|
||||
if (strstr(fname,".+,;=[]."))
|
||||
{
|
||||
unix_ERR_class = ERRDOS;
|
||||
unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ofun & 0x3) == 0 && file_existed) {
|
||||
if ((ofun & 0x3) == 0 && file_existed)
|
||||
{
|
||||
errno = EEXIST;
|
||||
return;
|
||||
}
|
||||
@ -1405,7 +1448,7 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
|
||||
append does not mean the same thing under dos and unix */
|
||||
|
||||
switch (share_mode&0xF)
|
||||
{
|
||||
{
|
||||
case 1:
|
||||
flags = O_WRONLY;
|
||||
break;
|
||||
@ -1419,18 +1462,21 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
|
||||
default:
|
||||
flags = O_RDONLY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags != O_RDONLY && file_existed &&
|
||||
(!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) {
|
||||
if (!fcbopen) {
|
||||
(!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
|
||||
{
|
||||
if (!fcbopen)
|
||||
{
|
||||
errno = EACCES;
|
||||
return;
|
||||
}
|
||||
flags = O_RDONLY;
|
||||
}
|
||||
|
||||
if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) {
|
||||
if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
|
||||
{
|
||||
DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
|
||||
errno = EINVAL;
|
||||
return;
|
||||
@ -1438,21 +1484,36 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
|
||||
|
||||
if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
|
||||
|
||||
if (lp_share_modes(SNUM(cnum))) {
|
||||
int old_share=0;
|
||||
if (lp_share_modes(SNUM(cnum)))
|
||||
{
|
||||
int num_shares = 0;
|
||||
int i;
|
||||
min_share_mode_entry *old_shares = 0;
|
||||
|
||||
|
||||
if (file_existed)
|
||||
old_share = get_share_mode(cnum,&sbuf,&share_pid);
|
||||
{
|
||||
dev = (uint32)sbuf.st_dev;
|
||||
inode = (uint32)sbuf.st_ino;
|
||||
lock_share_entry(cnum, dev, inode, &token);
|
||||
share_locked = True;
|
||||
num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
|
||||
}
|
||||
|
||||
if (share_pid) {
|
||||
for(i = 0; i < num_shares; i++)
|
||||
{
|
||||
/* someone else has a share lock on it, check to see
|
||||
if we can too */
|
||||
int old_open_mode = old_share&0xF;
|
||||
int old_deny_mode = (old_share>>4)&7;
|
||||
int old_open_mode = old_shares[i].share_mode &0xF;
|
||||
int old_deny_mode = (old_shares[i].share_mode >>4)&7;
|
||||
|
||||
if (deny_mode > 4 || old_deny_mode > 4 || old_open_mode > 2) {
|
||||
if (deny_mode > 4 || old_deny_mode > 4 || old_open_mode > 2)
|
||||
{
|
||||
DEBUG(2,("Invalid share mode (%d,%d,%d) on file %s\n",
|
||||
deny_mode,old_deny_mode,old_open_mode,fname));
|
||||
free((char *)old_shares);
|
||||
if(share_locked)
|
||||
unlock_share_entry(cnum, dev, inode, token);
|
||||
errno = EACCES;
|
||||
unix_ERR_class = ERRDOS;
|
||||
unix_ERR_code = ERRbadshare;
|
||||
@ -1461,21 +1522,25 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
|
||||
|
||||
{
|
||||
int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
|
||||
share_pid,fname);
|
||||
old_shares[i].pid,fname);
|
||||
|
||||
if ((access_allowed == AFAIL) ||
|
||||
(!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) ||
|
||||
(access_allowed == AREAD && flags == O_WRONLY) ||
|
||||
(access_allowed == AWRITE && flags == O_RDONLY)) {
|
||||
(access_allowed == AWRITE && flags == O_RDONLY))
|
||||
{
|
||||
DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
|
||||
deny_mode,old_deny_mode,old_open_mode,
|
||||
share_pid,fname,
|
||||
old_shares[i].pid,fname,
|
||||
access_allowed));
|
||||
free((char *)old_shares);
|
||||
if(share_locked)
|
||||
unlock_share_entry(cnum, dev, inode, token);
|
||||
errno = EACCES;
|
||||
unix_ERR_class = ERRDOS;
|
||||
unix_ERR_code = ERRbadshare;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (access_allowed == AREAD)
|
||||
flags = O_RDONLY;
|
||||
@ -1484,76 +1549,69 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
|
||||
flags = O_WRONLY;
|
||||
}
|
||||
}
|
||||
if(old_shares != 0)
|
||||
free((char *)old_shares);
|
||||
}
|
||||
|
||||
DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
|
||||
flags,flags2,mode));
|
||||
|
||||
open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
|
||||
if (!Files[fnum].open && flags==O_RDWR && errno!=ENOENT && fcbopen) {
|
||||
if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
|
||||
{
|
||||
flags = O_RDONLY;
|
||||
open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
|
||||
}
|
||||
|
||||
if (Files[fnum].open) {
|
||||
if (fs_p->open)
|
||||
{
|
||||
int open_mode=0;
|
||||
switch (flags) {
|
||||
case O_RDONLY:
|
||||
open_mode = 0;
|
||||
break;
|
||||
case O_RDWR:
|
||||
open_mode = 2;
|
||||
break;
|
||||
case O_WRONLY:
|
||||
open_mode = 1;
|
||||
break;
|
||||
|
||||
if((share_locked == False) && lp_share_modes(SNUM(cnum)))
|
||||
{
|
||||
/* We created the file - thus we must now lock the share entry before creating it. */
|
||||
dev = fs_p->fd_ptr->dev;
|
||||
inode = fs_p->fd_ptr->inode;
|
||||
lock_share_entry(cnum, dev, inode, &token);
|
||||
share_locked = True;
|
||||
}
|
||||
|
||||
Files[fnum].share_mode = (deny_mode<<4) | open_mode;
|
||||
Files[fnum].share_pending = True;
|
||||
switch (flags)
|
||||
{
|
||||
case O_RDONLY:
|
||||
open_mode = 0;
|
||||
break;
|
||||
case O_RDWR:
|
||||
open_mode = 2;
|
||||
break;
|
||||
case O_WRONLY:
|
||||
open_mode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Access) {
|
||||
fs_p->share_mode = (deny_mode<<4) | open_mode;
|
||||
|
||||
if (Access)
|
||||
(*Access) = open_mode;
|
||||
}
|
||||
|
||||
if (action) {
|
||||
|
||||
if (action)
|
||||
{
|
||||
if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
|
||||
if (!file_existed) *action = 2;
|
||||
if (file_existed && (flags2 & O_TRUNC)) *action = 3;
|
||||
}
|
||||
|
||||
if (!share_pid)
|
||||
share_mode_pending = True;
|
||||
|
||||
if ((flags2&O_TRUNC) && file_existed)
|
||||
truncate_unless_locked(fnum,cnum);
|
||||
|
||||
if (lp_share_modes(SNUM(cnum)))
|
||||
set_share_mode(token, fnum);
|
||||
}
|
||||
|
||||
if (share_locked && lp_share_modes(SNUM(cnum)))
|
||||
unlock_share_entry( cnum, dev, inode, token);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
check for files that we should now set our share modes on
|
||||
********************************************************************/
|
||||
static void check_share_modes(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<MAX_OPEN_FILES;i++)
|
||||
if(Files[i].open && Files[i].share_pending) {
|
||||
if (lp_share_modes(SNUM(Files[i].cnum))) {
|
||||
int pid=0;
|
||||
get_share_mode_by_fnum(Files[i].cnum,i,&pid);
|
||||
if (!pid) {
|
||||
set_share_mode(i,Files[i].share_mode);
|
||||
Files[i].share_pending = False;
|
||||
}
|
||||
} else {
|
||||
Files[i].share_pending = False;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
seek a file. Try to avoid the seek if possible
|
||||
****************************************************************************/
|
||||
@ -2694,18 +2752,18 @@ int reply_nt1(char *outbuf)
|
||||
*/
|
||||
encrypt_len = doencrypt?challenge_len:0;
|
||||
#if UNICODE
|
||||
data_len = encrypt_len + 2*(strlen(lp_workgroup())+1);
|
||||
data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
|
||||
#else
|
||||
data_len = encrypt_len + strlen(lp_workgroup()) + 1;
|
||||
data_len = encrypt_len + strlen(myworkgroup) + 1;
|
||||
#endif
|
||||
|
||||
set_message(outbuf,17,data_len,True);
|
||||
|
||||
#if UNICODE
|
||||
/* put the OEM'd domain name */
|
||||
PutUniCode(smb_buf(outbuf)+encrypt_len,lp_workgroup());
|
||||
PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup);
|
||||
#else
|
||||
strcpy(smb_buf(outbuf)+encrypt_len, lp_workgroup());
|
||||
strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
|
||||
#endif
|
||||
|
||||
CVAL(outbuf,smb_vwv1) = secword;
|
||||
@ -3258,9 +3316,9 @@ void exit_server(char *reason)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if FAST_SHARE_MODES
|
||||
#ifdef FAST_SHARE_MODES
|
||||
stop_share_mode_mgmt();
|
||||
#endif
|
||||
#endif /* FAST_SHARE_MODES */
|
||||
|
||||
DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
|
||||
exit(0);
|
||||
@ -3738,24 +3796,6 @@ static void process(void)
|
||||
if (lp_readprediction())
|
||||
do_read_prediction();
|
||||
|
||||
{
|
||||
extern pstring share_del_pending;
|
||||
if (*share_del_pending) {
|
||||
unbecome_user();
|
||||
if (!unlink(share_del_pending))
|
||||
DEBUG(3,("Share file deleted %s\n",share_del_pending));
|
||||
else
|
||||
DEBUG(2,("Share del failed of %s\n",share_del_pending));
|
||||
share_del_pending[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (share_mode_pending) {
|
||||
unbecome_user();
|
||||
check_share_modes();
|
||||
share_mode_pending=False;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
for (counter=SMBD_SELECT_LOOP;
|
||||
@ -3787,6 +3827,7 @@ static void process(void)
|
||||
if (!(counter%SMBD_RELOAD_CHECK))
|
||||
reload_services(True);
|
||||
|
||||
#if 0 /* JRA */
|
||||
/* check the share modes every 10 secs */
|
||||
if (!(counter%SHARE_MODES_CHECK))
|
||||
check_share_modes();
|
||||
@ -3794,6 +3835,7 @@ static void process(void)
|
||||
/* clean the share modes every 5 minutes */
|
||||
if (!(counter%SHARE_MODES_CLEAN))
|
||||
clean_share_modes();
|
||||
#endif /* JRA */
|
||||
|
||||
/* automatic timeout if all connections are closed */
|
||||
if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) {
|
||||
@ -4082,6 +4124,8 @@ static void usage(char *pname)
|
||||
if (!reload_services(False))
|
||||
return(-1);
|
||||
|
||||
strcpy(myworkgroup, lp_workgroup());
|
||||
|
||||
#ifndef NO_SIGNAL_TEST
|
||||
signal(SIGHUP,SIGNAL_CAST sig_hup);
|
||||
#endif
|
||||
@ -4128,10 +4172,10 @@ static void usage(char *pname)
|
||||
if (!open_sockets(is_daemon,port))
|
||||
exit(1);
|
||||
|
||||
#if FAST_SHARE_MODES
|
||||
#ifdef FAST_SHARE_MODES
|
||||
if (!start_share_mode_mgmt())
|
||||
exit(1);
|
||||
#endif
|
||||
#endif /* FAST_SHARE_MODES */
|
||||
|
||||
/* possibly reload the services file. */
|
||||
reload_services(True);
|
||||
|
@ -277,6 +277,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l
|
||||
strequal(Connections[cnum].dirpath,"/"));
|
||||
BOOL was_8_3;
|
||||
int nt_extmode; /* Used for NT connections instead of mode */
|
||||
BOOL needslash = ( Connections[cnum].dirpath[strlen(Connections[cnum].dirpath) -1] != '/');
|
||||
|
||||
*fname = 0;
|
||||
*out_of_space = False;
|
||||
@ -323,7 +324,8 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l
|
||||
continue;
|
||||
|
||||
strcpy(pathreal,Connections[cnum].dirpath);
|
||||
strcat(pathreal,"/");
|
||||
if(needslash)
|
||||
strcat(pathreal,"/");
|
||||
strcat(pathreal,fname);
|
||||
if (sys_stat(pathreal,&sbuf) != 0)
|
||||
{
|
||||
|
@ -53,6 +53,81 @@ int Ucrit_pid[100]; /* Ugly !!! */ /* added by OH */
|
||||
int Ucrit_MaxPid=0; /* added by OH */
|
||||
unsigned int Ucrit_IsActive = 0; /* added by OH */
|
||||
|
||||
#ifndef FAST_SHARE_MODES
|
||||
static char *read_share_file(int fd, char *fname, char *progname)
|
||||
{
|
||||
struct stat sb;
|
||||
char *buf;
|
||||
int size;
|
||||
|
||||
if(fstat(fd, &sb) != 0)
|
||||
{
|
||||
printf("%s: ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
|
||||
progname, fname, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(sb.st_size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate space for the file */
|
||||
if((buf = (char *)malloc(sb.st_size)) == NULL)
|
||||
{
|
||||
printf("%s: read_share_file: malloc for file size %d fail !\n",
|
||||
progname, (int)sb.st_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(lseek(fd, 0, SEEK_SET) != 0)
|
||||
{
|
||||
printf("%s: ERROR: read_share_file: Failed to reset position to 0 \
|
||||
for share file %s (%s)\n", progname, fname, strerror(errno));
|
||||
if(buf)
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (read(fd,buf,sb.st_size) != sb.st_size)
|
||||
{
|
||||
printf("%s: ERROR: read_share_file: Failed to read share file %s (%s)\n",
|
||||
progname, fname, strerror(errno));
|
||||
if(buf)
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IVAL(buf,0) != LOCKING_VERSION) {
|
||||
printf("%s: ERROR: read_share_file: share file %s has incorrect \
|
||||
locking version (was %d, should be %d).\n",fname,
|
||||
progname, IVAL(buf,0), LOCKING_VERSION);
|
||||
if(buf)
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sanity check for file contents */
|
||||
size = sb.st_size;
|
||||
size -= 10; /* Remove the header */
|
||||
|
||||
/* Remove the filename component. */
|
||||
size -= SVAL(buf, 8);
|
||||
|
||||
/* The remaining size must be a multiple of 16 - error if not. */
|
||||
if((size % 16) != 0)
|
||||
{
|
||||
printf("%s: ERROR: read_share_file: share file %s is an incorrect length.\n",
|
||||
progname, fname);
|
||||
if(buf)
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif /* FAST_SHARE_MODES */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *f;
|
||||
@ -64,16 +139,16 @@ unsigned int Ucrit_IsActive = 0; /* added by OH */
|
||||
BOOL firstopen=True;
|
||||
BOOL processes_only=False;
|
||||
int last_pid=0;
|
||||
#if FAST_SHARE_MODES
|
||||
#ifdef FAST_SHARE_MODES
|
||||
pstring shmem_file_name;
|
||||
share_mode_record *scanner_p;
|
||||
share_mode_record *prev_p;
|
||||
share_mode_record *file_scanner_p;
|
||||
smb_shm_offset_t *mode_array;
|
||||
int bytes_free, bytes_used, bytes_overhead, bytes_total;
|
||||
#else
|
||||
int n;
|
||||
#else /* FAST_SHARE_MODES */
|
||||
void *dir;
|
||||
char *s;
|
||||
#endif
|
||||
#endif /* FAST_SHARE_MODES */
|
||||
int i;
|
||||
struct session_record *ptr;
|
||||
|
||||
|
||||
@ -226,101 +301,110 @@ unsigned int Ucrit_IsActive = 0; /* added by OH */
|
||||
|
||||
printf("\n");
|
||||
|
||||
#if FAST_SHARE_MODES
|
||||
#ifdef FAST_SHARE_MODES
|
||||
/*******************************************************************
|
||||
initialize the shared memory for share_mode management
|
||||
******************************************************************/
|
||||
|
||||
|
||||
strcpy(shmem_file_name,lp_lockdir());
|
||||
trim_string(shmem_file_name,"","/");
|
||||
if (!*shmem_file_name) exit(-1);
|
||||
strcat(shmem_file_name, "/SHARE_MEM_FILE");
|
||||
if(!smb_shm_open(shmem_file_name, SHMEM_SIZE)) exit(-1);
|
||||
if(!smb_shm_open(shmem_file_name, lp_shmem_size())) exit(-1);
|
||||
|
||||
if(!smb_shm_lock())
|
||||
mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
|
||||
if(mode_array == NULL)
|
||||
{
|
||||
smb_shm_close();
|
||||
exit (-1);
|
||||
printf("%s: base of shared memory hash array == 0! Exiting.\n", argv[0]);
|
||||
smb_shm_close();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
scanner_p = (share_mode_record *)smb_shm_offset2addr(smb_shm_get_userdef_off());
|
||||
prev_p = scanner_p;
|
||||
while(scanner_p)
|
||||
for( i = 0; i < lp_shmem_hash_size(); i++)
|
||||
{
|
||||
int pid,mode;
|
||||
struct timeval t;
|
||||
smb_shm_lock_hash_entry(i);
|
||||
if(mode_array[i] == NULL_OFFSET)
|
||||
{
|
||||
smb_shm_unlock_hash_entry(i);
|
||||
continue;
|
||||
}
|
||||
file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[i]);
|
||||
while((file_scanner_p != 0) && (file_scanner_p->num_share_mode_entries != 0))
|
||||
{
|
||||
share_mode_entry *entry_scanner_p =
|
||||
(share_mode_entry *)smb_shm_offset2addr(
|
||||
file_scanner_p->share_mode_entries);
|
||||
|
||||
while(entry_scanner_p != 0)
|
||||
{
|
||||
struct timeval t;
|
||||
int pid = entry_scanner_p->pid;
|
||||
int mode = entry_scanner_p->share_mode;
|
||||
|
||||
pid = scanner_p->pid;
|
||||
|
||||
if ( !Ucrit_checkPid(pid) )
|
||||
{
|
||||
prev_p = scanner_p ;
|
||||
scanner_p = (share_mode_record *)smb_shm_offset2addr(scanner_p->next_offset);
|
||||
continue;
|
||||
}
|
||||
|
||||
if( (scanner_p->locking_version != LOCKING_VERSION) || !process_exists(pid))
|
||||
{
|
||||
DEBUG(2,("Deleting stale share mode record"));
|
||||
if(prev_p == scanner_p)
|
||||
{
|
||||
smb_shm_set_userdef_off(scanner_p->next_offset);
|
||||
smb_shm_free(smb_shm_addr2offset(scanner_p));
|
||||
scanner_p = (share_mode_record *)smb_shm_offset2addr(smb_shm_get_userdef_off());
|
||||
prev_p = scanner_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_p->next_offset = scanner_p->next_offset;
|
||||
smb_shm_free(smb_shm_addr2offset(scanner_p));
|
||||
scanner_p = (share_mode_record *)smb_shm_offset2addr(prev_p->next_offset);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
t.tv_sec = scanner_p->time.tv_sec;
|
||||
t.tv_usec = scanner_p->time.tv_usec;
|
||||
mode = scanner_p->share_mode;
|
||||
strcpy(fname, scanner_p->file_name);
|
||||
#else
|
||||
t.tv_sec = entry_scanner_p->time.tv_sec;
|
||||
t.tv_usec = entry_scanner_p->time.tv_usec;
|
||||
strcpy(fname, file_scanner_p->file_name);
|
||||
#else /* FAST_SHARE_MODES */
|
||||
|
||||
/* For slow share modes go through all the files in
|
||||
the share mode directory and read the entries in
|
||||
each.
|
||||
*/
|
||||
|
||||
dir = opendir(lp_lockdir());
|
||||
if (!dir) return(0);
|
||||
if (!dir)
|
||||
{
|
||||
printf("%s: Unable to open lock directory %s.\n", argv[0], lp_lockdir());
|
||||
return(0);
|
||||
}
|
||||
while ((s=readdirname(dir))) {
|
||||
char buf[20];
|
||||
int pid,mode;
|
||||
struct timeval t;
|
||||
char *buf;
|
||||
char *base;
|
||||
int fd;
|
||||
pstring lname;
|
||||
int dev,inode;
|
||||
uint32 dev,inode;
|
||||
|
||||
if (sscanf(s,"share.%d.%d",&dev,&inode)!=2) continue;
|
||||
if (sscanf(s,"share.%u.%u",&dev,&inode)!=2) continue;
|
||||
|
||||
strcpy(lname,lp_lockdir());
|
||||
trim_string(lname,NULL,"/");
|
||||
strcat(lname,"/");
|
||||
strcat(lname,s);
|
||||
|
||||
fd = open(lname,O_RDONLY,0);
|
||||
if (fd < 0) continue;
|
||||
if (read(fd,buf,20) != 20) continue;
|
||||
n = read(fd,fname,sizeof(fname));
|
||||
fname[MAX(n,0)]=0;
|
||||
close(fd);
|
||||
|
||||
t.tv_sec = IVAL(buf,4);
|
||||
t.tv_usec = IVAL(buf,8);
|
||||
mode = IVAL(buf,12);
|
||||
pid = IVAL(buf,16);
|
||||
|
||||
if ( !Ucrit_checkPid(pid) ) /* added by OH */
|
||||
continue;
|
||||
|
||||
if (IVAL(buf,0) != LOCKING_VERSION || !process_exists(pid)) {
|
||||
if (unlink(lname)==0)
|
||||
printf("Deleted stale share file %s\n",s);
|
||||
continue;
|
||||
fd = open(lname,O_RDWR,0);
|
||||
if (fd < 0)
|
||||
{
|
||||
printf("%s: Unable to open share file %s.\n", argv[0], lname);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Lock the share mode file while we read it. */
|
||||
if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
|
||||
{
|
||||
printf("%s: Unable to lock open share file %s.\n", argv[0], lname);
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(( buf = read_share_file( fd, lname, argv[0] )) == NULL)
|
||||
{
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
strcpy( fname, &buf[10]);
|
||||
close(fd);
|
||||
|
||||
base = buf + 10 + SVAL(buf,8);
|
||||
for( i = 0; i < IVAL(buf, 4); i++)
|
||||
{
|
||||
char *p = base + (i*16);
|
||||
struct timeval t;
|
||||
int pid = IVAL(p,12);
|
||||
int mode = IVAL(p,8);
|
||||
|
||||
t.tv_sec = IVAL(p,0);
|
||||
t.tv_usec = IVAL(p,4);
|
||||
#endif /* FAST_SHARE_MODES */
|
||||
|
||||
fname[sizeof(fname)-1] = 0;
|
||||
|
||||
@ -349,28 +433,38 @@ unsigned int Ucrit_IsActive = 0; /* added by OH */
|
||||
}
|
||||
printf(" %s %s",fname,asctime(LocalTime((time_t *)&t.tv_sec)));
|
||||
|
||||
#if FAST_SHARE_MODES
|
||||
prev_p = scanner_p ;
|
||||
scanner_p = (share_mode_record *)smb_shm_offset2addr(scanner_p->next_offset);
|
||||
} /* end while */
|
||||
#ifdef FAST_SHARE_MODES
|
||||
|
||||
entry_scanner_p = (share_mode_entry *)smb_shm_offset2addr(
|
||||
entry_scanner_p->next_share_mode_entry);
|
||||
} /* end while entry_scanner_p */
|
||||
file_scanner_p = (share_mode_record *)smb_shm_offset2addr(
|
||||
file_scanner_p->next_offset);
|
||||
} /* end while file_scanner_p */
|
||||
smb_shm_unlock_hash_entry(i);
|
||||
} /* end for */
|
||||
|
||||
smb_shm_get_usage(&bytes_free, &bytes_used, &bytes_overhead);
|
||||
bytes_total = bytes_free + bytes_used + bytes_overhead;
|
||||
smb_shm_unlock();
|
||||
|
||||
/*******************************************************************
|
||||
deinitialize the shared memory for share_mode management
|
||||
******************************************************************/
|
||||
smb_shm_close();
|
||||
|
||||
#else
|
||||
#else /* FAST_SHARE_MODES */
|
||||
} /* end for i */
|
||||
|
||||
if(buf)
|
||||
free(buf);
|
||||
base = 0;
|
||||
} /* end while */
|
||||
closedir(dir);
|
||||
|
||||
#endif
|
||||
#endif /* FAST_SHARE_MODES */
|
||||
if (firstopen)
|
||||
printf("No locked files\n");
|
||||
#if FAST_SHARE_MODES
|
||||
#ifdef FAST_SHARE_MODES
|
||||
printf("\nShare mode memory usage (bytes):\n");
|
||||
printf(" %d(%d%%) free + %d(%d%%) used + %d(%d%%) overhead = %d(100%%) total\n",
|
||||
bytes_free, (bytes_free * 100)/bytes_total,
|
||||
@ -378,7 +472,7 @@ unsigned int Ucrit_IsActive = 0; /* added by OH */
|
||||
bytes_overhead, (bytes_overhead * 100)/bytes_total,
|
||||
bytes_total);
|
||||
|
||||
#endif
|
||||
#endif /* FAST_SHARE_MODES */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user