diff options
author | Andrew Tridgell <tridge@samba.org> | 1996-08-20 15:45:16 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 1996-08-20 15:45:16 +0000 |
commit | 748d65a4ac898708dc7d2fd6f2bdee41489fee86 (patch) | |
tree | b54a4d77d71beba6e6422c366ecb17f57c172614 /source3/smbd | |
parent | 7f38abfbdb57b4ed33fa0aaacdfe7414d4c19a28 (diff) | |
download | samba-748d65a4ac898708dc7d2fd6f2bdee41489fee86.tar.gz samba-748d65a4ac898708dc7d2fd6f2bdee41489fee86.tar.bz2 samba-748d65a4ac898708dc7d2fd6f2bdee41489fee86.zip |
- fix a bug in NetServerEnum where counted and total were not counted
correctly if there were multiple instances of a name. This led to the
infamous "not enough memory" error when browsing (but this isn't the
only cause of that message)
- fix a triple-chaining bug which affected OpenX following a TconX
- fix a serious nmbd bug that meant nmdb would answer packets that it
wasn't supposed to, causing havoc with browse lists.
- never time out SELF packets. This is an interim fix until I find out
why nmbd thought they should be timed out.
(This used to be commit 2960c3908c2c3b01a1f2b77def60350018d298e1)
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/ipc.c | 14 | ||||
-rw-r--r-- | source3/smbd/reply.c | 45 | ||||
-rw-r--r-- | source3/smbd/server.c | 45 |
3 files changed, 57 insertions, 47 deletions
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 78a9807769..9da7c993dd 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -963,7 +963,7 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data, int f_len, s_len; struct srv_info_struct *servers=NULL; int counted=0,total=0; - int i; + int i,missed; fstring domain; BOOL domain_request; BOOL local_request = servertype & SV_TYPE_LOCAL_LIST_ONLY; @@ -991,6 +991,7 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data, total = get_server_info(servertype,&servers,domain); data_len = fixed_len = string_len = 0; + missed = 0; qsort(servers,total,sizeof(servers[0]),QSORT_CAST srv_comp); @@ -1006,12 +1007,13 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data, DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n", s->name, s->type, s->comment, s->domain)); - if (data_len <= buf_len) - { + if (data_len <= buf_len) { counted++; fixed_len += f_len; string_len += s_len; - } + } else { + missed++; + } } } @@ -1044,12 +1046,12 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data, SSVAL(*rparam,0,NERR_Success); SSVAL(*rparam,2,0); SSVAL(*rparam,4,counted); - SSVAL(*rparam,6,total); + SSVAL(*rparam,6,counted+missed); if (servers) free(servers); DEBUG(3,("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n", - domain,uLevel,counted,total)); + domain,uLevel,counted,counted+missed)); return(True); } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index a84a9af0c1..7241aadac0 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -130,6 +130,44 @@ static int connection_error(char *inbuf,char *outbuf,int connection_num) } + +/**************************************************************************** + parse a share descriptor string +****************************************************************************/ +static void parse_connect(char *p,char *service,char *user, + char *password,int *pwlen,char *dev) +{ + char *p2; + + DEBUG(4,("parsing connect string %s\n",p)); + + p2 = strrchr(p,'\\'); + if (p2 == NULL) + strcpy(service,p); + else + strcpy(service,p2+1); + + p += strlen(p) + 2; + + strcpy(password,p); + *pwlen = strlen(password); + + p += strlen(p) + 2; + + strcpy(dev,p); + + *user = 0; + p = strchr(service,'%'); + if (p != NULL) + { + *p = 0; + strcpy(user,p+1); + } +} + + + + /**************************************************************************** reply to a tcon ****************************************************************************/ @@ -149,7 +187,7 @@ int reply_tcon(char *inbuf,char *outbuf) vuid = valid_uid(uid); - parse_connect(inbuf,service,user,password,&pwlen,dev); + parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev); connection_num = make_connection(service,user,password,pwlen,dev,vuid); @@ -1210,6 +1248,11 @@ int reply_unlink(char *inbuf,char *outbuf) if (check_name(directory,cnum)) dirptr = OpenDir(directory); + /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then + the pattern matches against the long name, otherwise the short name + We don't implement this yet XXXX + */ + if (dirptr) { error = ERRbadfile; diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 1fb6358794..683d63e7aa 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -2564,41 +2564,6 @@ static int reply_negprot(char *inbuf,char *outbuf) /**************************************************************************** - parse a connect packet -****************************************************************************/ -void parse_connect(char *buf,char *service,char *user,char *password,int *pwlen,char *dev) -{ - char *p = smb_buf(buf) + 1; - char *p2; - - DEBUG(4,("parsing connect string %s\n",p)); - - p2 = strrchr(p,'\\'); - if (p2 == NULL) - strcpy(service,p); - else - strcpy(service,p2+1); - - p += strlen(p) + 2; - - strcpy(password,p); - *pwlen = strlen(password); - - p += strlen(p) + 2; - - strcpy(dev,p); - - *user = 0; - p = strchr(service,'%'); - if (p != NULL) - { - *p = 0; - strcpy(user,p+1); - } -} - - -/**************************************************************************** close all open files for a connection ****************************************************************************/ static void close_open_files(int cnum) @@ -3261,14 +3226,14 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize) outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct; /* remember the original command type */ - smb_com1 = CVAL(orig_outbuf,smb_com); + smb_com1 = CVAL(orig_inbuf,smb_com); /* save the data which will be overwritten by the new headers */ memcpy(inbuf_saved,inbuf2,smb_wct); memcpy(outbuf_saved,outbuf2,smb_wct); - /* give the new packet the same header as the first part of the SMB */ - memmove(inbuf2,orig_inbuf,smb_wct); + /* give the new packet the same header as the last part of the SMB */ + memmove(inbuf2,inbuf,smb_wct); /* create the in buffer */ CVAL(inbuf2,smb_com) = smb_com2; @@ -3297,8 +3262,8 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize) outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size, bufsize-chain_size); - /* copy the new reply header over the old one, but preserve - the smb_com field */ + /* copy the new reply and request headers over the old ones, but + preserve the smb_com field */ memmove(orig_outbuf,outbuf2,smb_wct); CVAL(orig_outbuf,smb_com) = smb_com1; |