first cut at using the tdb code for the connections structure, the
authorAndrew Tridgell <tridge@samba.org>
Tue, 21 Dec 1999 04:54:30 +0000 (04:54 +0000)
committerAndrew Tridgell <tridge@samba.org>
Tue, 21 Dec 1999 04:54:30 +0000 (04:54 +0000)
SWAT status page and smbstatus. It made the code _much_ simpler, I
wish we'd done a database module a long time ago!

source/include/proto.h
source/include/smb.h
source/script/mkproto.awk
source/smbd/connection.c
source/smbd/reply.c
source/smbd/service.c
source/tdb/README
source/tdb/tdb.c
source/tdb/tdb.h
source/utils/status.c
source/web/statuspage.c

index c933a93222a91ea51b5d1dc9ea8907b45676c4f4..125ef3a27c8f851fa03f9bd359863c90233da230 100644 (file)
@@ -2375,7 +2375,9 @@ void conn_free(connection_struct *conn);
 
 /*The following definitions come from  smbd/connection.c  */
 
+TDB_CONTEXT *open_db(char *name);
 BOOL yield_connection(connection_struct *conn,char *name,int max_connections);
+int delete_dead(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf);
 BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOOL Clear);
 
 /*The following definitions come from  smbd/dfree.c  */
@@ -2796,10 +2798,14 @@ int smbw_stat(const char *fname, struct stat *st);
 /*The following definitions come from  tdb/tdb.c  */
 
 int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf);
+TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key);
 int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key);
 int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf));
+TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb);
+TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key);
 int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key);
 int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
+TDB_CONTEXT *tdb_open(char *name, int hash_size, int flags, mode_t mode);
 int tdb_close(TDB_CONTEXT *tdb);
 int tdb_writelock(TDB_CONTEXT *tdb);
 int tdb_writeunlock(TDB_CONTEXT *tdb);
index d3d64a2edf0848374e946680a3a1e442818403fe..6c3d7488c32e57c16db1cb4cf540a7ea2885e40b 100644 (file)
@@ -839,19 +839,23 @@ struct passdb_ops {
 #endif
 };
 
-/* this is used for smbstatus */
+/* key and data in the connections database - used in smbstatus and smbd */
+struct connections_key {
+       pid_t pid;
+       int cnum;
+       fstring name;
+};
 
-struct connect_record
-{
-  int magic;
-  pid_t pid;
-  int cnum;
-  uid_t uid;
-  gid_t gid;
-  char name[24];
-  char addr[24];
-  char machine[128];
-  time_t start;
+struct connections_data {
+       int magic;
+       pid_t pid;
+       int cnum;
+       uid_t uid;
+       gid_t gid;
+       char name[24];
+       char addr[24];
+       char machine[128];
+       time_t start;
 };
 
 /* the following are used by loadparm for option lists */
index 923624c3a261aaef060427864d4cf12b3e651322..fd0cbcd2f8fa0a457d47d040be988b753ff24c5d 100644 (file)
@@ -98,6 +98,10 @@ END {
     gotstart = 1;
   }
 
+  if( $0 ~ /^TDB_CONTEXT|^TDB_DATA/ ) {
+    gotstart = 1;
+  }
+
   if( $0 ~ /^long|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^FILE|^SMB_OFF_T|^size_t|^ssize_t|^SMB_BIG_UINT/ ) {
     gotstart = 1;
   }
index 393a3e7372ffe8fe6cc663cd45830e2824aaa844..f88d7079830e37c1c9b3b70d60d0a041913bbbd6 100644 (file)
@@ -27,202 +27,117 @@ extern fstring remote_machine;
 extern int DEBUGLEVEL;
 
 /****************************************************************************
-simple routines to do connection counting
+open the connections database
 ****************************************************************************/
-BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
+TDB_CONTEXT *open_db(char *name)
 {
-       struct connect_record crec;
        pstring fname;
-       int fd;
-       pid_t mypid = getpid();
-       int i;
-
-       DEBUG(3,("Yielding connection to %s\n",name));
-
-       if (max_connections <= 0)
-               return(True);
-
-       memset((char *)&crec,'\0',sizeof(crec));
 
        pstrcpy(fname,lp_lockdir());
        trim_string(fname,"","/");
-
-       pstrcat(fname,"/");
-       pstrcat(fname,name);
-       pstrcat(fname,".LCK");
-
-       fd = sys_open(fname,O_RDWR,0);
-       if (fd == -1) {
-               DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
-               return(False);
+       
+       if (!directory_exist(fname,NULL)) {
+               mkdir(fname,0755);
        }
+       
+       pstrcat(fname,"/connections.tdb");
+       
+       return tdb_open(fname, 0, O_RDWR | O_CREAT, 0644);
+}
 
-       if (fcntl_lock(fd,SMB_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,SMB_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 == conn->cnum)
-                       break;
-       }
 
-       if (crec.pid != mypid || crec.cnum != conn->cnum) {
-               if (fcntl_lock(fd,SMB_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);
-       }
+/****************************************************************************
+delete a connection record
+****************************************************************************/
+BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
+{
+       struct connections_key key;
+       TDB_DATA kbuf;
+       TDB_CONTEXT *tdb;
 
-       memset((void *)&crec,'\0',sizeof(crec));
-  
-       /* remove our mark */
-       if (sys_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,SMB_F_SETLKW,0,1,F_UNLCK)==False) {
-                       DEBUG(0,("ERROR: can't release lock on %s\n", fname));
-               }
-               close(fd);
-               return(False);
-       }
+       if (!(tdb = open_db(name))) return False;
 
-       if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_UNLCK)==False) {
-               DEBUG(0,("ERROR: can't release lock on %s\n", fname));
-       }
+       DEBUG(3,("Yielding connection to %s\n",name));
 
