home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 July & August / Pcwk78a98.iso / Wtestowe / Clico / UNIX / SAMBA / SOURCE / SAMBA.TAR / samba-1.9.17 / source / status.c < prev    next >
C/C++ Source or Header  |  1997-07-18  |  13KB  |  513 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    status reporting
  5.    Copyright (C) Andrew Tridgell 1994-1997
  6.    
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.    
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.    Revision History:
  22.  
  23.    12 aug 96: Erik.Devriendt@te6.siemens.be
  24.    added support for shared memory implementation of share mode locking
  25. */
  26.  
  27. /*
  28.  * This program reports current SMB connections
  29.  */
  30.  
  31. #ifdef SYSLOG
  32. #undef SYSLOG
  33. #endif
  34.  
  35. #include "includes.h"
  36.  
  37. struct connect_record crec;
  38.  
  39. struct session_record{
  40.   int pid;
  41.   int uid;
  42.   char machine[31];
  43.   time_t start;
  44.   struct session_record *next;
  45. } *srecs;
  46.  
  47. extern int DEBUGLEVEL;
  48. extern FILE *dbf;
  49. extern pstring myhostname;
  50.  
  51. static pstring Ucrit_username = "";                   /* added by OH */
  52. int            Ucrit_pid[100];  /* Ugly !!! */        /* added by OH */
  53. int            Ucrit_MaxPid=0;                        /* added by OH */
  54. unsigned int   Ucrit_IsActive = 0;                    /* added by OH */
  55.  
  56. #ifndef FAST_SHARE_MODES
  57. static char *read_share_file(int fd, char *fname, char *progname)
  58. {
  59.   struct stat sb;
  60.   char *buf;
  61.   int size;
  62.  
  63.   if(fstat(fd, &sb) != 0)
  64.   {
  65.     printf("%s: ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
  66.                   progname, fname, strerror(errno));
  67.     return 0;
  68.   }
  69.  
  70.   if(sb.st_size == 0)
  71.   {
  72.      return 0;
  73.   }
  74.  
  75.   /* Allocate space for the file */
  76.   if((buf = (char *)malloc(sb.st_size)) == NULL)
  77.   {
  78.     printf("%s: read_share_file: malloc for file size %d fail !\n", 
  79.               progname, (int)sb.st_size);
  80.     return 0;
  81.   }
  82.  
  83.   if(lseek(fd, 0, SEEK_SET) != 0)
  84.   {
  85.     printf("%s: ERROR: read_share_file: Failed to reset position to 0 \
  86. for share file %s (%s)\n", progname, fname, strerror(errno));
  87.     if(buf)
  88.       free(buf);
  89.     return 0;
  90.   }
  91.  
  92.   if (read(fd,buf,sb.st_size) != sb.st_size)
  93.   {
  94.     printf("%s: ERROR: read_share_file: Failed to read share file %s (%s)\n",
  95.                progname, fname, strerror(errno));
  96.     if(buf)
  97.       free(buf);
  98.     return 0;
  99.   }
  100.  
  101.   if (IVAL(buf,0) != LOCKING_VERSION) {
  102.     printf("%s: ERROR: read_share_file: share file %s has incorrect \
  103. locking version (was %d, should be %d).\n",fname, 
  104.               progname, IVAL(buf,0), LOCKING_VERSION);
  105.     if(buf)
  106.       free(buf);
  107.     return 0;
  108.   }
  109.  
  110.   /* Sanity check for file contents */
  111.   size = sb.st_size;
  112.   size -= 10; /* Remove the header */
  113.  
  114.   /* Remove the filename component. */
  115.   size -= SVAL(buf, 8);
  116.  
  117.   /* The remaining size must be a multiple of 16 - error if not. */
  118.   if((size % 16) != 0)
  119.   {
  120.     printf("%s: ERROR: read_share_file: share file %s is an incorrect length.\n", 
  121.              progname, fname);
  122.     if(buf)
  123.       free(buf);
  124.     return 0;
  125.   }
  126.  
  127.   return buf;
  128. }
  129. #endif /* FAST_SHARE_MODES */
  130.  
  131.  int main(int argc, char *argv[])
  132. {
  133.   FILE *f;
  134.   pstring fname;
  135.   int uid, c;
  136.   static pstring servicesf = CONFIGFILE;
  137.   extern char *optarg;
  138.   int verbose = 0, brief =0;
  139.   BOOL firstopen=True;
  140.   BOOL processes_only=False;
  141.   int last_pid=0;
  142. #ifdef FAST_SHARE_MODES
  143.   pstring shmem_file_name;
  144.   share_mode_record *file_scanner_p;
  145.   smb_shm_offset_t *mode_array;
  146.   int bytes_free, bytes_used, bytes_overhead, bytes_total;
  147. #else /* FAST_SHARE_MODES */
  148.   void *dir;
  149.   char *s;
  150. #endif /* FAST_SHARE_MODES */
  151.   int i;
  152.   struct session_record *ptr;
  153.  
  154.  
  155.   TimeInit();
  156.   setup_logging(argv[0],True);
  157.  
  158.   charset_initialise();
  159.  
  160.   DEBUGLEVEL = 0;
  161.   dbf = fopen("/dev/null","w");
  162.  
  163.   if (getuid() != geteuid()) {
  164.     printf("smbstatus should not be run setuid\n");
  165.     return(1);
  166.   }
  167.  
  168.   while ((c = getopt(argc, argv, "pds:u:b")) != EOF) {
  169.     switch (c) {
  170.     case 'b':
  171.       brief = 1;
  172.       break;
  173.     case 'd':
  174.       verbose = 1;
  175.       break;
  176.     case 'p':
  177.       processes_only = 1;
  178.       break;
  179.     case 's':
  180.       strcpy(servicesf, optarg);
  181.       break;
  182.     case 'u':                                       /* added by OH */
  183.       Ucrit_addUsername(optarg);                    /* added by OH */
  184.       break;
  185.     default:
  186.       fprintf(stderr, "Usage: %s [-d] [-p] [-s configfile] [-u username]\n", *argv); /* changed by OH */
  187.       return (-1);
  188.     }
  189.   }
  190.  
  191.   if (!lp_load(servicesf,False)) {
  192.     fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
  193.     return (-1);
  194.   }
  195.  
  196.   get_myname(myhostname, NULL);
  197.  
  198.   if (verbose) {
  199.     printf("using configfile = %s\n", servicesf);
  200.     printf("lockdir = %s\n", *lp_lockdir() ? lp_lockdir() : "NULL");
  201.   }
  202.  
  203.   strcpy(fname,lp_lockdir());
  204.   standard_sub_basic(fname);
  205.   trim_string(fname,"","/");
  206.   strcat(fname,"/STATUS..LCK");
  207.  
  208.   f = fopen(fname,"r");
  209.   if (!f) {
  210.     printf("Couldn't open status file %s\n",fname);
  211.     if (!lp_status(-1))
  212.       printf("You need to have status=yes in your smb config file\n");
  213.     return(0);
  214.   }
  215.   else if (verbose) {
  216.     printf("Opened status file %s\n", fname);
  217.   }
  218.  
  219.   uid = getuid();
  220.  
  221.   if (!processes_only) {
  222.     printf("\nSamba version %s\n",VERSION);
  223.  
  224.     if (brief)
  225.     {
  226.       printf("PID     Username  Machine                       Time logged in\n");
  227.       printf("-------------------------------------------------------------------\n");
  228.     }
  229.     else
  230.     {
  231.       printf("Service      uid      gid      pid     machine\n");
  232.       printf("----------------------------------------------\n");
  233.     }
  234.   }
  235.  
  236.   while (!feof(f))
  237.     {
  238.       if (fread(&crec,sizeof(crec),1,f) != 1)
  239.     break;
  240.       if ( crec.magic == 0x280267 && process_exists(crec.pid) 
  241.            && Ucrit_checkUsername(uidtoname(crec.uid))                      /* added by OH */
  242.          )
  243.       {
  244.         if (brief)
  245.         {
  246.       ptr=srecs;
  247.       while (ptr!=NULL)
  248.       {
  249.         if ((ptr->pid==crec.pid)&&(strncmp(ptr->machine,crec.machine,30)==0)) 
  250.         {
  251.           if (ptr->start > crec.start)
  252.         ptr->start=crec.start;
  253.           break;
  254.         }
  255.         ptr=ptr->next;
  256.       }
  257.       if (ptr==NULL)
  258.       {
  259.         ptr=(struct session_record *) malloc(sizeof(struct session_record));
  260.         ptr->uid=crec.uid;
  261.         ptr->pid=crec.pid;
  262.         ptr->start=crec.start;
  263.         strncpy(ptr->machine,crec.machine,30);
  264.         ptr->machine[30]='\0';
  265.         ptr->next=srecs;
  266.         srecs=ptr;
  267.       }
  268.         }
  269.         else
  270.         {
  271.       Ucrit_addPid(crec.pid);                                             /* added by OH */
  272.       if (processes_only) {
  273.         if (last_pid != crec.pid)
  274.           printf("%d\n",crec.pid);
  275.         last_pid = crec.pid; /* XXXX we can still get repeats, have to
  276.                     add a sort at some time */
  277.       }
  278.       else      
  279.         printf("%-10.10s   %-8s %-8s %5d   %-8s (%s) %s",
  280.            crec.name,uidtoname(crec.uid),gidtoname(crec.gid),crec.pid,
  281.            crec.machine,crec.addr,
  282.            asctime(LocalTime(&crec.start)));
  283.         }
  284.       }
  285.     }
  286.   fclose(f);
  287.  
  288.   if (processes_only) exit(0);
  289.   
  290.   if (brief)
  291.   {
  292.     ptr=srecs;
  293.     while (ptr!=NULL)
  294.     {
  295.       printf("%-8d%-10.10s%-30.30s%s",ptr->pid,uidtoname(ptr->uid),ptr->machine,asctime(LocalTime(&(ptr->start))));
  296.     ptr=ptr->next;
  297.     }
  298.     printf("\n");
  299.     exit(0);
  300.   }
  301.  
  302.   printf("\n");
  303.  
  304. #ifdef FAST_SHARE_MODES 
  305.   /*******************************************************************
  306.   initialize the shared memory for share_mode management 
  307.   ******************************************************************/
  308.    
  309.   strcpy(shmem_file_name,lp_lockdir());
  310.   trim_string(shmem_file_name,"","/");
  311.   if (!*shmem_file_name) exit(-1);
  312.   strcat(shmem_file_name, "/SHARE_MEM_FILE");
  313.   if(!smb_shm_open(shmem_file_name, lp_shmem_size())) exit(-1);
  314.   
  315.   mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
  316.   if(mode_array == NULL)
  317.   {
  318.     printf("%s: base of shared memory hash array == 0! Exiting.\n", argv[0]);
  319.     smb_shm_close();
  320.     exit(-1);
  321.   }
  322.  
  323.   for( i = 0; i < lp_shmem_hash_size(); i++)
  324.   {
  325.     smb_shm_lock_hash_entry(i);
  326.     if(mode_array[i] == NULL_OFFSET)
  327.     {
  328.       smb_shm_unlock_hash_entry(i);
  329.       continue;
  330.     }
  331.     file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[i]);
  332.     while((file_scanner_p != 0) && (file_scanner_p->num_share_mode_entries != 0))
  333.     {
  334.       share_mode_entry *entry_scanner_p = 
  335.                  (share_mode_entry *)smb_shm_offset2addr(
  336.                                        file_scanner_p->share_mode_entries);
  337.  
  338.       while(entry_scanner_p != 0)
  339.       {
  340.         struct timeval t;
  341.         int pid = entry_scanner_p->pid;
  342.         int mode = entry_scanner_p->share_mode;
  343.      
  344.         t.tv_sec = entry_scanner_p->time.tv_sec;
  345.         t.tv_usec = entry_scanner_p->time.tv_usec;
  346.         strcpy(fname, file_scanner_p->file_name);
  347. #else /* FAST_SHARE_MODES */
  348.  
  349.      /* For slow share modes go through all the files in
  350.         the share mode directory and read the entries in
  351.         each.
  352.       */
  353.  
  354.      dir = opendir(lp_lockdir());
  355.      if (!dir) 
  356.      {
  357.        printf("%s: Unable to open lock directory %s.\n", argv[0], lp_lockdir());
  358.        return(0);
  359.      }
  360.      while ((s=readdirname(dir))) {
  361.        char *buf;
  362.        char *base;
  363.        int fd;
  364.        pstring lname;
  365.        uint32 dev,inode;
  366.        
  367.        if (sscanf(s,"share.%u.%u",&dev,&inode)!=2) continue;
  368.        
  369.        strcpy(lname,lp_lockdir());
  370.        trim_string(lname,NULL,"/");
  371.        strcat(lname,"/");
  372.        strcat(lname,s);
  373.        
  374.        fd = open(lname,O_RDWR,0);
  375.        if (fd < 0) 
  376.        {
  377.          printf("%s: Unable to open share file %s.\n", argv[0], lname);
  378.          continue;
  379.        }
  380.  
  381.        /* Lock the share mode file while we read it. */
  382.        if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
  383.        {
  384.          printf("%s: Unable to lock open share file %s.\n", argv[0], lname);
  385.          close(fd);
  386.          continue;
  387.        }
  388.  
  389.        if(( buf = read_share_file( fd, lname, argv[0] )) == NULL)
  390.        {
  391.          close(fd);
  392.          continue;
  393.        } 
  394.        strcpy( fname, &buf[10]);
  395.        close(fd);
  396.       
  397.        base = buf + 10 + SVAL(buf,8); 
  398.        for( i = 0; i < IVAL(buf, 4); i++)
  399.        {
  400.          char *p = base + (i*16);
  401.          struct timeval t;
  402.          int pid = IVAL(p,12);
  403.          int mode = IVAL(p,8);
  404.      
  405.          t.tv_sec = IVAL(p,0);
  406.          t.tv_usec = IVAL(p,4);
  407. #endif /* FAST_SHARE_MODES */
  408.  
  409.     fname[sizeof(fname)-1] = 0;
  410.  
  411.     if (firstopen) {
  412.       firstopen=False;
  413.       printf("Locked files:\n");
  414.       printf("Pid    DenyMode   R/W     Name\n");
  415.       printf("------------------------------\n");
  416.     }
  417.  
  418.  
  419.     printf("%-5d  ",pid);
  420.     switch ((mode>>4)&0xF)
  421.       {
  422.       case DENY_NONE: printf("DENY_NONE  "); break;
  423.       case DENY_ALL:  printf("DENY_ALL   "); break;
  424.       case DENY_DOS:  printf("DENY_DOS   "); break;
  425.       case DENY_READ: printf("DENY_READ  "); break;
  426.       case DENY_WRITE:printf("DENY_WRITE "); break;
  427.       }
  428.     switch (mode&0xF) 
  429.       {
  430.       case 0: printf("RDONLY "); break;
  431.       case 1: printf("WRONLY "); break;
  432.       case 2: printf("RDWR   "); break;
  433.       }
  434.     printf(" %s   %s",fname,asctime(LocalTime((time_t *)&t.tv_sec)));
  435.  
  436. #ifdef FAST_SHARE_MODES
  437.  
  438.         entry_scanner_p = (share_mode_entry *)smb_shm_offset2addr(
  439.                                     entry_scanner_p->next_share_mode_entry);
  440.       } /* end while entry_scanner_p */
  441.      file_scanner_p = (share_mode_record *)smb_shm_offset2addr(
  442.                                     file_scanner_p->next_offset);
  443.     } /* end while file_scanner_p */
  444.     smb_shm_unlock_hash_entry(i);
  445.   } /* end for */
  446.  
  447.   smb_shm_get_usage(&bytes_free, &bytes_used, &bytes_overhead);
  448.   bytes_total = bytes_free + bytes_used + bytes_overhead;
  449.  
  450.   /*******************************************************************
  451.   deinitialize the shared memory for share_mode management 
  452.   ******************************************************************/
  453.   smb_shm_close();
  454.  
  455. #else /* FAST_SHARE_MODES */
  456.     } /* end for i */
  457.  
  458.     if(buf)
  459.       free(buf);
  460.     base = 0;
  461.   } /* end while */
  462.   closedir(dir);
  463.  
  464. #endif /* FAST_SHARE_MODES */
  465.   if (firstopen)
  466.     printf("No locked files\n");
  467. #ifdef FAST_SHARE_MODES
  468.   printf("\nShare mode memory usage (bytes):\n");
  469.   printf("   %d(%d%%) free + %d(%d%%) used + %d(%d%%) overhead = %d(100%%) total\n",
  470.      bytes_free, (bytes_free * 100)/bytes_total,
  471.      bytes_used, (bytes_used * 100)/bytes_total,
  472.      bytes_overhead, (bytes_overhead * 100)/bytes_total,
  473.      bytes_total);
  474.   
  475. #endif /* FAST_SHARE_MODES */
  476.  
  477.   return (0);
  478. }
  479.  
  480. /* added by OH */
  481. void Ucrit_addUsername(pstring username)
  482. {
  483.   strcpy(Ucrit_username, username);
  484.   if(strlen(Ucrit_username) > 0)
  485.     Ucrit_IsActive = 1;
  486. }
  487.  
  488. unsigned int Ucrit_checkUsername(pstring username)
  489. {
  490.   if ( !Ucrit_IsActive) return 1;
  491.   if (strcmp(Ucrit_username,username) ==0) return 1;
  492.   return 0;
  493. }
  494.  
  495. void Ucrit_addPid(int pid)
  496. {
  497.   int i;
  498.   if ( !Ucrit_IsActive) return;
  499.   for (i=0;i<Ucrit_MaxPid;i++)
  500.     if( pid == Ucrit_pid[i] ) return;
  501.   Ucrit_pid[Ucrit_MaxPid++] = pid;
  502. }
  503.  
  504. unsigned int   Ucrit_checkPid(int pid)
  505. {
  506.   int i;
  507.   if ( !Ucrit_IsActive) return 1;
  508.   for (i=0;i<Ucrit_MaxPid;i++)
  509.     if( pid == Ucrit_pid[i] ) return 1;
  510.   return 0;
  511. }
  512.  
  513.