00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "includes.h"
00035
00036 #define SMB_MAXPIDS 2048
00037 static uid_t Ucrit_uid = 0;
00038 static pid_t Ucrit_pid[SMB_MAXPIDS];
00039 static int Ucrit_MaxPid=0;
00040 static unsigned int Ucrit_IsActive = 0;
00041
00042 static int verbose, brief;
00043 static int shares_only = 0;
00044 static int locks_only = 0;
00045 static BOOL processes_only=False;
00046 static int show_brl;
00047 static BOOL numeric_only = False;
00048
00049 const char *username = NULL;
00050
00051 extern BOOL status_profile_dump(BOOL be_verbose);
00052 extern BOOL status_profile_rates(BOOL be_verbose);
00053
00054
00055 static void Ucrit_addUid(uid_t uid)
00056 {
00057 Ucrit_uid = uid;
00058 Ucrit_IsActive = 1;
00059 }
00060
00061 static unsigned int Ucrit_checkUid(uid_t uid)
00062 {
00063 if ( !Ucrit_IsActive )
00064 return 1;
00065
00066 if ( uid == Ucrit_uid )
00067 return 1;
00068
00069 return 0;
00070 }
00071
00072 static unsigned int Ucrit_checkPid(pid_t pid)
00073 {
00074 int i;
00075
00076 if ( !Ucrit_IsActive )
00077 return 1;
00078
00079 for (i=0;i<Ucrit_MaxPid;i++) {
00080 if( pid == Ucrit_pid[i] )
00081 return 1;
00082 }
00083
00084 return 0;
00085 }
00086
00087 static BOOL Ucrit_addPid( pid_t pid )
00088 {
00089 if ( !Ucrit_IsActive )
00090 return True;
00091
00092 if ( Ucrit_MaxPid >= SMB_MAXPIDS ) {
00093 d_printf("ERROR: More than %d pids for user %s!\n",
00094 SMB_MAXPIDS, uidtoname(Ucrit_uid));
00095
00096 return False;
00097 }
00098
00099 Ucrit_pid[Ucrit_MaxPid++] = pid;
00100
00101 return True;
00102 }
00103
00104 static void print_share_mode(const struct share_mode_entry *e,
00105 const char *sharepath,
00106 const char *fname,
00107 void *dummy)
00108 {
00109 static int count;
00110
00111 if (!is_valid_share_mode_entry(e)) {
00112 return;
00113 }
00114
00115 if (count==0) {
00116 d_printf("Locked files:\n");
00117 d_printf("Pid Uid DenyMode Access R/W Oplock SharePath Name Time\n");
00118 d_printf("--------------------------------------------------------------------------------------------------\n");
00119 }
00120 count++;
00121
00122 if (Ucrit_checkPid(procid_to_pid(&e->pid))) {
00123 d_printf("%-11s ",procid_str_static(&e->pid));
00124 d_printf("%-9u ", (unsigned int)e->uid);
00125 switch (map_share_mode_to_deny_mode(e->share_access,
00126 e->private_options)) {
00127 case DENY_NONE: d_printf("DENY_NONE "); break;
00128 case DENY_ALL: d_printf("DENY_ALL "); break;
00129 case DENY_DOS: d_printf("DENY_DOS "); break;
00130 case DENY_READ: d_printf("DENY_READ "); break;
00131 case DENY_WRITE:printf("DENY_WRITE "); break;
00132 case DENY_FCB: d_printf("DENY_FCB "); break;
00133 default: {
00134 d_printf("unknown-please report ! "
00135 "e->share_access = 0x%x, "
00136 "e->private_options = 0x%x\n",
00137 (unsigned int)e->share_access,
00138 (unsigned int)e->private_options );
00139 break;
00140 }
00141 }
00142 d_printf("0x%-8x ",(unsigned int)e->access_mask);
00143 if ((e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA))==
00144 (FILE_READ_DATA|FILE_WRITE_DATA)) {
00145 d_printf("RDWR ");
00146 } else if (e->access_mask & FILE_WRITE_DATA) {
00147 d_printf("WRONLY ");
00148 } else {
00149 d_printf("RDONLY ");
00150 }
00151
00152 if((e->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) ==
00153 (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) {
00154 d_printf("EXCLUSIVE+BATCH ");
00155 } else if (e->op_type & EXCLUSIVE_OPLOCK) {
00156 d_printf("EXCLUSIVE ");
00157 } else if (e->op_type & BATCH_OPLOCK) {
00158 d_printf("BATCH ");
00159 } else if (e->op_type & LEVEL_II_OPLOCK) {
00160 d_printf("LEVEL_II ");
00161 } else {
00162 d_printf("NONE ");
00163 }
00164
00165 d_printf(" %s %s %s",sharepath, fname, time_to_asc((time_t)e->time.tv_sec));
00166 }
00167 }
00168
00169 static void print_brl(SMB_DEV_T dev,
00170 SMB_INO_T ino,
00171 struct process_id pid,
00172 enum brl_type lock_type,
00173 enum brl_flavour lock_flav,
00174 br_off start,
00175 br_off size)
00176 {
00177 static int count;
00178 if (count==0) {
00179 d_printf("Byte range locks:\n");
00180 d_printf(" Pid dev:inode R/W start size\n");
00181 d_printf("------------------------------------------------\n");
00182 }
00183 count++;
00184
00185 d_printf("%8s %05x:%05x %s %9.0f %9.0f\n",
00186 procid_str_static(&pid), (int)dev, (int)ino,
00187 lock_type==READ_LOCK?"R":"W",
00188 (double)start, (double)size);
00189 }
00190
00191 static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
00192 {
00193 struct connections_data crec;
00194
00195 if (dbuf.dsize != sizeof(crec))
00196 return 0;
00197
00198 memcpy(&crec, dbuf.dptr, sizeof(crec));
00199
00200 if (crec.cnum == -1)
00201 return 0;
00202
00203 if (!process_exists(crec.pid) || !Ucrit_checkUid(crec.uid)) {
00204 return 0;
00205 }
00206
00207 d_printf("%-10s %s %-12s %s",
00208 crec.servicename,procid_str_static(&crec.pid),
00209 crec.machine,
00210 time_to_asc(crec.start));
00211
00212 return 0;
00213 }
00214
00215 static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
00216 {
00217 struct sessionid sessionid;
00218 fstring uid_str, gid_str;
00219
00220 if (dbuf.dsize != sizeof(sessionid))
00221 return 0;
00222
00223 memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
00224
00225 if (!process_exists_by_pid(sessionid.pid) || !Ucrit_checkUid(sessionid.uid)) {
00226 return 0;
00227 }
00228
00229 Ucrit_addPid( sessionid.pid );
00230
00231 fstr_sprintf(uid_str, "%d", sessionid.uid);
00232 fstr_sprintf(gid_str, "%d", sessionid.gid);
00233
00234 d_printf("%5d %-12s %-12s %-12s (%s)\n",
00235 (int)sessionid.pid,
00236 numeric_only ? uid_str : uidtoname(sessionid.uid),
00237 numeric_only ? gid_str : gidtoname(sessionid.gid),
00238 sessionid.remote_machine, sessionid.hostname);
00239
00240 return 0;
00241 }
00242
00243
00244
00245
00246 int main(int argc, char *argv[])
00247 {
00248 int c;
00249 int profile_only = 0;
00250 TDB_CONTEXT *tdb;
00251 BOOL show_processes, show_locks, show_shares;
00252 poptContext pc;
00253 struct poptOption long_options[] = {
00254 POPT_AUTOHELP
00255 {"processes", 'p', POPT_ARG_NONE, &processes_only, 'p', "Show processes only" },
00256 {"verbose", 'v', POPT_ARG_NONE, &verbose, 'v', "Be verbose" },
00257 {"locks", 'L', POPT_ARG_NONE, &locks_only, 'L', "Show locks only" },
00258 {"shares", 'S', POPT_ARG_NONE, &shares_only, 'S', "Show shares only" },
00259 {"user", 'u', POPT_ARG_STRING, &username, 'u', "Switch to user" },
00260 {"brief", 'b', POPT_ARG_NONE, &brief, 'b', "Be brief" },
00261 {"profile", 'P', POPT_ARG_NONE, NULL, 'P', "Do profiling" },
00262 {"profile-rates", 'R', POPT_ARG_NONE, NULL, 'R', "Show call rates" },
00263 {"byterange", 'B', POPT_ARG_NONE, &show_brl, 'B', "Include byte range locks"},
00264 {"numeric", 'n', POPT_ARG_NONE, &numeric_only, 'n', "Numeric uid/gid"},
00265 POPT_COMMON_SAMBA
00266 POPT_TABLEEND
00267 };
00268
00269 sec_init();
00270 load_case_tables();
00271
00272 setup_logging(argv[0],True);
00273
00274 dbf = x_stderr;
00275
00276 if (getuid() != geteuid()) {
00277 d_printf("smbstatus should not be run setuid\n");
00278 return(1);
00279 }
00280
00281 pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
00282 POPT_CONTEXT_KEEP_FIRST);
00283
00284 while ((c = poptGetNextOpt(pc)) != -1) {
00285 switch (c) {
00286 case 'u':
00287 Ucrit_addUid(nametouid(poptGetOptArg(pc)));
00288 break;
00289 case 'P':
00290 case 'R':
00291 profile_only = c;
00292 }
00293 }
00294
00295
00296
00297 show_processes = !(shares_only || locks_only || profile_only) || processes_only;
00298 show_locks = !(shares_only || processes_only || profile_only) || locks_only;
00299 show_shares = !(processes_only || locks_only || profile_only) || shares_only;
00300
00301 if ( username )
00302 Ucrit_addUid( nametouid(username) );
00303
00304 if (verbose) {
00305 d_printf("using configfile = %s\n", dyn_CONFIGFILE);
00306 }
00307
00308 if (!lp_load(dyn_CONFIGFILE,False,False,False,True)) {
00309 fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
00310 return (-1);
00311 }
00312
00313 switch (profile_only) {
00314 case 'P':
00315
00316 return status_profile_dump(verbose);
00317 case 'R':
00318
00319 return status_profile_rates(verbose);
00320 default:
00321 break;
00322 }
00323
00324 if ( show_processes ) {
00325 tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
00326 if (!tdb) {
00327 d_printf("sessionid.tdb not initialised\n");
00328 } else {
00329 d_printf("\nSamba version %s\n",SAMBA_VERSION_STRING);
00330 d_printf("PID Username Group Machine \n");
00331 d_printf("-------------------------------------------------------------------\n");
00332
00333 tdb_traverse(tdb, traverse_sessionid, NULL);
00334 tdb_close(tdb);
00335 }
00336
00337 if (processes_only)
00338 exit(0);
00339 }
00340
00341 if ( show_shares ) {
00342 tdb = tdb_open_log(lock_path("connections.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
00343 if (!tdb) {
00344 d_printf("%s not initialised\n", lock_path("connections.tdb"));
00345 d_printf("This is normal if an SMB client has never connected to your server.\n");
00346 } else {
00347 if (verbose) {
00348 d_printf("Opened %s\n", lock_path("connections.tdb"));
00349 }
00350
00351 if (brief)
00352 exit(0);
00353
00354 d_printf("\nService pid machine Connected at\n");
00355 d_printf("-------------------------------------------------------\n");
00356
00357 tdb_traverse(tdb, traverse_fn1, NULL);
00358 tdb_close(tdb);
00359
00360 d_printf("\n");
00361 }
00362
00363 if ( shares_only )
00364 exit(0);
00365 }
00366
00367 if ( show_locks ) {
00368 int ret;
00369
00370 tdb = tdb_open_log(lock_path("locking.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
00371
00372 if (!tdb) {
00373 d_printf("%s not initialised\n", lock_path("locking.tdb"));
00374 d_printf("This is normal if an SMB client has never connected to your server.\n");
00375 exit(0);
00376 } else {
00377 tdb_close(tdb);
00378 }
00379
00380 if (!locking_init(1)) {
00381 d_printf("Can't initialise locking module - exiting\n");
00382 exit(1);
00383 }
00384
00385 ret = share_mode_forall(print_share_mode, NULL);
00386
00387 if (ret == 0) {
00388 d_printf("No locked files\n");
00389 } else if (ret == -1) {
00390 d_printf("locked file list truncated\n");
00391 }
00392
00393 d_printf("\n");
00394
00395 if (show_brl) {
00396 brl_forall(print_brl);
00397 }
00398
00399 locking_end();
00400 }
00401
00402 return (0);
00403 }