-       DEBUG(3,("Yield successful\n"));
+       ZERO_STRUCT(key);
+       key.pid = getpid();
+       if (conn) key.cnum = conn->cnum;
+       fstrcpy(key.name, name);
 
-       close(fd);
+       kbuf.dptr = (char *)&key;
+       kbuf.dsize = sizeof(key);
+
+       tdb_delete(tdb, kbuf);
+       tdb_close(tdb);
        return(True);
 }
 
 
 /****************************************************************************
-simple routines to do connection counting
+claim an entry in the connections database
+****************************************************************************/
+int delete_dead(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
+{
+       struct connections_key key;
+       memcpy(&key, kbuf.dptr, sizeof(key));
+       if (!process_exists(key.pid)) tdb_delete(tdb, kbuf);
+       return 0;
+}
+
+
+/****************************************************************************
+claim an entry in the connections database
 ****************************************************************************/
 BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOOL Clear)
 {
+       struct connections_key key;
+       struct connections_data crec;
+       TDB_DATA kbuf, dbuf;
+       TDB_CONTEXT *tdb;
        extern int Client;
-       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);
-       
-       pstrcat(fname,"/");
-       pstrcat(fname,name);
-       pstrcat(fname,".LCK");
-       
-       if (!file_exist(fname,NULL)) {
-               fd = sys_open(fname,O_RDWR|O_CREAT|O_EXCL, 0644);
-       }
+       if (!(tdb = open_db(name))) return False;
 
-       if (fd == -1) {
-               fd = sys_open(fname,O_RDWR,0);
-       }
-       
-       if (fd == -1) {
-               DEBUG(1,("couldn't open lock file %s\n",fname));
-               return(False);
-       }
+       DEBUG(5,("claiming %s %d\n",name,max_connections));
+
+       ZERO_STRUCT(key);
+       key.pid = getpid();
+       key.cnum = conn?conn->cnum:-1;
+       fstrcpy(key.name, name);
+
+       kbuf.dptr = (char *)&key;
+       kbuf.dsize = sizeof(key);
 
