2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1994-1997
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.
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.
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.
23 12 aug 96: Erik.Devriendt@te6.siemens.be
24 added support for shared memory implementation of share mode locking
28 * This program reports current SMB connections
37 struct connect_record crec
;
39 struct session_record
{
44 struct session_record
*next
;
47 extern int DEBUGLEVEL
;
49 extern pstring myhostname
;
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 */
56 #ifndef FAST_SHARE_MODES
57 static char *read_share_file(int fd
, char *fname
, char *progname
)
63 if(fstat(fd
, &sb
) != 0)
65 printf("%s: ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
66 progname
, fname
, strerror(errno
));
75 /* Allocate space for the file */
76 if((buf
= (char *)malloc(sb
.st_size
)) == NULL
)
78 printf("%s: read_share_file: malloc for file size %d fail !\n",
79 progname
, (int)sb
.st_size
);
83 if(lseek(fd
, 0, SEEK_SET
) != 0)
85 printf("%s: ERROR: read_share_file: Failed to reset position to 0 \
86 for share file %s (%s)\n", progname
, fname
, strerror(errno
));
92 if (read(fd
,buf
,sb
.st_size
) != sb
.st_size
)
94 printf("%s: ERROR: read_share_file: Failed to read share file %s (%s)\n",
95 progname
, fname
, strerror(errno
));
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
);
110 /* Sanity check for file contents */
112 size
-= 10; /* Remove the header */
114 /* Remove the filename component. */
115 size
-= SVAL(buf
, 8);
117 /* The remaining size must be a multiple of 16 - error if not. */
120 printf("%s: ERROR: read_share_file: share file %s is an incorrect length.\n",
129 #endif /* FAST_SHARE_MODES */
131 int main(int argc
, char *argv
[])
136 static pstring servicesf
= CONFIGFILE
;
138 int verbose
= 0, brief
=0;
140 BOOL processes_only
=False
;
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 */
150 #endif /* FAST_SHARE_MODES */
152 struct session_record
*ptr
;
156 setup_logging(argv
[0],True
);
158 charset_initialise(0);
161 dbf
= fopen("/dev/null","w");
163 if (getuid() != geteuid()) {
164 printf("smbstatus should not be run setuid\n");
168 while ((c
= getopt(argc
, argv
, "pds:u:b")) != EOF
) {
180 strcpy(servicesf
, optarg
);
182 case 'u': /* added by OH */
183 Ucrit_addUsername(optarg
); /* added by OH */
186 fprintf(stderr
, "Usage: %s [-d] [-p] [-s configfile] [-u username]\n", *argv
); /* changed by OH */
191 if (!lp_load(servicesf
,False
)) {
192 fprintf(stderr
, "Can't load %s - run testparm to debug it\n", servicesf
);
196 get_myname(myhostname
, NULL
);
199 printf("using configfile = %s\n", servicesf
);
200 printf("lockdir = %s\n", *lp_lockdir() ? lp_lockdir() : "NULL");
203 strcpy(fname
,lp_lockdir());
204 standard_sub_basic(fname
);
205 trim_string(fname
,"","/");
206 strcat(fname
,"/STATUS..LCK");
208 f
= fopen(fname
,"r");
210 printf("Couldn't open status file %s\n",fname
);
212 printf("You need to have status=yes in your smb config file\n");
216 printf("Opened status file %s\n", fname
);
221 if (!processes_only
) {
222 printf("\nSamba version %s\n",VERSION
);
226 printf("PID Username Machine Time logged in\n");
227 printf("-------------------------------------------------------------------\n");
231 printf("Service uid gid pid machine\n");
232 printf("----------------------------------------------\n");
238 if (fread(&crec
,sizeof(crec
),1,f
) != 1)
240 if ( crec
.magic
== 0x280267 && process_exists(crec
.pid
)
241 && Ucrit_checkUsername(uidtoname(crec
.uid
)) /* added by OH */
249 if ((ptr
->pid
==crec
.pid
)&&(strncmp(ptr
->machine
,crec
.machine
,30)==0))
251 if (ptr
->start
> crec
.start
)
252 ptr
->start
=crec
.start
;
259 ptr
=(struct session_record
*) malloc(sizeof(struct session_record
));
262 ptr
->start
=crec
.start
;
263 strncpy(ptr
->machine
,crec
.machine
,30);
264 ptr
->machine
[30]='\0';
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 */
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
)));
288 if (processes_only
) exit(0);
295 printf("%-8d%-10.10s%-30.30s%s",ptr
->pid
,uidtoname(ptr
->uid
),ptr
->machine
,asctime(LocalTime(&(ptr
->start
))));
304 #ifdef FAST_SHARE_MODES
305 /*******************************************************************
306 initialize the shared memory for share_mode management
307 ******************************************************************/
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);
315 mode_array
= (smb_shm_offset_t
*)smb_shm_offset2addr(smb_shm_get_userdef_off());
316 if(mode_array
== NULL
)
318 printf("%s: base of shared memory hash array == 0! Exiting.\n", argv
[0]);
323 for( i
= 0; i
< lp_shmem_hash_size(); i
++)
325 smb_shm_lock_hash_entry(i
);
326 if(mode_array
[i
] == NULL_OFFSET
)
328 smb_shm_unlock_hash_entry(i
);
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))
334 share_mode_entry
*entry_scanner_p
=
335 (share_mode_entry
*)smb_shm_offset2addr(
336 file_scanner_p
->share_mode_entries
);
338 while(entry_scanner_p
!= 0)
341 int pid
= entry_scanner_p
->pid
;
342 int mode
= entry_scanner_p
->share_mode
;
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 */
349 /* For slow share modes go through all the files in
350 the share mode directory and read the entries in
354 dir
= opendir(lp_lockdir());
357 printf("%s: Unable to open lock directory %s.\n", argv
[0], lp_lockdir());
360 while ((s
=readdirname(dir
))) {
367 if (sscanf(s
,"share.%u.%u",&dev
,&inode
)!=2) continue;
369 strcpy(lname
,lp_lockdir());
370 trim_string(lname
,NULL
,"/");
374 fd
= open(lname
,O_RDWR
,0);
377 printf("%s: Unable to open share file %s.\n", argv
[0], lname
);
381 /* Lock the share mode file while we read it. */
382 if(fcntl_lock(fd
, F_SETLKW
, 0, 1, F_WRLCK
) == False
)
384 printf("%s: Unable to lock open share file %s.\n", argv
[0], lname
);
389 if(( buf
= read_share_file( fd
, lname
, argv
[0] )) == NULL
)
394 strcpy( fname
, &buf
[10]);
397 base
= buf
+ 10 + SVAL(buf
,8);
398 for( i
= 0; i
< IVAL(buf
, 4); i
++)
400 char *p
= base
+ (i
*16);
402 int pid
= IVAL(p
,12);
403 int mode
= IVAL(p
,8);
405 t
.tv_sec
= IVAL(p
,0);
406 t
.tv_usec
= IVAL(p
,4);
407 #endif /* FAST_SHARE_MODES */
409 fname
[sizeof(fname
)-1] = 0;
413 printf("Locked files:\n");
414 printf("Pid DenyMode R/W Name\n");
415 printf("------------------------------\n");
420 switch ((mode
>>4)&0xF)
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;
430 case 0: printf("RDONLY "); break;
431 case 1: printf("WRONLY "); break;
432 case 2: printf("RDWR "); break;
434 printf(" %s %s",fname
,asctime(LocalTime((time_t *)&t
.tv_sec
)));
436 #ifdef FAST_SHARE_MODES
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
);
447 smb_shm_get_usage(&bytes_free
, &bytes_used
, &bytes_overhead
);
448 bytes_total
= bytes_free
+ bytes_used
+ bytes_overhead
;
450 /*******************************************************************
451 deinitialize the shared memory for share_mode management
452 ******************************************************************/
455 #else /* FAST_SHARE_MODES */
464 #endif /* FAST_SHARE_MODES */
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
,
475 #endif /* FAST_SHARE_MODES */
481 void Ucrit_addUsername(pstring username
)
483 strcpy(Ucrit_username
, username
);
484 if(strlen(Ucrit_username
) > 0)
488 unsigned int Ucrit_checkUsername(pstring username
)
490 if ( !Ucrit_IsActive
) return 1;
491 if (strcmp(Ucrit_username
,username
) ==0) return 1;
495 void Ucrit_addPid(int pid
)
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
;
504 unsigned int Ucrit_checkPid(int pid
)
507 if ( !Ucrit_IsActive
) return 1;
508 for (i
=0;i
<Ucrit_MaxPid
;i
++)
509 if( pid
== Ucrit_pid
[i
] ) return 1;