summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1998-03-15 02:37:52 +0000
committerAndrew Tridgell <tridge@samba.org>1998-03-15 02:37:52 +0000
commitd360320618fe3a7f53ac1f05ee3ac54323a03c82 (patch)
tree97120a8949d82c8e9aab435bb56f6f0301beed28 /source3/smbd
parent69bb6f6f5fa472d2bf5c619a09aecc3b0ce4c254 (diff)
downloadsamba-d360320618fe3a7f53ac1f05ee3ac54323a03c82.tar.gz
samba-d360320618fe3a7f53ac1f05ee3ac54323a03c82.tar.bz2
samba-d360320618fe3a7f53ac1f05ee3ac54323a03c82.zip
- added the ability to kill off individual connections from SWAT (from
the status page) - split the claim_connection() code into its own file - fixed the claim_connection() code to lock the file when manipulating it - always claim a null connection at startup - fixed a bug in the pidfile code (This used to be commit abd4a17e21d12be3d1747e94ceb1915abaf135e3)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/connection.c221
-rw-r--r--source3/smbd/server.c186
2 files changed, 226 insertions, 181 deletions
diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c
new file mode 100644
index 0000000000..610afbc3e5
--- /dev/null
+++ b/source3/smbd/connection.c
@@ -0,0 +1,221 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ connection claim routines
+ Copyright (C) Andrew Tridgell 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+extern connection_struct Connections[MAX_CONNECTIONS];
+extern fstring remote_machine;
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+simple routines to do connection counting
+****************************************************************************/
+BOOL yield_connection(int cnum,char *name,int max_connections)
+{
+ struct connect_record crec;
+ pstring fname;
+ int fd;
+ int mypid = getpid();
+ int i;
+
+ DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
+
+ if (max_connections <= 0)
+ return(True);
+
+ bzero(&crec,sizeof(crec));
+
+ pstrcpy(fname,lp_lockdir());
+ trim_string(fname,"","/");
+
+ strcat(fname,"/");
+ strcat(fname,name);
+ strcat(fname,".LCK");
+
+ fd = open(fname,O_RDWR);
+ if (fd == -1) {
+ DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
+ return(False);
+ }
+
+ if (fcntl_lock(fd,F_SETLKW,0,1,F_WRLCK)==False) {
+ DEBUG(0,("ERROR: can't get lock on %s\n", fname));
+ return False;
+ }
+
+ /* find the right spot */
+ for (i=0;i<max_connections;i++) {
+ if (read(fd, &crec,sizeof(crec)) != sizeof(crec)) {
+ DEBUG(2,("Entry not found in lock file %s\n",fname));
+ if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
+ DEBUG(0,("ERROR: can't release lock on %s\n", fname));
+ }
+ close(fd);
+ return(False);
+ }
+ if (crec.pid == mypid && crec.cnum == cnum)
+ break;
+ }
+
+ if (crec.pid != mypid || crec.cnum != cnum) {
+ if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
+ DEBUG(0,("ERROR: can't release lock on %s\n", fname));
+ }
+ close(fd);
+ DEBUG(2,("Entry not found in lock file %s\n",fname));
+ return(False);
+ }
+
+ bzero((void *)&crec,sizeof(crec));
+
+ /* remove our mark */
+ if (lseek(fd,i*sizeof(crec),SEEK_SET) != i*sizeof(crec) ||
+ write(fd, &crec,sizeof(crec)) != sizeof(crec)) {
+ DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
+ if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
+ DEBUG(0,("ERROR: can't release lock on %s\n", fname));
+ }
+ close(fd);
+ return(False);
+ }
+
+ if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
+ DEBUG(0,("ERROR: can't release lock on %s\n", fname));
+ }
+
+ DEBUG(3,("Yield successful\n"));
+
+ close(fd);
+ return(True);
+}
+
+
+/****************************************************************************
+simple routines to do connection counting
+****************************************************************************/
+BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
+{
+ struct connect_record crec;
+ pstring fname;
+ int fd=-1;
+ int i,foundi= -1;
+ int total_recs;
+
+ if (max_connections <= 0)
+ return(True);
+
+ DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
+
+ pstrcpy(fname,lp_lockdir());
+ trim_string(fname,"","/");
+
+ if (!directory_exist(fname,NULL))
+ mkdir(fname,0755);
+
+ strcat(fname,"/");
+ strcat(fname,name);
+ strcat(fname,".LCK");
+
+ if (!file_exist(fname,NULL)) {
+ fd = open(fname,O_RDWR|O_CREAT|O_EXCL, 0644);
+ }
+
+ if (fd == -1) {
+ fd = open(fname,O_RDWR);
+ }
+
+ if (fd == -1) {
+ DEBUG(1,("couldn't open lock file %s\n",fname));
+ return(False);
+ }
+
+ if (fcntl_lock(fd,F_SETLKW,0,1,F_WRLCK)==False) {
+ DEBUG(0,("ERROR: can't get lock on %s\n", fname));
+ return False;
+ }
+
+ total_recs = file_size(fname) / sizeof(crec);
+
+ /* find a free spot */
+ for (i=0;i<max_connections;i++) {
+ if (i>=total_recs ||
+ lseek(fd,i*sizeof(crec),SEEK_SET) != i*sizeof(crec) ||
+ read(fd,&crec,sizeof(crec)) != sizeof(crec)) {
+ if (foundi < 0) foundi = i;
+ break;
+ }
+
+ if (Clear && crec.pid && !process_exists(crec.pid)) {
+ lseek(fd,i*sizeof(crec),SEEK_SET);
+ bzero((void *)&crec,sizeof(crec));
+ write(fd, &crec,sizeof(crec));
+ if (foundi < 0) foundi = i;
+ continue;
+ }
+ if (foundi < 0 && (!crec.pid || !process_exists(crec.pid))) {
+ foundi=i;
+ if (!Clear) break;
+ }
+ }
+
+ if (foundi < 0) {
+ DEBUG(3,("no free locks in %s\n",fname));
+ if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
+ DEBUG(0,("ERROR: can't release lock on %s\n", fname));
+ }
+ close(fd);
+ return(False);
+ }
+
+ /* fill in the crec */
+ bzero((void *)&crec,sizeof(crec));
+ crec.magic = 0x280267;
+ crec.pid = getpid();
+ crec.cnum = cnum;
+ if (cnum != -1) {
+ crec.uid = Connections[cnum].uid;
+ crec.gid = Connections[cnum].gid;
+ StrnCpy(crec.name,lp_servicename(SNUM(cnum)),sizeof(crec.name)-1);
+ }
+ crec.start = time(NULL);
+
+ StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
+ StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
+
+ /* make our mark */
+ if (lseek(fd,foundi*sizeof(crec),SEEK_SET) != foundi*sizeof(crec) ||
+ write(fd, &crec,sizeof(crec)) != sizeof(crec)) {
+ if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
+ DEBUG(0,("ERROR: can't release lock on %s\n", fname));
+ }
+ close(fd);
+ return(False);
+ }
+
+ if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
+ DEBUG(0,("ERROR: can't release lock on %s\n", fname));
+ }
+
+ close(fd);
+ return(True);
+}
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index ca4a95f59d..64b293336b 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -3312,7 +3312,6 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
connection_struct *pcon;
BOOL guest = False;
BOOL force = False;
- static BOOL first_connection = True;
strlower(service);
@@ -3518,9 +3517,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
}
if (lp_status(SNUM(cnum)))
- claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
-
- first_connection = False;
+ claim_connection(cnum,"STATUS.",MAXSTATUS,False);
} /* IS_IPC */
pcon->open = True;
@@ -4213,183 +4210,6 @@ void close_cnum(int cnum, uint16 vuid)
}
-/****************************************************************************
-simple routines to do connection counting
-****************************************************************************/
-BOOL yield_connection(int cnum,char *name,int max_connections)
-{
- struct connect_record crec;
- pstring fname;
- FILE *f;
- int mypid = getpid();
- int i;
-
- DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
-
- if (max_connections <= 0)
- return(True);
-
- bzero(&crec,sizeof(crec));
-
- pstrcpy(fname,lp_lockdir());
- standard_sub(cnum,fname);
- trim_string(fname,"","/");
-
- strcat(fname,"/");
- strcat(fname,name);
- strcat(fname,".LCK");
-
- f = fopen(fname,"r+");
- if (!f)
- {
- DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
- return(False);
- }
-
- fseek(f,0,SEEK_SET);
-
- /* find a free spot */
- for (i=0;i<max_connections;i++)
- {
- if (fread(&crec,sizeof(crec),1,f) != 1)
- {
- DEBUG(2,("Entry not found in lock file %s\n",fname));
- fclose(f);
- return(False);
- }
- if (crec.pid == mypid && crec.cnum == cnum)
- break;
- }
-
- if (crec.pid != mypid || crec.cnum != cnum)
- {
- fclose(f);
- DEBUG(2,("Entry not found in lock file %s\n",fname));
- return(False);
- }
-
- bzero((void *)&crec,sizeof(crec));
-
- /* remove our mark */
- if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
- fwrite(&crec,sizeof(crec),1,f) != 1)
- {
- DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
- fclose(f);
- return(False);
- }
-
- DEBUG(3,("Yield successful\n"));
-
- fclose(f);
- return(True);
-}
-
-
-/****************************************************************************
-simple routines to do connection counting
-****************************************************************************/
-BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
-{
- struct connect_record crec;
- pstring fname;
- FILE *f;
- int snum = SNUM(cnum);
- int i,foundi= -1;
- int total_recs;
-
- if (max_connections <= 0)
- return(True);
-
- DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
-
- pstrcpy(fname,lp_lockdir());
- standard_sub(cnum,fname);
- trim_string(fname,"","/");
-
- if (!directory_exist(fname,NULL))
- mkdir(fname,0755);
-
- strcat(fname,"/");
- strcat(fname,name);
- strcat(fname,".LCK");
-
- if (!file_exist(fname,NULL))
- {
- int oldmask = umask(022);
- f = fopen(fname,"w");
- if (f) fclose(f);
- umask(oldmask);
- }
-
- total_recs = file_size(fname) / sizeof(crec);
-
- f = fopen(fname,"r+");
-
- if (!f)
- {
- DEBUG(1,("couldn't open lock file %s\n",fname));
- return(False);
- }
-
- /* find a free spot */
- for (i=0;i<max_connections;i++)
- {
-
- if (i>=total_recs ||
- fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
- fread(&crec,sizeof(crec),1,f) != 1)
- {
- if (foundi < 0) foundi = i;
- break;
- }
-
- if (Clear && crec.pid && !process_exists(crec.pid))
- {
- fseek(f,i*sizeof(crec),SEEK_SET);
- bzero((void *)&crec,sizeof(crec));
- fwrite(&crec,sizeof(crec),1,f);
- if (foundi < 0) foundi = i;
- continue;
- }
- if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
- {
- foundi=i;
- if (!Clear) break;
- }
- }
-
- if (foundi < 0)
- {
- DEBUG(3,("no free locks in %s\n",fname));
- fclose(f);
- return(False);
- }
-
- /* fill in the crec */
- bzero((void *)&crec,sizeof(crec));
- crec.magic = 0x280267;
- crec.pid = getpid();
- crec.cnum = cnum;
- crec.uid = Connections[cnum].uid;
- crec.gid = Connections[cnum].gid;
- StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
- crec.start = time(NULL);
-
- StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
- StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
-
- /* make our mark */
- if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
- fwrite(&crec,sizeof(crec),1,f) != 1)
- {
- fclose(f);
- return(False);
- }
-
- fclose(f);
- return(True);
-}
#if DUMP_CORE
/*******************************************************************
@@ -5347,6 +5167,10 @@ static void usage(char *pname)
if(!open_oplock_ipc())
exit(1);
+ if (lp_status(-1)) {
+ claim_connection(-1,"STATUS.",MAXSTATUS,True);
+ }
+
process();
close_sockets();