-       if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_WRLCK)==False) {
-               DEBUG(0,("ERROR: can't get lock on %s\n", fname));
-               return False;
+       if (Clear) {
+               tdb_traverse(tdb, delete_dead);
        }
 
-       total_recs = get_file_size(fname) / sizeof(crec);
-                       
-       /* find a free spot */
-       for (i=0;i<max_connections;i++) {
-               if (i>=total_recs || 
-                   sys_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)) {
-                       if(sys_lseek(fd,i*sizeof(crec),SEEK_SET) != i*sizeof(crec)) {
-              DEBUG(0,("claim_connection: ERROR: sys_lseek failed to seek \
-to %d\n", (int)(i*sizeof(crec)) ));
-              continue;
-            }
-                       memset((void *)&crec,'\0',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,SMB_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 */
-       memset((void *)&crec,'\0',sizeof(crec));
+       ZERO_STRUCT(crec);
        crec.magic = 0x280267;
        crec.pid = getpid();
+       crec.cnum = conn?conn->cnum:-1;
        if (conn) {
-               crec.cnum = conn->cnum;
                crec.uid = conn->uid;
                crec.gid = conn->gid;
                StrnCpy(crec.name,
                        lp_servicename(SNUM(conn)),sizeof(crec.name)-1);
-       } else {
-               crec.cnum = -1;
        }
        crec.start = time(NULL);
        
        StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
-       StrnCpy(crec.addr,client_addr(Client),sizeof(crec.addr)-1);
-       
-       /* make our mark */
-       if (sys_lseek(fd,foundi*sizeof(crec),SEEK_SET) != foundi*sizeof(crec) ||
-           write(fd, &crec,sizeof(crec)) != sizeof(crec)) {
-               if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_UNLCK)==False) {
-                       DEBUG(0,("ERROR: can't release lock on %s\n", fname));
-               }
-               close(fd);
-               return(False);
-       }
+       StrnCpy(crec.addr,conn?conn->client_address:client_addr(Client),sizeof(crec.addr)-1);
 
-       if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_UNLCK)==False) {
-               DEBUG(0,("ERROR: can't release lock on %s\n", fname));
-       }
-       
-       close(fd);
-       return(True);
+       dbuf.dptr = (char *)&crec;
+       dbuf.dsize = sizeof(crec);
+
+       if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) return False;
+
+       tdb_close(tdb);
+
+       return True;
 }
index 54f646e09113a518408d8aab2fc07836446acf9f..aa7e95294daf29b12b26791cb1353dd7cec12131 100644 (file)
@@ -123,7 +123,7 @@ int reply_special(char *inbuf,char *outbuf)
                reopen_logs();
 
                if (lp_status(-1)) {
-                       claim_connection(NULL,"STATUS.",MAXSTATUS,True);
+                       claim_connection(NULL,"",MAXSTATUS,True);
                }
 
                break;
index 92807e2d43902bf13328a5a46103e8e7012730b0..ec723e13b9066923c60721e97dce90debb1c3e84 100644 (file)
@@ -458,7 +458,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
                }  
                
                if (lp_status(SNUM(conn)))
-                       claim_connection(conn,"STATUS.",
+                       claim_connection(conn,"",
                                         MAXSTATUS,False);
        } /* IS_IPC */
        
@@ -484,7 +484,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
                                         lp_servicename(SNUM(conn)),
                                         lp_max_connections(SNUM(conn)));
                        if (lp_status(SNUM(conn))) {
-                               yield_connection(conn,"STATUS.",MAXSTATUS);
+                               yield_connection(conn,"",MAXSTATUS);
                        }
                }
                conn_free(conn);
@@ -501,7 +501,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
                                         lp_servicename(SNUM(conn)),
                                         lp_max_connections(SNUM(conn)));
                        if (lp_status(SNUM(conn))) 
-                               yield_connection(conn,"STATUS.",MAXSTATUS);
+                               yield_connection(conn,"",MAXSTATUS);
                }
                conn_free(conn);
                *ecode = ERRinvnetname;
@@ -582,7 +582,7 @@ void close_cnum(connection_struct *conn, uint16 vuid)
                         lp_max_connections(SNUM(conn)));
 
        if (lp_status(SNUM(conn)))
-               yield_connection(conn,"STATUS.",MAXSTATUS);
+               yield_connection(conn,"",MAXSTATUS);
 
        file_close_conn(conn);
        dptr_closecnum(conn);
index fc99a68acced10ed6100d142cd790ff43ece30dc..3c0059c5cb7ddb1383a2e0c642a4b37e48c77ed2 100644 (file)
@@ -11,7 +11,7 @@ Compilation
 -----------
 
 add HAVE_MMAP=1 to use mmap instead of read/write
-add TDB_DEBUG for verbose debug info
+add TDB_DEBUG=1 for verbose debug info
 add NOLOCK=1 to disable locking code
 
 Testing
@@ -21,6 +21,12 @@ Compile tdbtest.c and link with gdbm for testing. tdbtest will perform
 identical operations via tdb and gdbm then make sure the result is the
 same
 
+Also included is tdbtool, which allows simple database manipulation
+on the commandline.
+
+tdbtest and tdbtool are not built as part of Samba, but are included
+for completeness.
+
 Interface
 ---------
 
@@ -31,3 +37,4 @@ The interface is very similar to gdbm except for the following:
 - no tdbm_reorganise() function
 - no tdbm_sync() function. No operations are cached in the library anyway
 - added a tdb_traverse() function for traversing the whole database
