summaryrefslogtreecommitdiff
path: root/source/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd')
-rw-r--r--source/smbd/dir.c6
-rw-r--r--source/smbd/ipc.c19
-rw-r--r--source/smbd/mangle.c207
-rw-r--r--source/smbd/password.c62
-rw-r--r--source/smbd/pipes.c6
-rw-r--r--source/smbd/predict.c39
-rw-r--r--source/smbd/quotas.c27
-rw-r--r--source/smbd/reply.c300
-rw-r--r--source/smbd/server.c1206
-rw-r--r--source/smbd/trans2.c37
-rw-r--r--source/smbd/uid.c84
11 files changed, 682 insertions, 1311 deletions
diff --git a/source/smbd/dir.c b/source/smbd/dir.c
index 316b58818fd..567bc14424e 100644
--- a/source/smbd/dir.c
+++ b/source/smbd/dir.c
@@ -470,12 +470,12 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo
if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
continue;
- pstrcpy(fname,filename);
+ strcpy(fname,filename);
*path = 0;
- pstrcpy(path,Connections[cnum].dirpath);
+ strcpy(path,Connections[cnum].dirpath);
if(needslash)
strcat(path,"/");
- pstrcpy(pathreal,path);
+ strcpy(pathreal,path);
strcat(path,fname);
strcat(pathreal,dname);
if (sys_stat(pathreal,&sbuf) != 0)
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c
index b9355c4ec07..1d7ee375d3f 100644
--- a/source/smbd/ipc.c
+++ b/source/smbd/ipc.c
@@ -440,7 +440,7 @@ static void PackDriverData(struct pack_desc* desc)
}
static int check_printq_info(struct pack_desc* desc,
- int uLevel, char *id1, char *id2)
+ int uLevel, char *id1, const char* id2)
{
desc->subformat = NULL;
switch( uLevel ) {
@@ -1074,7 +1074,7 @@ static BOOL api_RNetServerEnum(int cnum, uint16 vuid, char *param, char *data,
*rparam_len = 8;
*rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,NERR_Success);
+ SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERROR_MORE_DATA));
SSVAL(*rparam,2,0);
SSVAL(*rparam,4,counted);
SSVAL(*rparam,6,counted+missed);
@@ -1601,13 +1601,14 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data,
name[l] = 0;
DEBUG(3,("Setting print name to %s\n",name));
+
+ become_root(1);
for (i=0;i<MAX_OPEN_FILES;i++)
if (Files[i].open && Files[i].print_file)
{
pstring wd;
GetWd(wd);
- unbecome_user();
if (!become_user(Files[i].cnum,vuid) ||
!become_service(Files[i].cnum,True))
@@ -1617,6 +1618,8 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data,
string_set(&Files[i].name,name);
break;
}
+
+ unbecome_root(1);
}
desc.errcode=NERR_Success;
@@ -2219,7 +2222,6 @@ static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data,
int uLevel;
struct pack_desc desc;
char* name;
- char* logon_script;
uLevel = SVAL(p,0);
name = p + 2;
@@ -2262,14 +2264,7 @@ static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data,
PACKS(&desc,"z",mypath); /* computer */
}
PACKS(&desc,"z",myworkgroup);/* domain */
-
-/* JHT - By calling lp_logon_script() and standard_sub() we have */
-/* made sure all macros are fully substituted and available */
- logon_script = lp_logon_script();
- standard_sub( cnum, logon_script );
- PACKS(&desc,"z", logon_script); /* script path */
-/* End of JHT mods */
-
+ PACKS(&desc,"z",lp_logon_script()); /* script path */
PACKI(&desc,"D",0x00000000); /* reserved */
}
diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c
index b0a45ffb47c..66e8233df28 100644
--- a/source/smbd/mangle.c
+++ b/source/smbd/mangle.c
@@ -123,34 +123,30 @@ BOOL is_8_3(char *fname, BOOL check_case)
{
char *p = fname;
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- dot_pos = 0;
- while (*p)
+#ifdef KANJI
+ dot_pos = 0;
+ while (*p)
{
- if (is_shift_jis (*p))
- p += 2;
- else if (is_kana (*p))
- p ++;
- else
- {
- if (*p == '.' && !dot_pos)
- dot_pos = (char *) p;
- if (!isdoschar(*p))
- return(False);
- p++;
- }
- }
- }
- else
- {
- while (*p)
+ if (is_shift_jis (*p)) {
+ p += 2;
+ } else if (is_kana (*p)) {
+ p ++;
+ } else {
+ if (*p == '.' && !dot_pos)
+ dot_pos = (char *) p;
+ if (!isdoschar(*p))
+ return(False);
+ p++;
+ }
+ }
+#else
+ while (*p)
{
- if (!isdoschar(*p))
- return(False);
- p++;
+ if (!isdoschar(*p))
+ return(False);
+ p++;
}
- }
+#endif /* KANJI */
}
/* no dot and less than 9 means OK */
@@ -502,90 +498,84 @@ void mangle_name_83(char *s)
DEBUG(5,("Mangling name %s to ",s));
if (p)
- {
- if (p == s)
- strcpy(extension,"___");
- else
+ {
+ if (p == s)
+ strcpy(extension,"___");
+ else
{
*p++ = 0;
while (*p && extlen < 3)
- {
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- if (is_shift_jis (*p))
- {
- if (extlen < 2)
- {
- extension[extlen++] = p[0];
- extension[extlen++] = p[1];
- }
- else
- {
- extension[extlen++] = base36 (((unsigned char) *p) % 36);
- }
- p += 2;
- }
- else if (is_kana (*p))
- {
- extension[extlen++] = p[0];
- p++;
- }
- else
- {
- if (isdoschar (*p) && *p != '.')
- extension[extlen++] = p[0];
- p++;
- }
- }
- else
- {
- if (isdoschar(*p) && *p != '.')
- extension[extlen++] = *p;
- p++;
- }
- }
+ {
+#ifdef KANJI
+ if (is_shift_jis (*p))
+ {
+ if (extlen < 2)
+ {
+ extension[extlen++] = p[0];
+ extension[extlen++] = p[1];
+ }
+ else
+ {
+ extension[extlen++] = base36 (((unsigned char) *p) % 36);
+ }
+ p += 2;
+ }
+ else if (is_kana (*p))
+ {
+ extension[extlen++] = p[0];
+ p++;
+ }
+ else
+ {
+ if (isdoschar (*p) && *p != '.')
+ extension[extlen++] = p[0];
+ p++;
+ }
+#else
+ if (isdoschar(*p) && *p != '.')
+ extension[extlen++] = *p;
+ p++;
+#endif /* KANJI */
+ }
extension[extlen] = 0;
+ }
}
- }
p = s;
while (*p && baselen < 5)
- {
- if(lp_client_code_page() == KANJI_CODEPAGE)
{
+#ifdef KANJI
if (is_shift_jis (*p))
- {
- if (baselen < 4)
- {
- base[baselen++] = p[0];
- base[baselen++] = p[1];
- }
- else
- {
+ {
+ if (baselen < 4)
+ {
+ base[baselen++] = p[0];
+ base[baselen++] = p[1];
+ }
+ else
+ {
base[baselen++] = base36 (((unsigned char) *p) % 36);
- }
- p += 2;
- }
+ }
+ p += 2;
+ }
else if (is_kana (*p))
- {
- base[baselen++] = p[0];
- p++;
- }
+ {
+ base[baselen++] = p[0];
+ p++;
+ }
else
- {
- if (isdoschar (*p) && *p != '.')
- base[baselen++] = p[0];
- p++;
- }
- }
- else
- {
+ {
+ if (isdoschar (*p) && *p != '.')
+ base[baselen++] = p[0];
+ p++;
+ }
+#else
if (isdoschar(*p) && *p != '.')
- base[baselen++] = *p;
+ base[baselen++] = *p;
p++;
+#endif /* KANJI */
}
- }
base[baselen] = 0;
csum = csum % (36*36);
@@ -611,9 +601,8 @@ static BOOL illegal_name(char *name)
static BOOL initialised=False;
unsigned char *s;
- if (!initialised)
- {
- char *ill = "*\\/?<>|\":{}";
+ if (!initialised) {
+ char *ill = "*\\/?<>|\":";
initialised = True;
bzero((char *)illegal,256);
@@ -621,23 +610,21 @@ static BOOL illegal_name(char *name)
illegal[*s] = True;
}
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- for (s = (unsigned char *)name; *s;) {
- if (is_shift_jis (*s)) {
- s += 2;
- } else if (illegal[*s]) {
- return(True);
- } else {
- s++;
- }
+#ifdef KANJI
+ for (s = (unsigned char *)name; *s;) {
+ if (is_shift_jis (*s)) {
+ s += 2;
+ } else if (illegal[*s]) {
+ return(True);
+ } else {
+ s++;
}
}
- else
- {
- for (s = (unsigned char *)name;*s;s++)
- if (illegal[*s]) return(True);
- }
+#else
+ for (s = (unsigned char *)name;*s;s++)
+ if (illegal[*s]) return(True);
+#endif
+
return(False);
}
diff --git a/source/smbd/password.c b/source/smbd/password.c
index f4d94791cf3..6d84a5ff61c 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -36,6 +36,7 @@ static char this_user[100]="";
static char this_salt[100]="";
static char this_crypted[100]="";
+#ifdef SMB_PASSWD
/* Data to do lanman1/2 password challenge. */
static unsigned char saved_challenge[8];
static BOOL challenge_sent=False;
@@ -45,24 +46,17 @@ Get the next challenge value - no repeats.
********************************************************************/
void generate_next_challenge(char *challenge)
{
- unsigned char buf[16];
- static int counter = 0;
- struct timeval tval;
- int v1,v2;
-
- /* get a sort-of random number */
- GetTimeOfDay(&tval);
- v1 = (counter++) + getpid() + tval.tv_sec;
- v2 = (counter++) * getpid() + tval.tv_usec;
- SIVAL(challenge,0,v1);
- SIVAL(challenge,4,v2);
-
- /* mash it up with md4 */
- mdfour(buf, (unsigned char *)challenge, 8);
-
- memcpy(saved_challenge, buf, 8);
- memcpy(challenge,buf,8);
- challenge_sent = True;
+ static int counter = 0;
+ struct timeval tval;
+ int v1,v2;
+ GetTimeOfDay(&tval);
+ v1 = (counter++) + getpid() + tval.tv_sec;
+ v2 = (counter++) * getpid() + tval.tv_usec;
+ SIVAL(challenge,0,v1);
+ SIVAL(challenge,4,v2);
+ E1((uchar *)challenge,(uchar *)"SAMBA",(uchar *)saved_challenge);
+ memcpy(challenge,saved_challenge,8);
+ challenge_sent = True;
}
/*******************************************************************
@@ -84,6 +78,7 @@ BOOL last_challenge(char *challenge)
memcpy(challenge,saved_challenge,8);
return(True);
}
+#endif
/* this holds info on user ids that are already validated for this VC */
static user_struct *validated_users = NULL;
@@ -406,7 +401,7 @@ static char *PAM_password;
* echo off means password.
*/
static int PAM_conv (int num_msg,
- struct pam_message **msg,
+ const struct pam_message **msg,
struct pam_response **resp,
void *appdata_ptr) {
int count = 0, replies = 0;
@@ -817,6 +812,7 @@ Hence we make a direct return to avoid a second chance!!!
#endif
}
+#ifdef SMB_PASSWD
/****************************************************************************
core of smb password checking routine.
****************************************************************************/
@@ -858,6 +854,7 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha
#endif
return (memcmp(p24, password, 24) == 0);
}
+#endif
/****************************************************************************
check if a username/password is OK
@@ -867,16 +864,21 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd)
pstring pass2;
int level = lp_passwordlevel();
struct passwd *pass;
+#ifdef SMB_PASSWD
char challenge[8];
struct smb_passwd *smb_pass;
BOOL challenge_done = False;
+#endif
if (password) password[pwlen] = 0;
+#ifdef SMB_PASSWD
if (pwlen == 24)
challenge_done = last_challenge(challenge);
+#endif
#if DEBUG_PASSWORD
+#ifdef SMB_PASSWD
if (challenge_done)
{
int i;
@@ -884,9 +886,10 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd)
for( i = 0; i < 24; i++)
DEBUG(100,("%0x ", (unsigned char)password[i]));
DEBUG(100,("]\n"));
- } else {
- DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password));
}
+ else
+#endif
+ DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password));
#endif
if (!password)
@@ -903,6 +906,8 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd)
else
pass = Get_Pwnam(user,True);
+#ifdef SMB_PASSWD
+
DEBUG(4,("SMB Password - pwlen = %d, challenge_done = %d\n", pwlen, challenge_done));
if((pwlen == 24) && challenge_done)
@@ -959,6 +964,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd)
DEBUG(3,("Error smb_password_check failed\n"));
}
+#endif
DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen));
@@ -1520,7 +1526,7 @@ BOOL server_cryptkey(char *buf)
struct in_addr dest_ip;
int port = SMB_PORT;
BOOL ret;
-
+
if(secserver_inbuf == NULL) {
secserver_inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
if(secserver_inbuf == NULL) {
@@ -1590,12 +1596,12 @@ BOOL server_cryptkey(char *buf)
and the remote machine name.
*/
{
- char buf2[32]; /* create name as PIDname */
- sprintf(buf2,"%d", getpid());
- strncpy(&buf2[strlen(buf2)], remote_machine, 31 - strlen(buf2));
- buf2[31] = '\0';
- DEBUG(1,("negprot w/password server as %s\n",buf2));
- name_mangle(buf2,p,' ');
+ char buf[32]; /* create name as PIDname */
+ sprintf(buf,"%d", getpid());
+ strncpy(&buf[strlen(buf)], remote_machine, 31 - strlen(buf));
+ buf[31] = '\0';
+ DEBUG(1,("negprot w/password server as %s\n",buf));
+ name_mangle(buf,p,' ');
len += name_len(p);
}
diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c
index a465e911459..2cc6eea506f 100644
--- a/source/smbd/pipes.c
+++ b/source/smbd/pipes.c
@@ -127,7 +127,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
unixmode = unix_mode(cnum,smb_attr);
open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
- 0, &rmode,&smb_action);
+ &rmode,&smb_action);
if (!Files[fnum].open)
{
@@ -141,7 +141,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
}
if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
- close_file(fnum);
+ close_file(fnum, 0);
return(ERROR(ERRDOS,ERRnoaccess));
}
@@ -149,7 +149,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
fmode = dos_mode(cnum,fname,&sbuf);
mtime = sbuf.st_mtime;
if (fmode & aDIR) {
- close_file(fnum);
+ close_file(fnum, 0);
return(ERROR(ERRDOS,ERRnoaccess));
}
diff --git a/source/smbd/predict.c b/source/smbd/predict.c
index 691d8fbb4e0..7d6b2498f5a 100644
--- a/source/smbd/predict.c
+++ b/source/smbd/predict.c
@@ -53,24 +53,37 @@ int read_predict(int fd,int offset,char *buf,char **ptr,int num)
offset >= rp_offset &&
possible>0 &&
smb_last_time-rp_time < rp_timeout)
- {
- ret = possible;
- if (buf)
- memcpy(buf,rp_buffer + (offset-rp_offset),possible);
- else
- *ptr = rp_buffer + (offset-rp_offset);
- DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num));
- }
+ {
+ ret = possible;
+ if (buf)
+ memcpy(buf,rp_buffer + (offset-rp_offset),possible);
+ else
+ *ptr = rp_buffer + (offset-rp_offset);
+ DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num));
+ }
if (ret == num) {
predict_skip = True;
} else {
- predict_skip = False;
+ struct stat rp_stat;
+
+ /* Find the end of the file - ensure we don't
+ read predict beyond it. */
+ if(fstat(fd,&rp_stat) < 0)
+ {
+ DEBUG(0,("read-prediction failed on fstat. Error was %s\n", strerror(errno)));
+ predict_skip = True;
+ }
+ else
+ {
+ predict_skip = False;
- /* prepare the next prediction */
- rp_predict_fd = fd;
- rp_predict_offset = offset + num;
- rp_predict_length = num;
+ /* prepare the next prediction */
+ rp_predict_fd = fd;
+ /* Make sure we don't seek beyond the end of the file. */
+ rp_predict_offset = MIN((offset + num),rp_stat.st_size);
+ rp_predict_length = num;
+ }
}
if (ret < 0) ret = 0;
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c
index d4f746c9e36..2d238dfaf17 100644
--- a/source/smbd/quotas.c
+++ b/source/smbd/quotas.c
@@ -416,10 +416,12 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
}
return (True);
}
+
#else
#ifdef __FreeBSD__
#include <ufs/ufs/quota.h>
+#include <machine/param.h>
#elif AIX
/* AIX quota patch from Ole Holm Nielsen <ohnielse@fysik.dtu.dk> */
#include <jfs/quota.h>
@@ -463,7 +465,25 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
}
#else /* USE_SETRES */
#if defined(__FreeBSD__)
- r= quotactl(path,Q_GETQUOTA,euser_id,(char *) &D);
+ {
+ /* FreeBSD patches from Marty Moll <martym@arbor.edu> */
+ uid_t user_id;
+ gid_t egrp_id;
+
+ /* Need to be root to get quotas in FreeBSD */
+ user_id = getuid();
+ egrp_id = getegid();
+ setuid(0);
+ seteuid(0);
+ r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
+
+ /* As FreeBSD has group quotas, if getting the user
+ quota fails, try getting the group instead. */
+ if (r)
+ r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D);
+ setuid(user_id);
+ seteuid(euser_id);
+ }
#elif defined(AIX)
/* AIX has both USER and GROUP quotas:
Get the USER quota (ohnielse@fysik.dtu.dk) */
@@ -474,7 +494,12 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
#endif /* USE_SETRES */
/* Use softlimit to determine disk space, except when it has been exceeded */
+#if defined(__FreeBSD__)
+ *bsize = DEV_BSIZE;
+#else /* !__FreeBSD__ */
*bsize = 1024;
+#endif /*!__FreeBSD__ */
+
if (r)
{
if (errno == EDQUOT)
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index a8f674183c5..ffa80aac870 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -42,7 +42,6 @@ extern BOOL short_case_preserve;
extern pstring sesssetup_user;
extern fstring myworkgroup;
extern int Client;
-extern int global_oplock_break;
/* this macro should always be used to extract an fnum (smb_fid) from
a packet to ensure chaining works correctly */
@@ -66,18 +65,18 @@ static void overflow_attack(int len)
****************************************************************************/
int reply_special(char *inbuf,char *outbuf)
{
- int outsize = 4;
- int msg_type = CVAL(inbuf,0);
- int msg_flags = CVAL(inbuf,1);
- pstring name1,name2;
- extern fstring remote_machine;
- extern fstring local_machine;
- char *p;
-
- *name1 = *name2 = 0;
-
- smb_setlen(outbuf,0);
-
+ int outsize = 4;
+ int msg_type = CVAL(inbuf,0);
+ int msg_flags = CVAL(inbuf,1);
+ pstring name1,name2;
+ extern fstring remote_machine;
+ extern fstring local_machine;
+ char *p;
+
+ *name1 = *name2 = 0;
+
+ smb_setlen(outbuf,0);
+
switch (msg_type) {
case 0x81: /* session request */
CVAL(outbuf,0) = 0x82;
@@ -122,15 +121,15 @@ int reply_special(char *inbuf,char *outbuf)
DEBUG(0,("Unexpected session response\n"));
break;
- case 0x85: /* session keepalive */
- default:
- return(0);
- }
-
+ case 0x85: /* session keepalive */
+ default:
+ return(0);
+ }
+
DEBUG(5,("%s init msg_type=0x%x msg_flags=0x%x\n",
timestring(),msg_type,msg_flags));
-
- return(outsize);
+
+ return(outsize);
}
@@ -252,7 +251,7 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
if ((SVAL(inbuf,smb_vwv2) & 0x1) != 0)
close_cnum(SVAL(inbuf,smb_tid),vuid);
- if (passlen > MAX_PASSWORD_LENGTH) {
+ if (passlen > MAX_PASS_LEN) {
overflow_attack(passlen);
}
@@ -388,7 +387,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
if (Protocol < PROTOCOL_NT1) {
smb_apasslen = SVAL(inbuf,smb_vwv7);
- if (smb_apasslen > MAX_PASSWORD_LENGTH)
+ if (smb_apasslen > MAX_PASS_LEN)
{
overflow_attack(smb_apasslen);
}
@@ -423,12 +422,12 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
if (passlen1 != 24 && passlen2 != 24)
doencrypt = False;
- if (passlen1 > MAX_PASSWORD_LENGTH) {
+ if (passlen1 > MAX_PASS_LEN) {
overflow_attack(passlen1);
}
- passlen1 = MIN(passlen1, MAX_PASSWORD_LENGTH);
- passlen2 = MIN(passlen2, MAX_PASSWORD_LENGTH);
+ passlen1 = MIN(passlen1, MAX_PASS_LEN);
+ passlen2 = MIN(passlen2, MAX_PASS_LEN);
if(doencrypt) {
/* Save the lanman2 password and the NT md4 password. */
@@ -599,7 +598,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
if (!done_sesssetup)
max_send = MIN(max_send,smb_bufsize);
- DEBUG(6,("Client requested max send size of %d\n", max_send));
+ DEBUG(5,(" Client requested max send size of %d\n", max_send));
done_sesssetup = True;
@@ -640,15 +639,6 @@ int reply_chkpth(char *inbuf,char *outbuf)
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
-
- /* Ugly - NT specific hack - but needed (JRA) */
- if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
- (get_remote_arch() == RA_WINNT))
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbaddirectory;
- }
-
return(UNIXERROR(ERRDOS,ERRbadpath));
}
@@ -1111,8 +1101,6 @@ int reply_open(char *inbuf,char *outbuf)
int rmode=0;
struct stat sbuf;
BOOL bad_path = False;
- files_struct *fsp;
- int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
cnum = SVAL(inbuf,smb_tid);
@@ -1137,12 +1125,9 @@ int reply_open(char *inbuf,char *outbuf)
unixmode = unix_mode(cnum,aARCH);
- open_file_shared(fnum,cnum,fname,share_mode,3,unixmode,
- oplock_request,&rmode,NULL);
-
- fsp = &Files[fnum];
+ open_file_shared(fnum,cnum,fname,share_mode,3,unixmode,&rmode,NULL);
- if (!fsp->open)
+ if (!Files[fnum].open)
{
if((errno == ENOENT) && bad_path)
{
@@ -1152,8 +1137,8 @@ int reply_open(char *inbuf,char *outbuf)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
- close_file(fnum);
+ if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
+ close_file(fnum, 0);
return(ERROR(ERRDOS,ERRnoaccess));
}
@@ -1163,7 +1148,7 @@ int reply_open(char *inbuf,char *outbuf)
if (fmode & aDIR) {
DEBUG(3,("attempt to open a directory %s\n",fname));
- close_file(fnum);
+ close_file(fnum, 0);
return(ERROR(ERRDOS,ERRnoaccess));
}
@@ -1174,12 +1159,10 @@ int reply_open(char *inbuf,char *outbuf)
SIVAL(outbuf,smb_vwv4,size);
SSVAL(outbuf,smb_vwv6,rmode);
- if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ if (lp_fake_oplocks(SNUM(cnum))) {
+ CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5));
}
- if(fsp->granted_oplock)
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
return(outsize);
}
@@ -1194,7 +1177,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
int fnum = -1;
int smb_mode = SVAL(inbuf,smb_vwv3);
int smb_attr = SVAL(inbuf,smb_vwv5);
- BOOL oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
+ BOOL oplock_request = BITSETW(inbuf+smb_vwv2,1);
#if 0
int open_flags = SVAL(inbuf,smb_vwv2);
int smb_sattr = SVAL(inbuf,smb_vwv4);
@@ -1206,7 +1189,6 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
struct stat sbuf;
int smb_action = 0;
BOOL bad_path = False;
- files_struct *fsp;
/* If it's an IPC, pass off the pipe handler. */
if (IS_IPC(cnum))
@@ -1234,11 +1216,9 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
unixmode = unix_mode(cnum,smb_attr | aARCH);
open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
- oplock_request, &rmode,&smb_action);
+ &rmode,&smb_action);
- fsp = &Files[fnum];
-
- if (!fsp->open)
+ if (!Files[fnum].open)
{
if((errno == ENOENT) && bad_path)
{
@@ -1248,8 +1228,8 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
- close_file(fnum);
+ if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
+ close_file(fnum, 0);
return(ERROR(ERRDOS,ERRnoaccess));
}
@@ -1257,18 +1237,12 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
fmode = dos_mode(cnum,fname,&sbuf);
mtime = sbuf.st_mtime;
if (fmode & aDIR) {
- close_file(fnum);
+ close_file(fnum, 0);
return(ERROR(ERRDOS,ERRnoaccess));
}
if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
- smb_action |= EXTENDED_OPLOCK_GRANTED;
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
- }
-
- if(fsp->granted_oplock) {
- smb_action |= EXTENDED_OPLOCK_GRANTED;
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ smb_action |= (1<<15);
}
set_message(outbuf,15,0,True);
@@ -1303,7 +1277,7 @@ int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize)
int i;
for (i=0;i<MAX_OPEN_FILES;i++)
if (Files[i].uid == vuser->uid && Files[i].open) {
- close_file(i);
+ close_file(i, 0);
}
}
@@ -1330,8 +1304,6 @@ int reply_mknew(char *inbuf,char *outbuf)
mode_t unixmode;
int ofun = 0;
BOOL bad_path = False;
- files_struct *fsp;
- int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
com = SVAL(inbuf,smb_com);
cnum = SVAL(inbuf,smb_tid);
@@ -1373,12 +1345,9 @@ int reply_mknew(char *inbuf,char *outbuf)
}
/* Open file in dos compatibility share mode. */
- open_file_shared(fnum,cnum,fname,(DENY_FCB<<4)|0xF, ofun, unixmode,
- oplock_request, NULL, NULL);
+ open_file_shared(fnum,cnum,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, NULL, NULL);
- fsp = &Files[fnum];
-
- if (!fsp->open)
+ if (!Files[fnum].open)
{
if((errno == ENOENT) && bad_path)
{
@@ -1391,13 +1360,10 @@ int reply_mknew(char *inbuf,char *outbuf)
outsize = set_message(outbuf,1,0,True);
SSVAL(outbuf,smb_vwv0,fnum);
- if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ if (lp_fake_oplocks(SNUM(cnum))) {
+ CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5));
}
-
- if(fsp->granted_oplock)
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
-
+
DEBUG(2,("new file %s\n",fname));
DEBUG(3,("%s mknew %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname,Files[fnum].fd_ptr->fd,fnum,cnum,createmode,unixmode));
@@ -1418,8 +1384,6 @@ int reply_ctemp(char *inbuf,char *outbuf)
int createmode;
mode_t unixmode;
BOOL bad_path = False;
- files_struct *fsp;
- int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
cnum = SVAL(inbuf,smb_tid);
createmode = SVAL(inbuf,smb_vwv0);
@@ -1447,12 +1411,9 @@ int reply_ctemp(char *inbuf,char *outbuf)
/* Open file in dos compatibility share mode. */
/* We should fail if file exists. */
- open_file_shared(fnum,cnum,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode,
- oplock_request, NULL, NULL);
+ open_file_shared(fnum,cnum,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, NULL, NULL);
- fsp = &Files[fnum];
-
- if (!fsp->open)
+ if (!Files[fnum].open)
{
if((errno == ENOENT) && bad_path)
{
@@ -1467,13 +1428,10 @@ int reply_ctemp(char *inbuf,char *outbuf)
CVAL(smb_buf(outbuf),0) = 4;
strcpy(smb_buf(outbuf) + 1,fname2);
- if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ if (lp_fake_oplocks(SNUM(cnum))) {
+ CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5));
}
- if(fsp->granted_oplock)
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
-
DEBUG(2,("created temp file %s\n",fname2));
DEBUG(3,("%s ctemp %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname2,Files[fnum].fd_ptr->fd,fnum,cnum,createmode,unixmode));
@@ -1621,22 +1579,6 @@ int reply_readbraw(char *inbuf, char *outbuf)
int fd;
char *fname;
-#ifdef USE_OPLOCKS
- /*
- * Special check if an oplock break has been issued
- * and the readraw request croses on the wire, we must
- * return a zero length response here.
- */
-
- if(global_oplock_break)
- {
- _smb_setlen(header,0);
- transfer_file(0,Client,0,header,4,0);
- DEBUG(5,("readbraw - oplock break finished\n"));
- return -1;
- }
-#endif
-
cnum = SVAL(inbuf,smb_tid);
fnum = GETFNUM(inbuf,smb_vwv0);
@@ -2248,7 +2190,7 @@ int reply_close(char *inbuf,char *outbuf)
/* try and set the date */
set_filetime(Files[fnum].name,mtime);
- close_file(fnum);
+ close_file(fnum, 1);
/* We have a cached error */
if(eclass || err)
@@ -2295,7 +2237,7 @@ int reply_writeclose(char *inbuf,char *outbuf)
set_filetime(Files[fnum].name,mtime);
- close_file(fnum);
+ close_file(fnum, 1);
DEBUG(3,("%s writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n",
timestring(),fnum,cnum,numtowrite,nwritten,
@@ -2492,8 +2434,7 @@ int reply_printopen(char *inbuf,char *outbuf)
return(ERROR(ERRDOS,ERRnoaccess));
/* Open for exclusive use, write only. */
- open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0),
- 0, NULL, NULL);
+ open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0), NULL, NULL);
if (!Files[fnum].open)
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2527,7 +2468,7 @@ int reply_printclose(char *inbuf,char *outbuf)
if (!CAN_PRINT(cnum))
return(ERROR(ERRDOS,ERRnoaccess));
- close_file(fnum);
+ close_file(fnum, 1);
DEBUG(3,("%s printclose fd=%d fnum=%d cnum=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum));
@@ -2695,66 +2636,6 @@ int reply_mkdir(char *inbuf,char *outbuf)
return(outsize);
}
-/****************************************************************************
-Static function used by reply_rmdir to delete an entire directory
-tree recursively.
-****************************************************************************/
-static BOOL recursive_rmdir(char *directory)
-{
- char *dname = NULL;
- BOOL ret = False;
- void *dirptr = OpenDir(-1, directory, False);
-
- if(dirptr == NULL)
- return True;
-
- while((dname = ReadDirName(dirptr)))
- {
- pstring fullname;
- struct stat st;
-
- if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
- continue;
-
- /* Construct the full name. */
- if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
- {
- errno = ENOMEM;
- ret = True;
- break;
- }
- strcpy(fullname, directory);
- strcat(fullname, "/");
- strcat(fullname, dname);
-
- if(sys_lstat(fullname, &st) != 0)
- {
- ret = True;
- break;
- }
-
- if(st.st_mode & S_IFDIR)
- {
- if(recursive_rmdir(fullname)!=0)
- {
- ret = True;
- break;
- }
- if(sys_rmdir(fullname) != 0)
- {
- ret = True;
- break;
- }
- }
- else if(sys_unlink(fullname) != 0)
- {
- ret = True;
- break;
- }
- }
- CloseDir(dirptr);
- return ret;
-}
/****************************************************************************
reply to a rmdir
@@ -2823,15 +2704,10 @@ int reply_rmdir(char *inbuf,char *outbuf)
if(sys_lstat(fullname, &st) != 0)
break;
if(st.st_mode & S_IFDIR)
- {
- if(lp_recursive_veto_delete(SNUM(cnum)))
{
- if(recursive_rmdir(fullname) != 0)
+ if(sys_rmdir(fullname) != 0)
break;
}
- if(sys_rmdir(fullname) != 0)
- break;
- }
else if(sys_unlink(fullname) != 0)
break;
}
@@ -3155,7 +3031,7 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun,
fnum1 = find_free_file();
if (fnum1<0) return(False);
open_file_shared(fnum1,cnum,src,(DENY_NONE<<4),
- 1,0,0,&Access,&action);
+ 1,0,&Access,&action);
if (!Files[fnum1].open) return(False);
@@ -3164,14 +3040,14 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun,
fnum2 = find_free_file();
if (fnum2<0) {
- close_file(fnum1);
+ close_file(fnum1, 0);
return(False);
}
open_file_shared(fnum2,cnum,dest,(DENY_NONE<<4)|1,
- ofun,st.st_mode,0,&Access,&action);
+ ofun,st.st_mode,&Access,&action);
if (!Files[fnum2].open) {
- close_file(fnum1);
+ close_file(fnum1, 0);
return(False);
}
@@ -3182,8 +3058,8 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun,
if (st.st_size)
ret = transfer_file(Files[fnum1].fd_ptr->fd,Files[fnum2].fd_ptr->fd,st.st_size,NULL,0,0);
- close_file(fnum1);
- close_file(fnum2);
+ close_file(fnum1, 0);
+ close_file(fnum2, 0);
return(ret == st.st_size);
}
@@ -3370,10 +3246,7 @@ int reply_setdir(char *inbuf,char *outbuf)
int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
{
int fnum = GETFNUM(inbuf,smb_vwv2);
- unsigned char locktype = CVAL(inbuf,smb_vwv3);
-#if 0
- unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
-#endif /* USE_OPLOCKS */
+ uint16 locktype = SVAL(inbuf,smb_vwv3);
uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
uint16 num_locks = SVAL(inbuf,smb_vwv7);
uint32 count, offset;
@@ -3390,50 +3263,6 @@ int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
CHECK_ERROR(fnum);
data = smb_buf(inbuf);
-
-#ifdef USE_OPLOCKS
- /* Check if this is an oplock break on a file
- we have granted an oplock on.
- */
- if((locktype == LOCKING_ANDX_OPLOCK_RELEASE) &&
- (num_ulocks == 0) && (num_locks == 0) &&
- (CVAL(inbuf,smb_vwv0) == 0xFF))
- {
- share_lock_token token;
- files_struct *fsp = &Files[fnum];
- uint32 dev = fsp->fd_ptr->dev;
- uint32 inode = fsp->fd_ptr->inode;
-
- DEBUG(5,("reply_lockingX: oplock break reply from client for fnum = %d\n",
- fnum));
- /*
- * Make sure we have granted an oplock on this file.
- */
- if(!fsp->granted_oplock)
- {
- DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
-no oplock granted on this file.\n", fnum));
- return ERROR(ERRDOS,ERRlock);
- }
-
- /* Remove the oplock flag from the sharemode. */
- lock_share_entry(fsp->cnum, dev, inode, &token);
- if(remove_share_oplock( fnum, token)==False)
- {
- DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
-dev = %x, inode = %x\n", fnum, dev, inode));
- unlock_share_entry(fsp->cnum, dev, inode, token);
- return -1;
- }
- unlock_share_entry(fsp->cnum, dev, inode, token);
-
- /* Clear the granted flag and return. */
-
- fsp->granted_oplock = False;
- return -1;
- }
-#endif /* USE_OPLOCKS */
-
/* Data now points at the beginning of the list
of smb_unlkrng structs */
for(i = 0; i < (int)num_ulocks; i++) {
@@ -3468,7 +3297,7 @@ dev = %x, inode = %x\n", fnum, dev, inode));
set_message(outbuf,2,0,True);
DEBUG(3,("%s lockingX fnum=%d cnum=%d type=%d num_locks=%d num_ulocks=%d\n",
- timestring(),fnum,cnum,(unsigned int)locktype,num_locks,num_ulocks));
+ timestring(),fnum,cnum,locktype,num_locks,num_ulocks));
chain_fnum = fnum;
@@ -3821,3 +3650,8 @@ int reply_getattrE(char *inbuf,char *outbuf)
return(outsize);
}
+
+
+
+
+
diff --git a/source/smbd/server.c b/source/smbd/server.c
index b250572a1f4..3bfd5bbbf40 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -84,16 +84,6 @@ int chain_fnum = -1;
/* number of open connections */
static int num_connections_open = 0;
-#ifdef USE_OPLOCKS
-/* Oplock ipc UDP socket. */
-int oplock_sock = -1;
-uint16 oplock_port = 0;
-/* Current number of oplocks we have outstanding. */
-int32 global_oplocks_open = 0;
-#endif /* USE_OPLOCKS */
-
-BOOL global_oplock_break = False;
-
extern fstring remote_machine;
pstring OriginalDir;
@@ -189,7 +179,7 @@ int dos_mode(int cnum,char *path,struct stat *sbuf)
int result = 0;
extern struct current_user current_user;
- DEBUG(8,("dos_mode: %d %s\n", cnum, path));
+ DEBUG(5,("dos_mode: %d %s\n", cnum, path));
if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
if (!((sbuf->st_mode & S_IWOTH) ||
@@ -241,15 +231,15 @@ int dos_mode(int cnum,char *path,struct stat *sbuf)
result |= aHIDDEN;
}
- DEBUG(8,("dos_mode returning "));
+ DEBUG(5,("dos_mode returning "));
- if (result & aHIDDEN) DEBUG(8, ("h"));
- if (result & aRONLY ) DEBUG(8, ("r"));
- if (result & aSYSTEM) DEBUG(8, ("s"));
- if (result & aDIR ) DEBUG(8, ("d"));
- if (result & aARCH ) DEBUG(8, ("a"));
+ if (result & aHIDDEN) DEBUG(5, ("h"));
+ if (result & aRONLY ) DEBUG(5, ("r"));
+ if (result & aSYSTEM) DEBUG(5, ("s"));
+ if (result & aDIR ) DEBUG(5, ("d"));
+ if (result & aARCH ) DEBUG(5, ("a"));
- DEBUG(8,("\n"));
+ DEBUG(5,("\n"));
return(result);
}
@@ -713,7 +703,15 @@ int disk_free(char *path,int *bsize,int *dfree,int *dsize)
dfree_retval : dfreeq_retval ;
/* maybe dfree and dfreeq are calculated using different bsizes
so convert dfree from bsize into bsizeq */
- *dfree = ((*dfree) * (*bsize)) / (bsizeq);
+ /* avoid overflows due to multiplication, so do not:
+ *dfree = ((*dfree) * (*bsize)) / (bsizeq);
+ bsize and bsizeq are powers of 2 so its better to
+ to divide them getting a multiplication or division factor
+ for dfree. Rene Nieuwenhuizen (07-10-1997) */
+ if (*bsize >= bsizeq)
+ *dfree = *dfree * (*bsize / bsizeq);
+ else
+ *dfree = *dfree / (bsizeq / *bsize);
*dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
*bsize = bsizeq;
*dsize = dsizeq;
@@ -803,7 +801,15 @@ if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
dfree_retval : dfreeq_retval ;
/* maybe dfree and dfreeq are calculated using different bsizes
so convert dfree from bsize into bsizeq */
- *dfree = ((*dfree) * (*bsize)) / (bsizeq);
+ /* avoid overflows due to multiplication, so do not:
+ *dfree = ((*dfree) * (*bsize)) / (bsizeq);
+ bsize and bsizeq are powers of 2 so its better to
+ to divide them getting a multiplication or division factor
+ for dfree. Rene Nieuwenhuizen (07-10-1997) */
+ if (*bsize >= bsizeq)
+ *dfree = *dfree * (*bsize / bsizeq);
+ else
+ *dfree = *dfree / (bsizeq / *bsize);
*dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
*bsize = bsizeq;
*dsize = dsizeq;
@@ -886,7 +892,8 @@ static void check_for_pipe(char *fname)
/****************************************************************************
fd support routines - attempt to do a sys_open
****************************************************************************/
-static int fd_attempt_open(char *fname, int flags, int mode)
+
+int fd_attempt_open(char *fname, int flags, int mode)
{
int fd = sys_open(fname,flags,mode);
@@ -938,7 +945,7 @@ static int fd_attempt_open(char *fname, int flags, int mode)
fd support routines - attempt to find an already open file by dev
and inode - increments the ref_count of the returned file_fd_struct *.
****************************************************************************/
-static file_fd_struct *fd_get_already_open(struct stat *sbuf)
+file_fd_struct *fd_get_already_open(struct stat *sbuf)
{
int i;
file_fd_struct *fd_ptr;
@@ -965,7 +972,7 @@ static file_fd_struct *fd_get_already_open(struct stat *sbuf)
fd support routines - attempt to find a empty slot in the FileFd array.
Increments the ref_count of the returned entry.
****************************************************************************/
-static file_fd_struct *fd_get_new()
+file_fd_struct *fd_get_new()
{
int i;
file_fd_struct *fd_ptr;
@@ -998,7 +1005,8 @@ n"));
fd support routines - attempt to re-open an already open fd as O_RDWR.
Save the already open fd (we cannot close due to POSIX file locking braindamage.
****************************************************************************/
-static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
+
+void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
{
int fd = sys_open( fname, O_RDWR, mode);
@@ -1018,7 +1026,7 @@ static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
fd support routines - attempt to close the file referenced by this fd.
Decrements the ref_count and returns it.
****************************************************************************/
-static int fd_attempt_close(file_fd_struct *fd_ptr)
+int fd_attempt_close(file_fd_struct *fd_ptr)
{
DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
fd_ptr - &FileFd[0],
@@ -1054,11 +1062,9 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
pstring fname;
struct stat statbuf;
file_fd_struct *fd_ptr;
- files_struct *fsp = &Files[fnum];
- fsp->open = False;
- fsp->fd_ptr = 0;
- fsp->granted_oplock = False;
+ Files[fnum].open = False;
+ Files[fnum].fd_ptr = 0;
errno = EPERM;
pstrcpy(fname,fname1);
@@ -1196,7 +1202,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
lp_minprintspace(SNUM(cnum))) {
fd_attempt_close(fd_ptr);
- fsp->fd_ptr = 0;
+ Files[fnum].fd_ptr = 0;
if(fd_ptr->ref_count == 0)
sys_unlink(fname);
errno = ENOSPC;
@@ -1232,26 +1238,25 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
fd_ptr->dev = (uint32)sbuf->st_dev;
fd_ptr->inode = (uint32)sbuf->st_ino;
- fsp->fd_ptr = fd_ptr;
+ Files[fnum].fd_ptr = fd_ptr;
Connections[cnum].num_files_open++;
- fsp->mode = sbuf->st_mode;
- GetTimeOfDay(&fsp->open_time);
- fsp->uid = current_user.id;
- fsp->size = 0;
- fsp->pos = -1;
- fsp->open = True;
- fsp->mmap_ptr = NULL;
- fsp->mmap_size = 0;
- fsp->can_lock = True;
- fsp->can_read = ((flags & O_WRONLY)==0);
- fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
- fsp->share_mode = 0;
- fsp->print_file = Connections[cnum].printer;
- fsp->modified = False;
- fsp->granted_oplock = False;
- fsp->cnum = cnum;
- string_set(&fsp->name,dos_to_unix(fname,False));
- fsp->wbmpx_ptr = NULL;
+ Files[fnum].mode = sbuf->st_mode;
+ GetTimeOfDay(&Files[fnum].open_time);
+ Files[fnum].uid = current_user.id;
+ Files[fnum].size = 0;
+ Files[fnum].pos = -1;
+ Files[fnum].open = True;
+ Files[fnum].mmap_ptr = NULL;
+ Files[fnum].mmap_size = 0;
+ Files[fnum].can_lock = True;
+ 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].print_file = Connections[cnum].printer;
+ Files[fnum].modified = False;
+ Files[fnum].cnum = cnum;
+ string_set(&Files[fnum].name,dos_to_unix(fname,False));
+ Files[fnum].wbmpx_ptr = NULL;
/*
* If the printer is marked as postscript output a leading
@@ -1260,8 +1265,8 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
* This has a similar effect as CtrlD=0 in WIN.INI file.
* tim@fsg.com 09/06/94
*/
- if (fsp->print_file && POSTSCRIPT(cnum) &&
- fsp->can_write)
+ if (Files[fnum].print_file && POSTSCRIPT(cnum) &&
+ Files[fnum].can_write)
{
DEBUG(3,("Writing postscript line\n"));
write_file(fnum,"%!\n",3);
@@ -1269,23 +1274,23 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
timestring(),Connections[cnum].user,fname,
- BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
+ BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write),
Connections[cnum].num_files_open,fnum));
}
#if USE_MMAP
/* mmap it if read-only */
- if (!fsp->can_write)
+ if (!Files[fnum].can_write)
{
- fsp->mmap_size = file_size(fname);
- fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
- PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
+ 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_ptr->fd,0);
- if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
+ if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr)
{
DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
- fsp->mmap_ptr = NULL;
+ Files[fnum].mmap_ptr = NULL;
}
}
#endif
@@ -1343,8 +1348,13 @@ static void check_magic(int fnum,int cnum)
/****************************************************************************
close a file - possibly invalidating the read prediction
+
+If normal_close is 1 then this came from a normal SMBclose (or equivalent)
+operation otherwise it came as the result of some other operation such as
+the closing of the connection. In the latter case printing and
+magic scripts are not run
****************************************************************************/
-void close_file(int fnum)
+void close_file(int fnum, int normal_close)
{
files_struct *fs_p = &Files[fnum];
int cnum = fs_p->cnum;
@@ -1356,17 +1366,17 @@ void close_file(int fnum)
fs_p->open = False;
Connections[cnum].num_files_open--;
if(fs_p->wbmpx_ptr)
- {
- free((char *)fs_p->wbmpx_ptr);
- fs_p->wbmpx_ptr = NULL;
- }
+ {
+ free((char *)fs_p->wbmpx_ptr);
+ fs_p->wbmpx_ptr = NULL;
+ }
#if USE_MMAP
if(fs_p->mmap_ptr)
- {
- munmap(fs_p->mmap_ptr,fs_p->mmap_size);
- fs_p->mmap_ptr = NULL;
- }
+ {
+ munmap(fs_p->mmap_ptr,fs_p->mmap_size);
+ fs_p->mmap_ptr = NULL;
+ }
#endif
if (lp_share_modes(SNUM(cnum)))
@@ -1381,11 +1391,12 @@ void close_file(int fnum)
unlock_share_entry( cnum, dev, inode, token);
/* NT uses smbclose to start a print - weird */
- if (fs_p->print_file)
+ if (normal_close && fs_p->print_file)
print_file(fnum);
/* check for magic scripts */
- check_magic(fnum,cnum);
+ if (normal_close)
+ check_magic(fnum,cnum);
DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
timestring(),Connections[cnum].user,fs_p->name,
@@ -1403,8 +1414,7 @@ static int access_table(int new_deny,int old_deny,int old_mode,
if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
- int pid = getpid();
- if (old_deny == new_deny && share_pid == pid)
+ if (old_deny == new_deny && share_pid == getpid())
return(AALL);
if (old_mode == 0) return(AREAD);
@@ -1458,76 +1468,23 @@ BOOL check_file_sharing(int cnum,char *fname)
struct stat sbuf;
share_lock_token token;
int pid = getpid();
- uint32 dev, inode;
if(!lp_share_modes(SNUM(cnum)))
return True;
if (stat(fname,&sbuf) == -1) return(True);
- dev = (uint32)sbuf.st_dev;
- inode = (uint32)sbuf.st_ino;
-
- lock_share_entry(cnum, dev, inode, &token);
- num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
+ 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);
- /*
- * Check if the share modes will give us access.
- */
-
- if(num_share_modes != 0)
+ for( i = 0; i < num_share_modes; i++)
{
- BOOL broke_oplock;
-
- do
- {
-
- broke_oplock = False;
- for(i = 0; i < num_share_modes; i++)
- {
- min_share_mode_entry *share_entry = &old_shares[i];
-
-#ifdef USE_OPLOCKS
- /*
- * Break oplocks before checking share modes. See comment in
- * open_file_shared for details.
- * Check if someone has an oplock on this file. If so we must
- * break it before continuing.
- */
- if(share_entry->op_type & BATCH_OPLOCK)
- {
-
- DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
-dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
-
- /* Oplock break.... */
- unlock_share_entry(cnum, dev, inode, token);
- if(request_oplock_break(share_entry, dev, inode) == False)
- {
- free((char *)old_shares);
- DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
-dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
- return False;
- }
- lock_share_entry(cnum, dev, inode, &token);
- broke_oplock = True;
- break;
- }
-#endif /* USE_OPLOCKS */
-
- /* someone else has a share lock on it, check to see
- if we can too */
- if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
- goto free_and_exit;
+ if (old_shares[i].share_mode != DENY_DOS)
+ goto free_and_exit;
- } /* end for */
-
- if(broke_oplock)
- {
- free((char *)old_shares);
- num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
- }
- } while(broke_oplock);
+ if(old_shares[i].pid != pid)
+ goto free_and_exit;
}
/* XXXX exactly what share mode combinations should be allowed for
@@ -1538,7 +1495,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
free_and_exit:
- unlock_share_entry(cnum, dev, inode, token);
+ unlock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, token);
if(old_shares != NULL)
free((char *)old_shares);
return(ret);
@@ -1559,7 +1516,7 @@ static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
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);
+ close_file(fnum, 0);
/* Share mode no longer locked. */
*share_locked = False;
errno = EACCES;
@@ -1571,52 +1528,12 @@ static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
}
}
-/****************************************************************************
-check if we can open a file with a share mode
-****************************************************************************/
-int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname,
- BOOL fcbopen, int *flags)
-{
- int old_open_mode = share->share_mode &0xF;
- int old_deny_mode = (share->share_mode >>4)&7;
-
- if (old_deny_mode > 4 || old_open_mode > 2)
- {
- DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
- deny_mode,old_deny_mode,old_open_mode,fname));
- return False;
- }
-
- {
- int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
- share->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))
- {
- DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
- deny_mode,old_deny_mode,old_open_mode,
- share->pid,fname, access_allowed));
- return False;
- }
-
- if (access_allowed == AREAD)
- *flags = O_RDONLY;
-
- if (access_allowed == AWRITE)
- *flags = O_WRONLY;
-
- }
- return True;
-}
/****************************************************************************
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 oplock_request, int *Access,int *action)
+ int mode,int *Access,int *action)
{
files_struct *fs_p = &Files[fnum];
int flags=0;
@@ -1629,7 +1546,6 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
share_lock_token token;
uint32 dev = 0;
uint32 inode = 0;
- int num_share_modes = 0;
fs_p->open = False;
fs_p->fd_ptr = 0;
@@ -1701,88 +1617,69 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
if (lp_share_modes(SNUM(cnum)))
{
+ int num_shares = 0;
int i;
min_share_mode_entry *old_shares = 0;
+
if (file_existed)
{
dev = (uint32)sbuf.st_dev;
inode = (uint32)sbuf.st_ino;
lock_share_entry(cnum, dev, inode, &token);
share_locked = True;
- num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
+ num_shares = get_share_modes(cnum, token, dev, inode, &old_shares);
}
- /*
- * Check if the share modes will give us access.
- */
-
- if(share_locked && (num_share_modes != 0))
+ for(i = 0; i < num_shares; i++)
{
- BOOL broke_oplock;
+ /* someone else has a share lock on it, check to see
+ if we can too */
+ int old_open_mode = old_shares[i].share_mode &0xF;
+ int old_deny_mode = (old_shares[i].share_mode >>4)&7;
- do
+ if (old_deny_mode > 4 || old_open_mode > 2)
{
+ DEBUG(0,("Invalid share mode found (%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;
+ return;
+ }
- broke_oplock = False;
- for(i = 0; i < num_share_modes; i++)
- {
- min_share_mode_entry *share_entry = &old_shares[i];
-
-#ifdef USE_OPLOCKS
- /*
- * By observation of NetBench, oplocks are broken *before* share
- * modes are checked. This allows a file to be closed by the client
- * if the share mode would deny access and the client has an oplock.
- * Check if someone has an oplock on this file. If so we must break
- * it before continuing.
- */
- if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
- {
-
- DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
-dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
-
- /* Oplock break.... */
- unlock_share_entry(cnum, dev, inode, token);
- if(request_oplock_break(share_entry, dev, inode) == False)
- {
- free((char *)old_shares);
- DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
-dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
- errno = EACCES;
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- return;
- }
- lock_share_entry(cnum, dev, inode, &token);
- broke_oplock = True;
- break;
- }
-#endif /* USE_OPLOCKS */
-
- /* someone else has a share lock on it, check to see
- if we can too */
- if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
- {
- free((char *)old_shares);
- unlock_share_entry(cnum, dev, inode, token);
- errno = EACCES;
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- return;
- }
-
- } /* end for */
+ {
+ int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
+ old_shares[i].pid,fname);
- if(broke_oplock)
+ if ((access_allowed == AFAIL) ||
+ (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) ||
+ (access_allowed == AREAD && flags == O_WRONLY) ||
+ (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,
+ old_shares[i].pid,fname,
+ access_allowed));
free((char *)old_shares);
- num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
+ if(share_locked)
+ unlock_share_entry(cnum, dev, inode, token);
+ errno = EACCES;
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadshare;
+ return;
}
- } while(broke_oplock);
+
+ if (access_allowed == AREAD)
+ flags = O_RDONLY;
+
+ if (access_allowed == AWRITE)
+ flags = O_WRONLY;
+ }
}
-
if(old_shares != 0)
free((char *)old_shares);
}
@@ -1839,35 +1736,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
file (which expects the share_mode_entry to be there).
*/
if (lp_share_modes(SNUM(cnum)))
- {
- uint16 port = 0;
-#ifdef USE_OPLOCKS
- /* JRA. Currently this only services Exlcusive and batch
- oplocks (no other opens on this file). This needs to
- be extended to level II oplocks (multiple reader
- oplocks). */
-
- if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)))
- {
- fs_p->granted_oplock = True;
- global_oplocks_open++;
- port = oplock_port;
-
- DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
-dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
-
- }
- else
- {
- port = 0;
- oplock_request = 0;
- }
-#else /* USE_OPLOCKS */
- oplock_request = 0;
- port = 0;
-#endif /* USE_OPLOCKS */
- set_share_mode(token, fnum, port, oplock_request);
- }
+ set_share_mode(token, fnum);
if ((flags2&O_TRUNC) && file_existed)
truncate_unless_locked(fnum,cnum,token,&share_locked);
@@ -2116,7 +1985,11 @@ struct
{EPERM,ERRDOS,ERRnoaccess},
{EACCES,ERRDOS,ERRnoaccess},
{ENOENT,ERRDOS,ERRbadfile},
+#if 0 /* Go back to old method for now. */
+ {ENOTDIR,ERRDOS,ERRbaddirectory},
+#else
{ENOTDIR,ERRDOS,ERRbadpath},
+#endif
{EIO,ERRHRD,ERRgeneral},
{EBADF,ERRSRV,ERRsrverror},
{EINVAL,ERRSRV,ERRsrverror},
@@ -2137,6 +2010,23 @@ struct
{0,0,0}
};
+#if 0 /* Go back to old method for now. */
+/* Mapping for old clients. */
+
+struct
+{
+ int new_smb_error;
+ int old_smb_error;
+ int protocol_level;
+ enum remote_arch_types valid_ra_type;
+} old_client_errmap[] =
+{
+ {ERRbaddirectory, ERRbadpath, (int)PROTOCOL_NT1, RA_WINNT},
+ {0,0,0}
+};
+
+#endif /* Go back to old method for now. */
+
/****************************************************************************
create an error packet from errno
****************************************************************************/
@@ -2167,6 +2057,32 @@ int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int
}
}
+#if 0 /* Go back to old method for now. */
+
+ /* Make sure we don't return error codes that old
+ clients don't understand. */
+
+ /* JRA - unfortunately, WinNT needs some error codes
+ for apps to work correctly, Win95 will break if
+ these error codes are returned. But they both
+ negotiate the *same* protocol. So we need to use
+ the revolting 'remote_arch' enum to tie break.
+
+ There must be a better way of doing this...
+ */
+
+ for(i = 0; old_client_errmap[i].new_smb_error != 0; i++)
+ {
+ if(((Protocol < old_client_errmap[i].protocol_level) ||
+ (old_client_errmap[i].valid_ra_type != get_remote_arch())) &&
+ (old_client_errmap[i].new_smb_error == ecode))
+ {
+ ecode = old_client_errmap[i].old_smb_error;
+ break;
+ }
+ }
+#endif /* Go back to old method for now. */
+
return(error_packet(inbuf,outbuf,eclass,ecode,line));
}
@@ -2373,516 +2289,6 @@ static BOOL open_sockets(BOOL is_daemon,int port)
return True;
}
-/****************************************************************************
- process an smb from the client - split out from the process() code so
- it can be used by the oplock break code.
-****************************************************************************/
-
-static void process_smb(char *inbuf, char *outbuf)
-{
- extern int Client;
- static int trans_num;
- int msg_type = CVAL(inbuf,0);
- int32 len = smb_len(inbuf);
- int nread = len + 4;
-
- if (trans_num == 0) {
- /* on the first packet, check the global hosts allow/ hosts
- deny parameters before doing any parsing of the packet
- passed to us by the client. This prevents attacks on our
- parsing code from hosts not in the hosts allow list */
- if (!check_access(-1)) {
- /* send a negative session response "not listining on calling
- name" */
- static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
- DEBUG(1,("%s Connection denied from %s\n",
- timestring(),client_addr()));
- send_smb(Client,(char *)buf);
- exit_server("connection denied");
- }
- }
-
- DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
- DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
-
-#ifdef WITH_VTP
- if(trans_num == 1 && VT_Check(inbuf))
- {
- VT_Process();
- return;
- }
-#endif
-
- if (msg_type == 0)
- show_msg(inbuf);
-
- nread = construct_reply(inbuf,outbuf,nread,max_send);
-
- if(nread > 0)
- {
- if (CVAL(outbuf,0) == 0)
- show_msg(outbuf);
-
- if (nread != smb_len(outbuf) + 4)
- {
- DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
- nread, smb_len(outbuf)));
- }
- else
- send_smb(Client,outbuf);
- }
- trans_num++;
-}
-
-#ifdef USE_OPLOCKS
-/****************************************************************************
- open the oplock IPC socket communication
-****************************************************************************/
-static BOOL open_oplock_ipc()
-{
- struct sockaddr_in sock_name;
- int name_len = sizeof(sock_name);
-
- DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
-
- /* Open a lookback UDP socket on a random port. */
- oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
- if (oplock_sock == -1)
- {
- DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
-address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
- oplock_port = 0;
- return(False);
- }
-
- /* Find out the transient UDP port we have been allocated. */
- if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &name_len)<0)
- {
- DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
- strerror(errno)));
- close(oplock_sock);
- oplock_sock = -1;
- oplock_port = 0;
- return False;
- }
- oplock_port = ntohs(sock_name.sin_port);
-
- return True;
-}
-
-/****************************************************************************
- process an oplock break message.
-****************************************************************************/
-static BOOL process_local_message(int oplock_sock, char *buffer, int buf_size)
-{
- int32 msg_len;
- int16 from_port;
- char *msg_start;
-
- msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
- from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
-
- msg_start = &buffer[UDP_CMD_HEADER_LEN];
-
- DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
- msg_len, from_port));
-
- /* Switch on message command - currently OPLOCK_BREAK_CMD is the
- only valid request. */
-
- switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
- {
- case OPLOCK_BREAK_CMD:
- /* Ensure that the msg length is correct. */
- if(msg_len != OPLOCK_BREAK_MSG_LEN)
- {
- DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
-should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
- return False;
- }
- {
- uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
- uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
- uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
- struct timeval tval;
- struct sockaddr_in toaddr;
-
- tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
- tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
-
- DEBUG(5,("process_local_message: oplock break request from \
-pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
-
- /*
- * If we have no record of any currently open oplocks,
- * it's not an error, as a close command may have
- * just been issued on the file that was oplocked.
- * Just return success in this case.
- */
-
- if(global_oplocks_open != 0)
- {
- if(oplock_break(dev, inode, &tval) == False)
- {
- DEBUG(0,("process_local_message: oplock break failed - \
-not returning udp message.\n"));
- return False;
- }
- }
- else
- {
- DEBUG(3,("process_local_message: oplock break requested with no outstanding \
-oplocks. Returning success.\n"));
- }
-
- /* Send the message back after OR'ing in the 'REPLY' bit. */
- SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
-
- bzero((char *)&toaddr,sizeof(toaddr));
- toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- toaddr.sin_port = htons(from_port);
- toaddr.sin_family = AF_INET;
-
- if(sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
- (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
- {
- DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
- remotepid, strerror(errno)));
- return False;
- }
-
- DEBUG(5,("process_local_message: oplock break reply sent to \
-pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
- from_port, dev, inode));
-
- }
- break;
- default:
- DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
- (unsigned int)SVAL(msg_start,0)));
- return False;
- }
- return True;
-}
-
-/****************************************************************************
- Process an oplock break directly.
-****************************************************************************/
-BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
-{
- extern int Client;
- static char *inbuf = NULL;
- static char *outbuf = NULL;
- files_struct *fsp = NULL;
- int fnum;
- time_t start_time;
- BOOL shutdown_server = False;
-
- DEBUG(5,("oplock_break: called for dev = %x, inode = %x. Current \
-global_oplocks_open = %d\n", dev, inode, global_oplocks_open));
-
- if(inbuf == NULL)
- {
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- if(inbuf == NULL) {
- DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
- return False;
- }
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- if(outbuf == NULL) {
- DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
- free(inbuf);
- inbuf = NULL;
- return False;
- }
- }
-
- /* We need to search the file open table for the
- entry containing this dev and inode, and ensure
- we have an oplock on it. */
- for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
- {
- if(OPEN_FNUM(fnum))
- {
- fsp = &Files[fnum];
- if((fsp->fd_ptr->dev == dev) && (fsp->fd_ptr->inode == inode) &&
- (fsp->open_time.tv_sec == tval->tv_sec) &&
- (fsp->open_time.tv_usec == tval->tv_usec))
- break;
- }
- }
-
- if(fsp == NULL)
- {
- /* The file could have been closed in the meantime - return success. */
- DEBUG(3,("oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
-allowing break to succeed.\n", dev, inode, fnum));
- return True;
- }
-
- /* Ensure we have an oplock on the file */
-
- /* There is a potential race condition in that an oplock could
- have been broken due to another udp request, and yet there are
- still oplock break messages being sent in the udp message
- queue for this file. So return true if we don't have an oplock,
- as we may have just freed it.
- */
-
- if(!fsp->granted_oplock)
- {
- DEBUG(3,("oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \
-Allowing break to succeed regardless.\n", fsp->name, fnum, dev, inode));
- return True;
- }
-
- /* Now comes the horrid part. We must send an oplock break to the client,
- and then process incoming messages until we get a close or oplock release.
- */
-
- /* Prepare the SMBlockingX message. */
- bzero(outbuf,smb_size);
- set_message(outbuf,8,0,True);
-
- SCVAL(outbuf,smb_com,SMBlockingX);
- SSVAL(outbuf,smb_tid,fsp->cnum);
- SSVAL(outbuf,smb_pid,0xFFFF);
- SSVAL(outbuf,smb_uid,0);
- SSVAL(outbuf,smb_mid,0xFFFF);
- SCVAL(outbuf,smb_vwv0,0xFF);
- SSVAL(outbuf,smb_vwv2,fnum);
- SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
- /* Change this when we have level II oplocks. */
- SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
-
- send_smb(Client, outbuf);
-
- global_oplock_break = True;
-
- /* Process incoming messages. */
-
- /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
- seconds we should just die.... */
-
- start_time = time(NULL);
-
- while(OPEN_FNUM(fnum) && fsp->granted_oplock)
- {
- if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
- {
- /*
- * Die if we got an error.
- */
-
- if (smb_read_error == READ_EOF)
- DEBUG(0,("oplock_break: end of file from client\n"));
-
- if (smb_read_error == READ_ERROR)
- DEBUG(0,("oplock_break: receive_smb error (%s)\n",
- strerror(errno)));
-
- if (smb_read_error == READ_TIMEOUT)
- DEBUG(0,("oplock_break: receive_smb timed out after %d seconds.\n",
- OPLOCK_BREAK_TIMEOUT));
-
- DEBUG(0,("oplock_break failed for file %s (fnum = %d, dev = %x, \
-inode = %x).\n", fsp->name, fnum, dev, inode));
- shutdown_server = True;
- break;
- }
- process_smb(inbuf, outbuf);
-
- /* We only need this in case a readraw crossed on the wire. */
- if(global_oplock_break)
- global_oplock_break = False;
-
- /*
- * Die if we go over the time limit.
- */
-
- if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
- {
- DEBUG(0,("oplock_break: no break received from client within \
-%d seconds.\n", OPLOCK_BREAK_TIMEOUT));
- DEBUG(0,("oplock_break failed for file %s (fnum = %d, dev = %x, \
-inode = %x).\n", fsp->name, fnum, dev, inode));
- shutdown_server = True;
- break;
- }
- }
-
- /*
- * If the client did not respond we must die.
- */
-
- if(shutdown_server)
- {
- DEBUG(0,("oplock_break: client failure in break - shutting down this smbd.\n"));
- close_sockets();
- close(oplock_sock);
- exit_server("oplock break failure");
- }
-
- if(OPEN_FNUM(fnum))
- {
- /* The lockingX reply will have removed the oplock flag
- from the sharemode. */
- /* Paranoia.... */
- fsp->granted_oplock = False;
- }
-
- global_oplocks_open--;
-
- /* Santity check - remove this later. JRA */
- if(global_oplocks_open < 0)
- {
- DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
- global_oplocks_open));
- abort();
- }
-
- DEBUG(5,("oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
-global_oplocks_open = %d\n", fnum, dev, inode, global_oplocks_open));
-
- return True;
-}
-
-/****************************************************************************
-Send an oplock break message to another smbd process. If the oplock is held
-by the local smbd then call the oplock break function directly.
-****************************************************************************/
-
-BOOL request_oplock_break(min_share_mode_entry *share_entry,
- uint32 dev, uint32 inode)
-{
- char op_break_msg[OPLOCK_BREAK_MSG_LEN];
- struct sockaddr_in addr_out;
- int pid = getpid();
-
- if(pid == share_entry->pid)
- {
- /* We are breaking our own oplock, make sure it's us. */
- if(share_entry->op_port != oplock_port)
- {
- DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
-should be %d\n", pid, share_entry->op_port, oplock_port));
- return False;
- }
-
- DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
-
- /* Call oplock break direct. */
- return oplock_break(dev, inode, &share_entry->time);
- }
-
- /* We need to send a OPLOCK_BREAK_CMD message to the
- port in the share mode entry. */
-
- SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
- SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
- SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
- SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
- SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
- SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
-
- /* set the address and port */
- bzero((char *)&addr_out,sizeof(addr_out));
- addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- addr_out.sin_port = htons( share_entry->op_port );
- addr_out.sin_family = AF_INET;
-
- DEBUG(3,("request_oplock_break: sending a oplock break message to pid %d on port %d \
-for dev = %x, inode = %x\n", share_entry->pid, share_entry->op_port, dev, inode));
-
- if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
- (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
- {
- DEBUG(0,("request_oplock_break: failed when sending a oplock break message \
-to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
- share_entry->pid, share_entry->op_port, dev, inode,
- strerror(errno)));
- return False;
- }
-
- /*
- * Now we must await the oplock broken message coming back
- * from the target smbd process. Timeout if it fails to
- * return in OPLOCK_BREAK_TIMEOUT seconds.
- * While we get messages that aren't ours, loop.
- */
-
- while(1)
- {
- char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
- int32 reply_msg_len;
- int16 reply_from_port;
- char *reply_msg_start;
-
- if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
- OPLOCK_BREAK_TIMEOUT * 1000) == False)
- {
- if(smb_read_error == READ_TIMEOUT)
- DEBUG(0,("request_oplock_break: no response received to oplock break request to \
-pid %d on port %d for dev = %x, inode = %x\n", share_entry->pid,
- share_entry->op_port, dev, inode));
- else
- DEBUG(0,("request_oplock_break: error in response received to oplock break request to \
-pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", share_entry->pid,
- share_entry->op_port, dev, inode, strerror(errno)));
- return False;
- }
-
- /*
- * If the response we got was not an answer to our message, but
- * was a completely different request, push it onto the pending
- * udp message stack so that we can deal with it in the main loop.
- * It may be another oplock break request to us.
- */
-
- /*
- * Local note from JRA. There exists the possibility of a denial
- * of service attack here by allowing non-root processes running
- * on a local machine sending many of these pending messages to
- * a smbd port. Currently I'm not sure how to restrict the messages
- * I will queue (although I could add a limit to the queue) to
- * those received by root processes only. There should be a
- * way to make this bulletproof....
- */
-
- reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
- reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
-
- reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
-
- if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
- {
- /* Ignore it. */
- DEBUG(0,("request_oplock_break: invalid message length received. Ignoring\n"));
- continue;
- }
-
- if(((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) == 0) ||
- (reply_from_port != share_entry->op_port) ||
- (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
- &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
- OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) != 0))
- {
- DEBUG(3,("request_oplock_break: received other message whilst awaiting \
-oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
- share_entry->pid, share_entry->op_port, dev, inode));
- if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False)
- return False;
- }
-
- break;
- }
-
- DEBUG(3,("request_oplock_break: broke oplock.\n"));
-
- return True;
-}
-
-#endif /* USE_OPLOCKS */
/****************************************************************************
check if a snum is in use
@@ -3440,15 +2846,19 @@ int reply_lanman1(char *outbuf)
set_message(outbuf,13,doencrypt?8:0,True);
SSVAL(outbuf,smb_vwv1,secword);
+#ifdef SMB_PASSWD
/* Create a token value and add it to the outgoing packet. */
if (doencrypt)
generate_next_challenge(smb_buf(outbuf));
+#endif
Protocol = PROTOCOL_LANMAN1;
if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
DEBUG(3,("using password server validation\n"));
+#ifdef SMB_PASSWD
if (doencrypt) set_challenge(smb_buf(outbuf));
+#endif
}
CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
@@ -3487,9 +2897,11 @@ int reply_lanman2(char *outbuf)
set_message(outbuf,13,doencrypt?8:0,True);
SSVAL(outbuf,smb_vwv1,secword);
+#ifdef SMB_PASSWD
/* Create a token value and add it to the outgoing packet. */
if (doencrypt)
generate_next_challenge(smb_buf(outbuf));
+#endif
SIVAL(outbuf,smb_vwv6,getpid());
@@ -3497,7 +2909,9 @@ int reply_lanman2(char *outbuf)
if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
DEBUG(3,("using password server validation\n"));
+#ifdef SMB_PASSWD
if (doencrypt) set_challenge(smb_buf(outbuf));
+#endif
}
CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
@@ -3567,6 +2981,7 @@ int reply_nt1(char *outbuf)
#endif
CVAL(outbuf,smb_vwv1) = secword;
+#ifdef SMB_PASSWD
/* Create a token value and add it to the outgoing packet. */
if (doencrypt)
{
@@ -3575,12 +2990,15 @@ int reply_nt1(char *outbuf)
/* Tell the nt machine how long the challenge is. */
SSVALS(outbuf,smb_vwv16+1,challenge_len);
}
+#endif
Protocol = PROTOCOL_NT1;
if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
DEBUG(3,("using password server validation\n"));
+#ifdef SMB_PASSWD
if (doencrypt) set_challenge(smb_buf(outbuf));
+#endif
}
SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
@@ -3791,7 +3209,7 @@ static void close_open_files(int cnum)
int i;
for (i=0;i<MAX_OPEN_FILES;i++)
if( Files[i].cnum == cnum && Files[i].open) {
- close_file(i);
+ close_file(i, 0);
}
}
@@ -3804,6 +3222,10 @@ void close_cnum(int cnum, uint16 vuid)
{
DirCacheFlush(SNUM(cnum));
+ close_open_files(cnum);
+ dptr_closecnum(cnum);
+
+ /* after this we are running as root, so be careful! */
unbecome_user();
if (!OPEN_CNUM(cnum))
@@ -3824,9 +3246,6 @@ void close_cnum(int cnum, uint16 vuid)
if (lp_status(SNUM(cnum)))
yield_connection(cnum,"STATUS.",MAXSTATUS);
- close_open_files(cnum);
- dptr_closecnum(cnum);
-
/* execute any "postexec = " line */
if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
{
@@ -4556,11 +3975,14 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
return(outsize);
}
+
/****************************************************************************
process commands from the client
****************************************************************************/
static void process(void)
{
+ static int trans_num = 0;
+ int nread;
extern int Client;
InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
@@ -4583,36 +4005,32 @@ static void process(void)
#endif
while (True)
- {
- int deadtime = lp_deadtime()*60;
- int counter;
- int last_keepalive=0;
- int service_load_counter = 0;
-#ifdef USE_OPLOCKS
- BOOL got_smb = False;
-#endif /* USE_OPLOCKS */
-
- if (deadtime <= 0)
- deadtime = DEFAULT_SMBD_TIMEOUT;
-
- if (lp_readprediction())
- do_read_prediction();
-
- errno = 0;
-
- for (counter=SMBD_SELECT_LOOP;
-#ifdef USE_OPLOCKS
- !receive_message_or_smb(Client,oplock_sock,
- InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
-#else /* USE_OPLOCKS */
- !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000);
-#endif /* USE_OPLOCKS */
- counter += SMBD_SELECT_LOOP)
{
- int i;
- time_t t;
- BOOL allidle = True;
- extern int keepalive;
+ int32 len;
+ int msg_type;
+ int msg_flags;
+ int type;
+ int deadtime = lp_deadtime()*60;
+ int counter;
+ int last_keepalive=0;
+ int service_load_counter = 0;
+
+ if (deadtime <= 0)
+ deadtime = DEFAULT_SMBD_TIMEOUT;
+
+ if (lp_readprediction())
+ do_read_prediction();
+
+ errno = 0;
+
+ for (counter=SMBD_SELECT_LOOP;
+ !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000);
+ counter += SMBD_SELECT_LOOP)
+ {
+ int i;
+ time_t t;
+ BOOL allidle = True;
+ extern int keepalive;
if (counter > 365 * 3600) /* big number of seconds. */
{
@@ -4620,84 +4038,126 @@ static void process(void)
service_load_counter = 0;
}
- if (smb_read_error == READ_EOF)
- {
- DEBUG(3,("end of file from client\n"));
- return;
- }
+ if (smb_read_error == READ_EOF) {
+ DEBUG(3,("end of file from client\n"));
+ return;
+ }
- if (smb_read_error == READ_ERROR)
- {
- DEBUG(3,("receive_smb error (%s) exiting\n",
- strerror(errno)));
- return;
- }
+ if (smb_read_error == READ_ERROR) {
+ DEBUG(3,("receive_smb error (%s) exiting\n",
+ strerror(errno)));
+ return;
+ }
- t = time(NULL);
+ t = time(NULL);
- /* become root again if waiting */
- unbecome_user();
+ /* become root again if waiting */
+ unbecome_user();
- /* check for smb.conf reload */
- if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
+ /* check for smb.conf reload */
+ if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
{
service_load_counter = counter;
/* reload services, if files have changed. */
- reload_services(True);
+ reload_services(True);
}
- /* automatic timeout if all connections are closed */
- if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
- {
- DEBUG(2,("%s Closing idle connection\n",timestring()));
- return;
- }
+ /* automatic timeout if all connections are closed */
+ if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) {
+ DEBUG(2,("%s Closing idle connection\n",timestring()));
+ return;
+ }
- if (keepalive && (counter-last_keepalive)>keepalive)
- {
- extern int password_client;
- if (!send_keepalive(Client))
- {
- DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
- return;
- }
- /* also send a keepalive to the password server if its still
- connected */
- if (password_client != -1)
- send_keepalive(password_client);
- last_keepalive = counter;
+ if (keepalive && (counter-last_keepalive)>keepalive) {
+ extern int password_client;
+ if (!send_keepalive(Client)) {
+ DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
+ return;
+ }
+ /* also send a keepalive to the password server if its still
+ connected */
+ if (password_client != -1)
+ send_keepalive(password_client);
+ last_keepalive = counter;
+ }
+
+ /* check for connection timeouts */
+ for (i=0;i<MAX_CONNECTIONS;i++)
+ if (Connections[i].open)
+ {
+ /* close dirptrs on connections that are idle */
+ if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
+ dptr_idlecnum(i);
+
+ if (Connections[i].num_files_open > 0 ||
+ (t-Connections[i].lastused)<deadtime)
+ allidle = False;
+ }
+
+ if (allidle && num_connections_open>0) {
+ DEBUG(2,("%s Closing idle connection 2\n",timestring()));
+ return;
+ }
+ }
+
+ if (trans_num == 0) {
+ /* on the first packet, check the global hosts allow/ hosts
+ deny parameters before doing any parsing of the packet
+ passed to us by the client. This prevents attacks on our
+ parsing code from hosts not in the hosts allow list */
+ if (!check_access(-1)) {
+ /* send a negative session response "not listining
+ on calling name" */
+ static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
+ DEBUG(1,("%s Connection denied from %s\n",
+ timestring(),client_addr()));
+ send_smb(Client,(char *)buf);
+ exit_server("connection denied");
+ }
}
- /* check for connection timeouts */
- for (i=0;i<MAX_CONNECTIONS;i++)
- if (Connections[i].open)
- {
- /* close dirptrs on connections that are idle */
- if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
- dptr_idlecnum(i);
- if (Connections[i].num_files_open > 0 ||
- (t-Connections[i].lastused)<deadtime)
- allidle = False;
- }
+ msg_type = CVAL(InBuffer,0);
+ msg_flags = CVAL(InBuffer,1);
+ type = CVAL(InBuffer,smb_com);
- if (allidle && num_connections_open>0)
- {
- DEBUG(2,("%s Closing idle connection 2\n",timestring()));
+ len = smb_len(InBuffer);
+
+ DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
+
+ nread = len + 4;
+
+ DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
+
+#ifdef WITH_VTP
+ if(trans_num == 1 && VT_Check(InBuffer)) {
+ VT_Process();
return;
}
- }
+#endif
-#ifdef USE_OPLOCKS
- if(got_smb)
-#endif /* USE_OPLOCKS */
- process_smb(InBuffer, OutBuffer);
-#ifdef USE_OPLOCKS
- else
- process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
-#endif /* USE_OPLOCKS */
- }
+
+ if (msg_type == 0)
+ show_msg(InBuffer);
+
+ nread = construct_reply(InBuffer,OutBuffer,nread,max_send);
+
+ if(nread > 0) {
+ if (CVAL(OutBuffer,0) == 0)
+ show_msg(OutBuffer);
+
+ if (nread != smb_len(OutBuffer) + 4)
+ {
+ DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
+ nread,
+ smb_len(OutBuffer)));
+ }
+ else
+ send_smb(Client,OutBuffer);
+ }
+ trans_num++;
+ }
}
@@ -4976,12 +4436,6 @@ static void usage(char *pname)
DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
}
-#ifdef USE_OPLOCKS
- /* Setup the oplock IPC socket. */
- if(!open_oplock_ipc())
- exit(1);
-#endif /* USE_OPLOCKS */
-
process();
close_sockets();
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 7f46604cce9..f7351b99e5a 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -166,7 +166,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
char *params = *pparams;
int16 open_mode = SVAL(params, 2);
int16 open_attr = SVAL(params,6);
- BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
+ BOOL oplock_request = BITSETW(params,1);
#if 0
BOOL return_additional_info = BITSETW(params,0);
int16 open_sattr = SVAL(params, 4);
@@ -213,7 +213,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
open_file_shared(fnum,cnum,fname,open_mode,open_ofun,unixmode,
- oplock_request, &rmode,&smb_action);
+ &rmode,&smb_action);
if (!Files[fnum].open)
{
@@ -226,7 +226,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
}
if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
- close_file(fnum);
+ close_file(fnum, 0);
return(ERROR(ERRDOS,ERRnoaccess));
}
@@ -235,7 +235,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
mtime = sbuf.st_mtime;
inode = sbuf.st_ino;
if (fmode & aDIR) {
- close_file(fnum);
+ close_file(fnum, 0);
return(ERROR(ERRDOS,ERRnoaccess));
}
@@ -252,7 +252,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
SSVAL(params,12,rmode);
if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
- smb_action |= EXTENDED_OPLOCK_GRANTED;
+ smb_action |= (1<<15);
}
SSVAL(params,18,smb_action);
@@ -319,7 +319,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l
reskey = TellDir(Connections[cnum].dirptr);
- DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
+ DEBUG(6,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr)));
if (!dname)
@@ -607,15 +607,6 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
-
- /* Ugly - NT specific hack - but needed (JRA) */
- if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
- (get_remote_arch() == RA_WINNT))
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbaddirectory;
- }
-
return(ERROR(ERRDOS,ERRbadpath));
}
@@ -650,14 +641,6 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
-
- /* Ugly - NT specific hack - but needed (JRA) */
- if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
- (get_remote_arch() == RA_WINNT))
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbaddirectory;
- }
return (UNIXERROR(ERRDOS,ERRbadpath));
}
return(ERROR(ERRDOS,ERRbadpath));
@@ -1364,14 +1347,6 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length,
tvs.modtime=MAX(interpret_long_date(pdata+16),
interpret_long_date(pdata+24));
-#if 0 /* Needs more testing... */
- /* Test from Luke to prevent Win95 from
- setting incorrect values here.
- */
- if (tvs.actime < tvs.modtime)
- return(ERROR(ERRDOS,ERRnoaccess));
-#endif /* Needs more testing... */
-
/* attributes */
mode = IVAL(pdata,32);
break;
diff --git a/source/smbd/uid.c b/source/smbd/uid.c
index cdc4e474c61..fe2cb5a652d 100644
--- a/source/smbd/uid.c
+++ b/source/smbd/uid.c
@@ -258,6 +258,8 @@ BOOL become_user(int cnum, uint16 vuid)
if (current_user.ngroups > 0)
if (setgroups(current_user.ngroups,current_user.groups)<0)
DEBUG(0,("setgroups call failed!\n"));
+ } else {
+ current_user.ngroups = 0;
}
#endif
@@ -318,7 +320,8 @@ BOOL unbecome_user(void )
current_user.uid = initial_uid;
current_user.gid = initial_gid;
-
+ current_user.ngroups = 0;
+
if (ChDir(OriginalDir) != 0)
DEBUG(0,("%s chdir(%s) failed in unbecome_user\n",
timestring(),OriginalDir));
@@ -476,3 +479,82 @@ int smbrun(char *cmd,char *outfile,BOOL shared)
#endif
return 1;
}
+
+
+
+static struct current_user current_user_saved;
+static int become_root_depth;
+static pstring become_root_dir;
+
+/****************************************************************************
+This is used when we need to do a privilaged operation (such as mucking
+with share mode files) and temporarily need root access to do it. This
+call should always be paired with an unbecome_root() call immediately
+after the operation
+
+Set save_dir if you also need to save/restore the CWD
+****************************************************************************/
+void become_root(int save_dir)
+{
+ if (become_root_depth) {
+ DEBUG(0,("ERROR: become root depth is non zero\n"));
+ }
+ if (save_dir)
+ GetWd(become_root_dir);
+
+ current_user_saved = current_user;
+ become_root_depth = 1;
+
+ become_gid(0);
+ become_uid(0);
+}
+
+/****************************************************************************
+When the privilaged operation is over call this
+
+Set save_dir if you also need to save/restore the CWD
+****************************************************************************/
+void unbecome_root(int restore_dir)
+{
+ if (become_root_depth != 1) {
+ DEBUG(0,("ERROR: unbecome root depth is %d\n",
+ become_root_depth));
+ }
+
+ /* we might have done a become_user() while running as root,
+ if we have then become root again in order to become
+ non root! */
+ if (current_user.uid != 0) {
+ become_uid(0);
+ }
+
+ /* restore our gid first */
+ if (!become_gid(current_user_saved.gid)) {
+ DEBUG(0,("ERROR: Failed to restore gid\n"));
+ exit_server("Failed to restore gid");
+ }
+
+#ifndef NO_SETGROUPS
+ if (current_user_saved.ngroups > 0) {
+ if (setgroups(current_user_saved.ngroups,
+ current_user_saved.groups)<0)
+ DEBUG(0,("ERROR: setgroups call failed!\n"));
+ }
+#endif
+
+ /* now restore our uid */
+ if (!become_uid(current_user_saved.uid)) {
+ DEBUG(0,("ERROR: Failed to restore uid\n"));
+ exit_server("Failed to restore uid");
+ }
+
+ if (restore_dir)
+ ChDir(become_root_dir);
+
+ current_user = current_user_saved;
+
+ become_root_depth = 0;
+}
+
+
+