Unix SMB/Netbios implementation.
Version 1.9.
Main SMB server routines
- Copyright (C) Andrew Tridgell 1992-1995
+ Copyright (C) Andrew Tridgell 1992-1997
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
pstring servicesf = CONFIGFILE;
extern pstring debugf;
extern pstring sesssetup_user;
+extern fstring myworkgroup;
char *InBuffer = NULL;
char *OutBuffer = NULL;
int am_parent = 1;
int atexit_set = 0;
-BOOL share_mode_pending = False;
-
/* the last message the was processed */
int last_message = -1;
extern int Protocol;
-int maxxmit = BUFFER_SIZE;
+/*
+ * Size of data we can send to client. Set
+ * by the client for all protocols above CORE.
+ * Set by us for CORE protocol.
+ */
+int max_send = BUFFER_SIZE;
+/*
+ * Size of the data we can receive. Set by us.
+ * Can be modified by the max xmit parameter.
+ */
+int max_recv = BUFFER_SIZE;
/* a fnum to use when chaining */
int chain_fnum = -1;
void *dflt_sig(void)
{
exit_server("caught signal");
+ return 0; /* Keep -Wall happy :-) */
}
/****************************************************************************
Send a SIGTERM to our process group.
if ( !IS_DOS_READONLY(dosmode) )
result |= (S_IWUSR | S_IWGRP | S_IWOTH);
- if (IS_DOS_DIR(dosmode))
+ if (IS_DOS_DIR(dosmode)) {
result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
-
- if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
- result |= S_IXUSR;
+ result &= (lp_dir_mode(SNUM(cnum)) | 0700);
+ } else {
+ if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
+ result |= S_IXUSR;
- if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
- result |= S_IXGRP;
+ if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
+ result |= S_IXGRP;
- if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
- result |= S_IXOTH;
+ if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
+ result |= S_IXOTH;
- result &= CREATE_MODE(cnum);
+ result &= CREATE_MODE(cnum);
+ }
return(result);
}
{
pstring tmpname;
- if (is_8_3(name2))
+ if (is_8_3(name2, True))
return(False);
strcpy(tmpname,name2);
unix_format(name);
unix_clean_name(name);
- if (!case_sensitive &&
- (!case_preserve || (is_8_3(name) && !short_case_preserve)))
- strnorm(name);
-
/* names must be relative to the root of the service - trim any leading /.
also trim trailing /'s */
trim_string(name,"/","/");
+ /*
+ * Ensure saved_last_component is valid even if file exists.
+ */
+ if(saved_last_component) {
+ end = strrchr(name, '/');
+ if(end)
+ strcpy(saved_last_component, end + 1);
+ else
+ strcpy(saved_last_component, name);
+ }
+
+ if (!case_sensitive &&
+ (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
+ strnorm(name);
+
/* check if it's a printer file */
if (Connections[cnum].printer)
{
- if ((! *name) || strchr(name,'/') || !is_8_3(name))
+ if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
{
char *s;
fstring name2;
return(True);
}
- /*
- * Ensure saved_last_component is valid even if file exists.
- */
- if(saved_last_component) {
- end = strrchr(name, '/');
- if(end)
- strcpy(saved_last_component, end + 1);
- else
- strcpy(saved_last_component, name);
- }
-
/* stat the name - if it exists then we are all done! */
if (sys_stat(name,&st) == 0)
return(True);
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",
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;
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;
/****************************************************************************
open a file
****************************************************************************/
-void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
+static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
{
extern struct current_user current_user;
pstring fname;
return;
}
- /*
- * If O_TRUNC was set, ensure we truncate the file.
- * open_file_shared explicitly clears this flag before
- * calling open_file, so we can safely do this here.
- */
- if(flags & O_TRUNC)
- ftruncate(fd_ptr->fd, 0);
-
} else {
int open_flags;
/* We need to allocate a new file_fd_struct (this increments the
/* Set the flags as needed without the read/write modes. */
open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
+ /*
+ * On some systems opening a file for R/W access on a read only
+ * filesystems sets errno to EROFS.
+ */
+#ifdef EROFS
+ if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
+#else /* No EROFS */
if((fd_ptr->fd == -1) && (errno == EACCES)) {
+#endif /* EROFS */
if(flags & O_WRONLY) {
fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
fd_ptr->real_open_flags = O_WRONLY;
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++;
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;
{
Files[fnum].mmap_size = file_size(fname);
Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size,
- PROT_READ,MAP_SHARED,Files[fnum].fd,0);
+ PROT_READ,MAP_SHARED,Files[fnum].fd_ptr->fd,0);
if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
{
****************************************************************************/
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));
}
********************************************************************/
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);
}
/****************************************************************************
Helper for open_file_shared.
Truncate a file after checking locking; close file if locked.
**************************************************************************/
-static void truncate_unless_locked(int fnum, int cnum)
+static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
+ BOOL *share_locked)
{
if (Files[fnum].can_write){
if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
+ /* If share modes are in force for this connection we
+ have the share entry locked. Unlock it before closing. */
+ if (*share_locked && lp_share_modes(SNUM(cnum)))
+ unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
+ Files[fnum].fd_ptr->inode, token);
close_file(fnum);
+ /* Share mode no longer locked. */
+ *share_locked = False;
errno = EACCES;
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRlock;
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;
}
append does not mean the same thing under dos and unix */
switch (share_mode&0xF)
- {
+ {
case 1:
flags = O_WRONLY;
break;
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;
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;
{
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;
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;
+ }
+
+ switch (flags)
+ {
+ case O_RDONLY:
+ open_mode = 0;
+ break;
+ case O_RDWR:
+ open_mode = 2;
+ break;
+ case O_WRONLY:
+ open_mode = 1;
+ break;
}
- Files[fnum].share_mode = (deny_mode<<4) | open_mode;
- Files[fnum].share_pending = True;
+ fs_p->share_mode = (deny_mode<<4) | open_mode;
- if (Access) {
+ 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;
+ /* We must create the share mode entry before truncate as
+ truncate can fail due to locking and have to close the
+ file (which expects the share_mode_entry to be there).
+ */
+ if (lp_share_modes(SNUM(cnum)))
+ set_share_mode(token, fnum);
if ((flags2&O_TRUNC) && file_existed)
- truncate_unless_locked(fnum,cnum);
+ truncate_unless_locked(fnum,cnum,token,&share_locked);
}
-}
-
-
-/*******************************************************************
-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;
- }
- }
+ if (share_locked && lp_share_modes(SNUM(cnum)))
+ unlock_share_entry( cnum, dev, inode, token);
}
-
/****************************************************************************
seek a file. Try to avoid the seek if possible
****************************************************************************/
}
if(atexit_set == 0)
- atexit(&killkids);
+ atexit(killkids);
/* now accept incoming connections - forking a new process
for each incoming connection */
int secword=0;
BOOL doencrypt = SMBENCRYPT();
time_t t = time(NULL);
+ /* We need to save and restore this as it can be destroyed
+ if we call another server if security=server
+ Thanks to Paul Nelson @ Thursby for pointing this out.
+ */
+ uint16 mid = SVAL(outbuf, smb_mid);
if (lp_security()>=SEC_USER) secword |= 1;
if (doencrypt) secword |= 2;
}
CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
- SSVAL(outbuf,smb_vwv2,maxxmit);
+ SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
+ SSVAL(outbuf,smb_vwv2,max_recv);
SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
SSVAL(outbuf,smb_vwv4,1);
SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
int secword=0;
BOOL doencrypt = SMBENCRYPT();
time_t t = time(NULL);
+ /* We need to save and restore this as it can be destroyed
+ if we call another server if security=server
+ Thanks to Paul Nelson @ Thursby for pointing this out.
+ */
+ uint16 mid = SVAL(outbuf, smb_mid);
if (lp_security()>=SEC_USER) secword |= 1;
if (doencrypt) secword |= 2;
}
CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
- SSVAL(outbuf,smb_vwv2,maxxmit);
+ SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
+ SSVAL(outbuf,smb_vwv2,max_recv);
SSVAL(outbuf,smb_vwv3,lp_maxmux());
SSVAL(outbuf,smb_vwv4,1);
SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
return (smb_len(outbuf)+4);
}
+
/****************************************************************************
reply for the nt protocol
****************************************************************************/
int reply_nt1(char *outbuf)
{
- int capabilities=0x300; /* has dual names + lock_and_read */
+ /* dual names + lock_and_read + nt SMBs + remote API calls */
+ int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
+/*
+ other valid capabilities which we may support at some time...
+ CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
+ CAP_LARGE_FILES|CAP_LARGE_READX|
+ CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
+ */
+
int secword=0;
BOOL doencrypt = SMBENCRYPT();
time_t t = time(NULL);
+ int data_len;
+ int encrypt_len;
+ char challenge_len = 8;
+ /* We need to save and restore this as it can be destroyed
+ if we call another server if security=server
+ Thanks to Paul Nelson @ Thursby for pointing this out.
+ */
+ uint16 mid = SVAL(outbuf, smb_mid);
+
+ if (lp_readraw() && lp_writeraw())
+ {
+ capabilities |= CAP_RAW_MODE;
+ }
if (lp_security()>=SEC_USER) secword |= 1;
if (doencrypt) secword |= 2;
- set_message(outbuf,17,doencrypt?8:0,True);
+ /* decide where (if) to put the encryption challenge, and
+ follow it with the OEM'd domain name
+ */
+ encrypt_len = doencrypt?challenge_len:0;
+#if UNICODE
+ data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
+#else
+ 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,myworkgroup);
+#else
+ strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
+#endif
+
CVAL(outbuf,smb_vwv1) = secword;
#ifdef SMB_PASSWD
/* Create a token value and add it to the outgoing packet. */
- if (doencrypt) {
+ if (doencrypt)
+ {
generate_next_challenge(smb_buf(outbuf));
+
/* Tell the nt machine how long the challenge is. */
- SSVALS(outbuf,smb_vwv16+1,8);
+ SSVALS(outbuf,smb_vwv16+1,challenge_len);
}
#endif
- SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
-
Protocol = PROTOCOL_NT1;
if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
#endif
}
- if (lp_readraw() && lp_writeraw())
- capabilities |= 1;
-
+ SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
- SIVAL(outbuf,smb_vwv3+1,0xFFFF); /* max buffer */
- SIVAL(outbuf,smb_vwv5+1,0xFFFF); /* raw size */
+ SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
+ SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
+ SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
put_long_date(outbuf+smb_vwv11+1,t);
SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
+ SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
return (smb_len(outbuf)+4);
}
-
/* these are the protocol lists used for auto architecture detection:
WinNT 3.51:
#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);
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;
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();
/* 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) {
if (msg_type == 0)
show_msg(InBuffer);
- nread = construct_reply(InBuffer,OutBuffer,nread,maxxmit);
+ nread = construct_reply(InBuffer,OutBuffer,nread,max_send);
if(nread > 0) {
if (CVAL(OutBuffer,0) == 0)
if (!reload_services(False))
return(-1);
+ strcpy(myworkgroup, lp_workgroup());
+
#ifndef NO_SIGNAL_TEST
signal(SIGHUP,SIGNAL_CAST sig_hup);
#endif
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);
- maxxmit = MIN(lp_maxxmit(),BUFFER_SIZE);
+ max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
if (*lp_rootdir())
{