+
index dacecf95726e461a9bd2104e7f592c70d256c4a5..01d2e740f7f6547cc9837794077f49d8bdbcef25 100644 (file)
@@ -102,10 +102,39 @@ static tdb_off tdb_hash_top(TDB_CONTEXT *tdb, unsigned hash)
        return ret;
 }
 
+
+/* check for an out of bounds access - if it is out of bounds then
+   see if the database has been expanded by someone else and expand
+   if necessary */
+static int tdb_oob(TDB_CONTEXT *tdb, tdb_off offset)
+{
+       struct stat st;
+       if (offset < tdb->map_size) return 0;
+
+       fstat(tdb->fd, &st);
+       if (st.st_size <= tdb->map_size) return -1;
+
+#if HAVE_MMAP
+       if (tdb->map_ptr) {
+               munmap(tdb->map_ptr, tdb->map_size);
+               tdb->map_ptr = NULL;
+       }
+#endif
+
+       tdb->map_size = st.st_size;
+#if HAVE_MMAP
+       tdb->map_ptr = (void *)mmap(NULL, tdb->map_size, 
+                                   tdb->read_only?PROT_READ:PROT_READ|PROT_WRITE,
+                                   MAP_SHARED | MAP_FILE, tdb->fd, 0);
+#endif 
+       return 0;
+}
+
+
 /* write a lump of data at a specified offset */
 static int tdb_write(TDB_CONTEXT *tdb, tdb_off offset, char *buf, tdb_len len)
 {
-       if (offset + len > tdb->map_size) {
+       if (tdb_oob(tdb, offset + len) != 0) {
                /* oops - trying to write beyond the end of the database! */
 #if TDB_DEBUG
                printf("write error of length %u at offset %u (max %u)\n",
@@ -128,7 +157,7 @@ static int tdb_write(TDB_CONTEXT *tdb, tdb_off offset, char *buf, tdb_len len)
 /* read a lump of data at a specified offset */
 static int tdb_read(TDB_CONTEXT *tdb, tdb_off offset, char *buf, tdb_len len)
 {
-       if (offset + len > tdb->map_size) {
+       if (tdb_oob(tdb, offset + len) != 0) {
                /* oops - trying to read beyond the end of the database! */
 #if TDB_DEBUG
                printf("read error of length %u at offset %u (max %u)\n",
@@ -514,6 +543,7 @@ int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key)
 
 /* traverse the entire database - calling fn(tdb, key, data) on each element.
    return -1 on error or the record count traversed
+   if fn is NULL then it is not called
    a non-zero return value from fn() indicates that the traversal should stop
   */
 int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf))
@@ -552,7 +582,7 @@ int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB
                        dbuf.dsize = rec.data_len;
                        count++;
 
-                       if (fn(tdb, key, dbuf) != 0) {
+                       if (fn && fn(tdb, key, dbuf) != 0) {
                                /* they want us to stop traversing */
                                free(data);
                                return count;
@@ -915,9 +945,10 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int flags, mode_t mode)
        /* map the database and fill in the return structure */
        tdb.name = (char *)strdup(name);
        tdb.map_size = st.st_size;
+       tdb.read_only = ((flags & O_ACCMODE) == O_RDONLY);
 #if HAVE_MMAP
        tdb.map_ptr = (void *)mmap(NULL, st.st_size, 
-                                 (flags & O_ACCMODE) == O_RDONLY? PROT_READ : PROT_READ|PROT_WRITE,
+                                 tdb.read_only? PROT_READ : PROT_READ|PROT_WRITE,
                                  MAP_SHARED | MAP_FILE, tdb.fd, 0);
 #endif
        tdb.header = header;
index 316338606b00fca474e9b985d00f3e0409cc07e9..111b804f71e2ed272dce2508757b678c20a9d2ea 100644 (file)
@@ -39,6 +39,7 @@ typedef struct {
        void *map_ptr; /* where it is currently mapped */
        int fd; /* open file descriptor for the database */
        tdb_len map_size; /* how much space has been mapped */
+       int read_only; /* opened read-only */
        int write_locked; /* set if we have the db locked */
        struct tdb_header header; /* a cached copy of the header */
 } TDB_CONTEXT;
index 2cbfbfdaf5b25b2cf1ac87a0989382bb9752ab1c..594783bd39ecbaed890d45c0ad449c71ccc0e445 100644 (file)
@@ -36,8 +36,6 @@
 
 #include "includes.h"
 
-struct connect_record crec;
-
 struct session_record{
   pid_t pid;
   uid_t uid;
@@ -50,12 +48,13 @@ extern int DEBUGLEVEL;
 extern FILE *dbf;
 
 static pstring Ucrit_username = "";                   /* added by OH */
-pid_t  Ucrit_pid[100];  /* Ugly !!! */        /* added by OH */
-int            Ucrit_MaxPid=0;                        /* added by OH */
-unsigned int   Ucrit_IsActive = 0;                    /* added by OH */
-
-int            shares_only = 0;            /* Added by RJS */
-int            locks_only  = 0;            /* Added by RJS */
+static pid_t   Ucrit_pid[100];  /* Ugly !!! */        /* added by OH */
+static int            Ucrit_MaxPid=0;                        /* added by OH */
+static unsigned int   Ucrit_IsActive = 0;                    /* added by OH */
+static int verbose, brief;
+static int            shares_only = 0;            /* Added by RJS */
+static int            locks_only  = 0;            /* Added by RJS */
+static BOOL processes_only=False;
 
 /* we need these because we link to locking*.o */
  void become_root(BOOL save_dir) {}
@@ -161,197 +160,198 @@ static int profile_dump(void)
 }
 
 
+static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
+{
+       static pid_t last_pid;
+       struct session_record *ptr;
+       struct connections_data crec;
+       static int doneone;
+
+       memcpy(&crec, dbuf.dptr, sizeof(crec));
+
+       if (crec.cnum == -1) return 0;
+
+       if (!process_exists(crec.pid) || !Ucrit_checkUsername(uidtoname(crec.uid))) {
+               return 0;
+       }
+
+       if (brief) {
+               if (!doneone) {
+                       printf("\nSamba version %s\n",VERSION);
+                       printf("PID     Username  Machine                       Time logged in\n");
+                       printf("-------------------------------------------------------------------\n");
+                       doneone = 1;
+               }
+
+               ptr=srecs;
+               while (ptr!=NULL) {
+                       if ((ptr->pid==crec.pid)&&(strncmp(ptr->machine,crec.machine,30)==0)) {
+                               if (ptr->start > crec.start)
+                                       ptr->start=crec.start;
+                               break;
+                       }
+                       ptr=ptr->next;
+               }
+               if (ptr==NULL) {
+                       ptr=(struct session_record *) malloc(sizeof(struct session_record));
+                       ptr->uid=crec.uid;
+                       ptr->pid=crec.pid;
+                       ptr->start=crec.start;
+                       strncpy(ptr->machine,crec.machine,30);
+                       ptr->machine[30]='\0';
+                       ptr->next=srecs;
+                       srecs=ptr;
+               }
+       } else {
+               if (!doneone) {
+                       printf("\nSamba version %s\n",VERSION);
+                       printf("Service      uid      gid      pid     machine\n");
+                       printf("----------------------------------------------\n");
+                       doneone = 1;
+               }
+
+               Ucrit_addPid(crec.pid);  
+               if (processes_only) {
+                       if (last_pid != crec.pid)
+                               printf("%d\n",(int)crec.pid);
+                       last_pid = crec.pid; /* XXXX we can still get repeats, have to
+                                               add a sort at some time */
+               } else {
+                       printf("%-10.10s   %-8s %-8s %5d   %-8s (%s) %s",
+                              crec.name,uidtoname(crec.uid),gidtoname(crec.gid),(int)crec.pid,
+                              crec.machine,crec.addr,
+                              asctime(LocalTime(&crec.start)));
+               }
+       }
+
+       return 0;
+}
+
+
+
 
  int main(int argc, char *argv[])
 {
-  FILE *f;
-  pstring fname;
-  int c;
-  static pstring servicesf = CONFIGFILE;
-  extern char *optarg;
-  int verbose = 0, brief =0;
-  BOOL processes_only=False;
-  pid_t last_pid=(pid_t)0;
-  struct session_record *ptr;
-  int profile_only = 0;
-
-  TimeInit();
-  setup_logging(argv[0],True);
-
-  charset_initialise();
-
-  DEBUGLEVEL = 0;
-  dbf = stderr;
-
-  if (getuid() != geteuid()) {
-    printf("smbstatus should not be run setuid\n");
-    return(1);
-  }
-
-  while ((c = getopt(argc, argv, "pdLSs:u:bP")) != EOF) {
-    switch (c) {
-    case 'b':
-      brief = 1;
-      break;
-    case 'd':
-      verbose = 1;
-      break;
-    case 'L':
-      locks_only = 1;
-      break;
-    case 'p':
-      processes_only = 1;
-      break;
-    case 'P':
-      profile_only = 1;
-      break;
-    case 'S':
-      shares_only = 1;
-      break;
-    case 's':
-      pstrcpy(servicesf, optarg);
-      break;
-    case 'u':                                       /* added by OH */
-      Ucrit_addUsername(optarg);                    /* added by OH */
-      break;
-    default:
-      fprintf(stderr, "Usage: %s [-P] [-d] [-L] [-p] [-S] [-s configfile] [-u username]\n", *argv); /* changed by OH */
-      return (-1);
-    }
-  }
-
-  if (!lp_load(servicesf,False,False,False)) {
-    fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
-    return (-1);
-  }
-
-  if (verbose) {
-    printf("using configfile = %s\n", servicesf);
-    printf("lockdir = %s\n", *lp_lockdir() ? lp_lockdir() : "NULL");
-  }
-
-  if (profile_only) {
-       return profile_dump();
-  }
-
-  pstrcpy(fname,lp_lockdir());
-  standard_sub_basic(fname);
-  trim_string(fname,"","/");
-  pstrcat(fname,"/STATUS..LCK");
-
-  f = sys_fopen(fname,"r");
-  if (!f) {
-    printf("Couldn't open status file %s\n",fname);
-    if (!lp_status(-1))
-      printf("You need to have status=yes in your smb config file\n");
-    return(0);
-  }
-  else if (verbose) {
-    printf("Opened status file %s\n", fname);
-  }
-
-  if (!locks_only) {
-
-    if (!processes_only) {
-      printf("\nSamba version %s\n",VERSION);
-
-      if (brief)
-       {
-         printf("PID     Username  Machine                       Time logged in\n");
-         printf("-------------------------------------------------------------------\n");
-       }
-      else
-       {
-         printf("Service      uid      gid      pid     machine\n");
-         printf("----------------------------------------------\n");
+       pstring fname;
+       int c;
+       static pstring servicesf = CONFIGFILE;
+       extern char *optarg;
+       int profile_only = 0;
+       TDB_CONTEXT *tdb;
+       struct session_record *ptr;
+
+       TimeInit();
+       setup_logging(argv[0],True);
+       
+       charset_initialise();
+       
+       DEBUGLEVEL = 0;
+       dbf = stderr;
+       
+       if (getuid() != geteuid()) {
+               printf("smbstatus should not be run setuid\n");
+               return(1);
        }
-    }
-
-    while (!feof(f))
-      {
-       if (fread(&crec,sizeof(crec),1,f) != 1)
-         break;
-       if (crec.cnum == -1) continue;
-       if ( crec.magic == 0x280267 && process_exists(crec.pid) 
-            && Ucrit_checkUsername(uidtoname(crec.uid))                      /* added by OH */
-            )
-         {
-           if (brief)
-             {
-               ptr=srecs;
-               while (ptr!=NULL)
-                 {
-                   if ((ptr->pid==crec.pid)&&(strncmp(ptr->machine,crec.machine,30)==0)) 
-                     {
-                       if (ptr->start > crec.start)
-                         ptr->start=crec.start;
+       
+       while ((c = getopt(argc, argv, "pdLSs:u:bP")) != EOF) {
+               switch (c) {
+               case 'b':
+                       brief = 1;
                        break;
-                     }
-                   ptr=ptr->next;
-                 }
-               if (ptr==NULL)
-                 {
-                   ptr=(struct session_record *) malloc(sizeof(struct session_record));
-                   ptr->uid=crec.uid;
-                   ptr->pid=crec.pid;
-                   ptr->start=crec.start;
-                   strncpy(ptr->machine,crec.machine,30);
-                   ptr->machine[30]='\0';
-                   ptr->next=srecs;
-                   srecs=ptr;
-                 }
-             }
-           else
-             {
-               Ucrit_addPid(crec.pid);                                             /* added by OH */
-               if (processes_only) {
-                 if (last_pid != crec.pid)
-                   printf("%d\n",(int)crec.pid);
-                 last_pid = crec.pid; /* XXXX we can still get repeats, have to
-                                   add a sort at some time */
+               case 'd':
+                       verbose = 1;
+                       break;
+               case 'L':
+                       locks_only = 1;
+                       break;
+               case 'p':
+                       processes_only = 1;
+                       break;
+               case 'P':
+                       profile_only = 1;
+                       break;
+               case 'S':
+                       shares_only = 1;
+                       break;
+               case 's':
+                       pstrcpy(servicesf, optarg);
+                       break;
+               case 'u':                                       /* added by OH */
+                       Ucrit_addUsername(optarg);                    /* added by OH */
+                       break;
+               default:
+                       fprintf(stderr, "Usage: %s [-P] [-d] [-L] [-p] [-S] [-s configfile] [-u username]\n", *argv); /* changed by OH */
+                       return (-1);
                }
-               else      
-                 printf("%-10.10s   %-8s %-8s %5d   %-8s (%s) %s",
-                        crec.name,uidtoname(crec.uid),gidtoname(crec.gid),(int)crec.pid,
-                        crec.machine,crec.addr,
-                        asctime(LocalTime(&crec.start)));
-             }
-         }
-      }
-    fclose(f);
-  }
-  if (processes_only) exit(0);
+       }
+       
+       if (!lp_load(servicesf,False,False,False)) {
+               fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
+               return (-1);
+       }
+       
+       if (verbose) {
+               printf("using configfile = %s\n", servicesf);
+               printf("lockdir = %s\n", *lp_lockdir() ? lp_lockdir() : "NULL");
+       }
+       
+       if (profile_only) {
+               return profile_dump();
+       }
+       
+       pstrcpy(fname,lp_lockdir());
+       standard_sub_basic(fname);
+       trim_string(fname,"","/");
+       pstrcat(fname,"/connections.tdb");
+
+       tdb = tdb_open(fname, 0, O_RDONLY, 0);
+       if (!tdb) {
+               printf("Couldn't open status file %s\n",fname);
+               if (!lp_status(-1))
+                       printf("You need to have status=yes in your smb config file\n");
+               return(0);
+       }  else if (verbose) {
+               printf("Opened status file %s\n", fname);
+       }
+
+       if (locks_only) goto locks;
+
+       tdb_traverse(tdb, traverse_fn1);
+
+ locks:
+       if (processes_only) exit(0);
   
-  if (brief)
-  {
-    ptr=srecs;
-    while (ptr!=NULL)
-    {
-      printf("%-8d%-10.10s%-30.30s%s",(int)ptr->pid,uidtoname(ptr->uid),ptr->machine,asctime(LocalTime(&(ptr->start))));
-    ptr=ptr->next;
-    }
-    printf("\n");
-    exit(0);
-  }
-
-  printf("\n");
-
-  if (!shares_only) {
-         if (!locking_init(1)) {
-                 printf("Can't initialise shared memory - exiting\n");
-                 exit(1);
-         }
+       if (brief)  {
+               ptr=srecs;
+               while (ptr!=NULL) {
+                       printf("%-8d%-10.10s%-30.30s%s",
+                              (int)ptr->pid,uidtoname(ptr->uid),
+                              ptr->machine,
+                              asctime(LocalTime(&(ptr->start))));
+                       ptr=ptr->next;
+               }
+               printf("\n");
+               exit(0);
+       }
+
+       printf("\n");
+
+       if (!shares_only) {
+               if (!locking_init(1)) {
+                       printf("Can't initialise shared memory - exiting\n");
+                       exit(1);
+               }
+               
+               if (share_mode_forall(print_share_mode) <= 0)
+                       printf("No locked files\n");
+               
+               printf("\n");
+               
+               share_status(stdout);
+               
+               locking_end();
+       }
 
-         if (share_mode_forall(print_share_mode) <= 0)
-                 printf("No locked files\n");
-         
-         printf("\n");
-         
-         share_status(stdout);
-         
-         locking_end();
-  }
-
-  return (0);
+       return (0);
 }
 
index 304a122e2304d3a2c8febbe87e9f409513160600..8b7108c0b509a52b8ddc9b475c2d155015f24cf7 100644 (file)
@@ -71,15 +71,68 @@ static void print_share_mode(share_mode_entry *e, char *fname)
 }
 
 
+/* kill off any connections chosen by the user */
+static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
+{
+       struct connections_data crec;
+       memcpy(&crec, dbuf.dptr, sizeof(crec));
+
+       if (crec.cnum == -1 && process_exists(crec.pid)) {
+               char buf[30];
+               slprintf(buf,sizeof(buf)-1,"kill_%d", (int)crec.pid);
+               if (cgi_variable(buf)) {
+                       kill_pid(crec.pid);
+               }
+       }
+       return 0;
+}
+
+/* traversal fn for showing machine connections */
+static int traverse_fn2(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
+{
+       struct connections_data crec;
+       memcpy(&crec, dbuf.dptr, sizeof(crec));
+       
+       if (crec.cnum != -1 || !process_exists(crec.pid)) return 0;
+
+       printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td>\n",
+              (int)crec.pid,
+              crec.machine,crec.addr,
+              tstring(crec.start));
+       if (geteuid() == 0) {
+               printf("<td><input type=submit value=\"X\" name=\"kill_%d\"></td>\n",
+                      (int)crec.pid);
+       }
+       printf("</tr>\n");
+
+       return 0;
+}
+
+/* traversal fn for showing share connections */
+static int traverse_fn3(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
+{
+       struct connections_data crec;
+       memcpy(&crec, dbuf.dptr, sizeof(crec));
+
+       if (crec.cnum != -1 || !process_exists(crec.pid)) return 0;
+
+       printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td></tr>\n",
+              crec.name,uidtoname(crec.uid),
+              gidtoname(crec.gid),(int)crec.pid,
+              crec.machine,
+              tstring(crec.start));
+       return 0;
+}
+
+
 /* show the current server status */
 void status_page(void)
 {
-       struct connect_record crec;
        pstring fname;
-       FILE *f;
        char *v;
        int autorefresh=0;
        int refresh_interval=30;
+       TDB_CONTEXT *tdb;
 
        if (cgi_variable("smbd_restart")) {
                if (smbd_running())
@@ -123,24 +176,10 @@ void status_page(void)
        pstrcpy(fname,lp_lockdir());
        standard_sub_basic(fname);
        trim_string(fname,"","/");
-       pstrcat(fname,"/STATUS..LCK");
-
-
-       f = sys_fopen(fname,"r");
-       if (f) {
-               while (!feof(f)) {
-                       if (fread(&crec,sizeof(crec),1,f) != 1) break;
-                       if (crec.magic == 0x280267 && crec.cnum == -1 &&
-                           process_exists(crec.pid)) {
-                               char buf[30];
-                               slprintf(buf,sizeof(buf)-1,"kill_%d", (int)crec.pid);
-                               if (cgi_variable(buf)) {
-                                       kill_pid(crec.pid);
-                               }
-                       }
-               }
-               fclose(f);
-       }
+       pstrcat(fname,"/connections.tdb");
+
+       tdb = tdb_open(fname, 0, O_RDONLY, 0);
+       if (tdb) tdb_traverse(tdb, traverse_fn1);
 
        printf("<H2>Server Status</H2>\n");
 
@@ -159,8 +198,7 @@ void status_page(void)
 
        printf("<p>\n");
 
-       f = sys_fopen(fname,"r");
-       if (!f) {
+       if (!tdb) {
                /* open failure either means no connections have been
                    made or status=no */
                if (!lp_status(-1))
@@ -207,44 +245,15 @@ void status_page(void)
        }
        printf("</tr>\n");
 
-       while (f && !feof(f)) {
-               if (fread(&crec,sizeof(crec),1,f) != 1)
-                       break;
-               if (crec.magic == 0x280267 && 
-                   crec.cnum == -1 &&
-                   process_exists(crec.pid)) {
-                       printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td>\n",
-                              (int)crec.pid,
-                              crec.machine,crec.addr,
-                              tstring(crec.start));
-                       if (geteuid() == 0) {
-                           printf("<td><input type=submit value=\"X\" name=\"kill_%d\"></td>\n",
-                              (int)crec.pid);
-                       }
-                       printf("</tr>\n");
-               }
-       }
+       if (tdb) tdb_traverse(tdb, traverse_fn2);
 
        printf("</table><p>\n");
 
-       if (f) fseek(f, 0, SEEK_SET);
-       
        printf("<p><h3>Active Shares</h3>\n");
        printf("<table border=1>\n");
        printf("<tr><th>Share</th><th>User</th><th>Group</th><th>PID</th><th>Client</th><th>Date</th></tr>\n\n");
 
-       while (f && !feof(f)) {
-               if (fread(&crec,sizeof(crec),1,f) != 1)
-                       break;
-               if (crec.cnum == -1) continue;
-               if (crec.magic == 0x280267 && process_exists(crec.pid)) {
-                       printf("<tr><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td></tr>\n",
-                              crec.name,uidtoname(crec.uid),
-                              gidtoname(crec.gid),(int)crec.pid,
-                              crec.machine,
-                              tstring(crec.start));
-               }
-       }
+       if (tdb) tdb_traverse(tdb, traverse_fn3);
 
        printf("</table><p>\n");
 
@@ -257,7 +266,7 @@ void status_page(void)
        locking_end();
        printf("</table>\n");
 
-       if (f) fclose(f);
+       tdb_close(tdb);
 
        printf("</FORM>\n");