LCOV - code coverage report
Current view: top level - source3/utils - status.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 306 621 49.3 %
Date: 2024-05-31 13:13:24 Functions: 17 22 77.3 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    status reporting
       4             :    Copyright (C) Andrew Tridgell 1994-1998
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : 
      19             :    Revision History:
      20             : 
      21             :    12 aug 96: Erik.Devriendt@te6.siemens.be
      22             :    added support for shared memory implementation of share mode locking
      23             : 
      24             :    21-Jul-1998: rsharpe@ns.aus.com (Richard Sharpe)
      25             :    Added -L (locks only) -S (shares only) flags and code
      26             : 
      27             : */
      28             : 
      29             : /*
      30             :  * This program reports current SMB connections
      31             :  */
      32             : 
      33             : #include "includes.h"
      34             : #include "lib/util/server_id.h"
      35             : #include "smbd/globals.h"
      36             : #include "system/filesys.h"
      37             : #include "lib/cmdline/cmdline.h"
      38             : #include "dbwrap/dbwrap.h"
      39             : #include "dbwrap/dbwrap_open.h"
      40             : #include "../libcli/security/security.h"
      41             : #include "session.h"
      42             : #include "locking/share_mode_lock.h"
      43             : #include "locking/proto.h"
      44             : #include "messages.h"
      45             : #include "librpc/gen_ndr/open_files.h"
      46             : #include "smbd/smbd.h"
      47             : #include "librpc/gen_ndr/notify.h"
      48             : #include "conn_tdb.h"
      49             : #include "serverid.h"
      50             : #include "status_profile.h"
      51             : #include "status.h"
      52             : #include "status_json.h"
      53             : #include "smbd/notifyd/notifyd_db.h"
      54             : #include "cmdline_contexts.h"
      55             : #include "locking/leases_db.h"
      56             : #include "lib/util/string_wrappers.h"
      57             : #include "lib/param/param.h"
      58             : 
      59             : #ifdef HAVE_JANSSON
      60             : #include <jansson.h>
      61             : #include "audit_logging.h" /* various JSON helpers */
      62             : #include "auth/common_auth.h"
      63             : #endif /* HAVE_JANSSON */
      64             : 
      65             : #define SMB_MAXPIDS             2048
      66             : static uid_t            Ucrit_uid = 0;               /* added by OH */
      67             : static struct server_id Ucrit_pid[SMB_MAXPIDS];  /* Ugly !!! */   /* added by OH */
      68             : static int              Ucrit_MaxPid=0;                    /* added by OH */
      69             : static unsigned int     Ucrit_IsActive = 0;                /* added by OH */
      70             : 
      71             : static bool verbose, brief;
      72             : static bool shares_only;            /* Added by RJS */
      73             : static bool locks_only;            /* Added by RJS */
      74             : static bool processes_only;
      75             : static bool show_brl;
      76             : static bool numeric_only;
      77             : static bool do_checks = true;
      78             : 
      79             : const char *username = NULL;
      80             : 
      81             : /* added by OH */
      82           0 : static void Ucrit_addUid(uid_t uid)
      83             : {
      84           0 :         Ucrit_uid = uid;
      85           0 :         Ucrit_IsActive = 1;
      86           0 : }
      87             : 
      88          22 : static unsigned int Ucrit_checkUid(uid_t uid)
      89             : {
      90          22 :         if ( !Ucrit_IsActive )
      91          22 :                 return 1;
      92             : 
      93           0 :         if ( uid == Ucrit_uid )
      94           0 :                 return 1;
      95             : 
      96           0 :         return 0;
      97             : }
      98             : 
      99          10 : static unsigned int Ucrit_checkPid(struct server_id pid)
     100             : {
     101             :         int i;
     102             : 
     103          10 :         if ( !Ucrit_IsActive )
     104          10 :                 return 1;
     105             : 
     106           0 :         for (i=0;i<Ucrit_MaxPid;i++) {
     107           0 :                 if (server_id_equal(&pid, &Ucrit_pid[i])) {
     108           0 :                         return 1;
     109             :                 }
     110             :         }
     111             : 
     112           0 :         return 0;
     113             : }
     114             : 
     115          12 : static bool Ucrit_addPid( struct server_id pid )
     116             : {
     117          12 :         if ( !Ucrit_IsActive )
     118          12 :                 return True;
     119             : 
     120           0 :         if ( Ucrit_MaxPid >= SMB_MAXPIDS ) {
     121           0 :                 fprintf(stderr, "ERROR: More than %d pids for user %s!\n",
     122             :                          SMB_MAXPIDS, uidtoname(Ucrit_uid));
     123             : 
     124           0 :                 return False;
     125             :         }
     126             : 
     127           0 :         Ucrit_pid[Ucrit_MaxPid++] = pid;
     128             : 
     129           0 :         return True;
     130             : }
     131             : 
     132           6 : static int print_share_mode_stdout(struct traverse_state *state,
     133             :                                    const char *pid,
     134             :                                    const char *user_name,
     135             :                                    const char *denymode,
     136             :                                    int access_mask,
     137             :                                    const char *rw,
     138             :                                    const char *oplock,
     139             :                                    const char *servicepath,
     140             :                                    const char *filename,
     141             :                                    const char *timestr)
     142             : {
     143           6 :         if (state->first) {
     144           6 :                 d_printf("\nLocked files:\n");
     145           6 :                 d_printf("Pid          User(ID)   DenyMode   Access      R/W        Oplock           SharePath   Name   Time\n");
     146           6 :                 d_printf("--------------------------------------------------------------------------------------------------\n");
     147             : 
     148           6 :                 state->first = false;
     149             :         }
     150             : 
     151           6 :         d_printf("%-11s  %-9s  %-10s 0x%-8x  %-10s %-14s   %s   %s   %s",
     152             :                  pid, user_name, denymode, access_mask, rw, oplock,
     153             :                  servicepath, filename, timestr);
     154           6 :         return 0;
     155             : }
     156             : 
     157          10 : static int prepare_share_mode(struct traverse_state *state)
     158             : {
     159          10 :         if (!state->json_output) {
     160             :                 /* only print header line if there are open files */
     161           6 :                 state->first = true;
     162             :         } else {
     163           4 :                 add_section_to_json(state, "open_files");
     164             :         }
     165          10 :         return 0;
     166             : }
     167             : 
     168          10 : static uint32_t map_share_mode_to_deny_mode(
     169             :         uint32_t share_access, uint32_t private_options)
     170             : {
     171          10 :         switch (share_access & ~FILE_SHARE_DELETE) {
     172           0 :         case FILE_SHARE_NONE:
     173           0 :                 return DENY_ALL;
     174           0 :         case FILE_SHARE_READ:
     175           0 :                 return DENY_WRITE;
     176           0 :         case FILE_SHARE_WRITE:
     177           0 :                 return DENY_READ;
     178          10 :         case FILE_SHARE_READ|FILE_SHARE_WRITE:
     179          10 :                 return DENY_NONE;
     180             :         }
     181           0 :         if (private_options & NTCREATEX_FLAG_DENY_DOS) {
     182           0 :                 return DENY_DOS;
     183           0 :         } else if (private_options & NTCREATEX_FLAG_DENY_FCB) {
     184           0 :                 return DENY_FCB;
     185             :         }
     186             : 
     187           0 :         return (uint32_t)-1;
     188             : }
     189             : 
     190          10 : static int print_share_mode(struct file_id fid,
     191             :                             const struct share_mode_data *d,
     192             :                             const struct share_mode_entry *e,
     193             :                             void *private_data)
     194             : {
     195          10 :         const char *denymode = NULL;
     196             :         uint denymode_int;
     197          10 :         const char *oplock = NULL;
     198          10 :         const char *pid = NULL;
     199          10 :         const char *rw = NULL;
     200          10 :         const char *filename = NULL;
     201          10 :         const char *timestr = NULL;
     202          10 :         const char *user_str = NULL;
     203             :         uint32_t lstate;
     204          10 :         struct traverse_state *state = (struct traverse_state *)private_data;
     205             : 
     206          10 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     207          10 :         if (tmp_ctx == NULL) {
     208           0 :                 return -1;
     209             :         }
     210             : 
     211          10 :         if (do_checks && !is_valid_share_mode_entry(e)) {
     212           0 :                 TALLOC_FREE(tmp_ctx);
     213           0 :                 return 0;
     214             :         }
     215             : 
     216          10 :         if (do_checks && !serverid_exists(&e->pid)) {
     217             :                 /* the process for this entry does not exist any more */
     218           0 :                 TALLOC_FREE(tmp_ctx);
     219           0 :                 return 0;
     220             :         }
     221             : 
     222          10 :         if (Ucrit_checkPid(e->pid)) {
     223             :                 struct server_id_buf tmp;
     224          10 :                 pid = server_id_str_buf(e->pid, &tmp);
     225          10 :                 if (state->resolve_uids) {
     226           0 :                         user_str = talloc_asprintf(tmp_ctx, "%s", uidtoname(e->uid));
     227             :                 } else {
     228          10 :                         user_str = talloc_asprintf(tmp_ctx, "%u", (unsigned int)e->uid);
     229             :                 }
     230          10 :                 if (user_str == NULL) {
     231           0 :                         TALLOC_FREE(tmp_ctx);
     232           0 :                         return -1;
     233             :                 }
     234             : 
     235          10 :                 denymode_int = map_share_mode_to_deny_mode(e->share_access,
     236          10 :                                                            e->private_options);
     237          10 :                 switch (denymode_int) {
     238          10 :                         case DENY_NONE:
     239          10 :                                 denymode = "DENY_NONE";
     240          10 :                                 break;
     241           0 :                         case DENY_ALL:
     242           0 :                                 denymode = "DENY_ALL";
     243           0 :                                 break;
     244           0 :                         case DENY_DOS:
     245           0 :                                 denymode = "DENY_DOS";
     246           0 :                                 break;
     247           0 :                         case DENY_READ:
     248           0 :                                 denymode = "DENY_READ";
     249           0 :                                 break;
     250           0 :                         case DENY_WRITE:
     251           0 :                                 denymode = "DENY_WRITE";
     252           0 :                                 break;
     253           0 :                         case DENY_FCB:
     254           0 :                                 denymode = "DENY_FCB";
     255           0 :                                 break;
     256           0 :                         default: {
     257           0 :                                 denymode = talloc_asprintf(tmp_ctx,
     258             :                                                            "UNKNOWN(0x%08x)",
     259             :                                                            denymode_int);
     260           0 :                                 if (denymode == NULL) {
     261           0 :                                         TALLOC_FREE(tmp_ctx);
     262           0 :                                         return -1;
     263             :                                 }
     264           0 :                                 fprintf(stderr,
     265             :                                         "unknown-please report ! "
     266             :                                         "e->share_access = 0x%x, "
     267             :                                         "e->private_options = 0x%x\n",
     268           0 :                                         (unsigned int)e->share_access,
     269           0 :                                         (unsigned int)e->private_options);
     270           0 :                                 break;
     271             :                         }
     272             :                 }
     273          10 :                 filename = talloc_asprintf(tmp_ctx,
     274             :                                            "%s%s",
     275          10 :                                            d->base_name,
     276          10 :                                            (d->stream_name != NULL) ? d->stream_name : "");
     277          10 :                 if (filename == NULL) {
     278           0 :                         TALLOC_FREE(tmp_ctx);
     279           0 :                         return -1;
     280             :                 }
     281          10 :                 if ((e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA))==
     282             :                                 (FILE_READ_DATA|FILE_WRITE_DATA)) {
     283          10 :                         rw = "RDWR";
     284           0 :                 } else if (e->access_mask & FILE_WRITE_DATA) {
     285           0 :                         rw = "WRONLY";
     286             :                 } else {
     287           0 :                         rw = "RDONLY";
     288             :                 }
     289             : 
     290          10 :                 if (e->op_type & BATCH_OPLOCK) {
     291           0 :                         oplock = "BATCH";
     292          10 :                 } else if (e->op_type & EXCLUSIVE_OPLOCK) {
     293           0 :                         oplock = "EXCLUSIVE";
     294          10 :                 } else if (e->op_type & LEVEL_II_OPLOCK) {
     295           0 :                         oplock = "LEVEL_II";
     296          10 :                 } else if (e->op_type == LEASE_OPLOCK) {
     297             :                         NTSTATUS status;
     298             : 
     299           0 :                         status = leases_db_get(
     300             :                                 &e->client_guid,
     301             :                                 &e->lease_key,
     302             :                                 &d->id,
     303             :                                 &lstate, /* current_state */
     304             :                                 NULL, /* breaking */
     305             :                                 NULL, /* breaking_to_requested */
     306             :                                 NULL, /* breaking_to_required */
     307             :                                 NULL, /* lease_version */
     308             :                                 NULL); /* epoch */
     309             : 
     310           0 :                         if (NT_STATUS_IS_OK(status)) {
     311           0 :                                 oplock = talloc_asprintf(tmp_ctx, "LEASE(%s%s%s)%s%s%s",
     312           0 :                                                  (lstate & SMB2_LEASE_READ)?"R":"",
     313           0 :                                                  (lstate & SMB2_LEASE_WRITE)?"W":"",
     314           0 :                                                  (lstate & SMB2_LEASE_HANDLE)?"H":"",
     315           0 :                                                  (lstate & SMB2_LEASE_READ)?"":" ",
     316           0 :                                                  (lstate & SMB2_LEASE_WRITE)?"":" ",
     317           0 :                                                  (lstate & SMB2_LEASE_HANDLE)?"":" ");
     318             :                         } else {
     319           0 :                                 oplock = "LEASE STATE UNKNOWN";
     320             :                         }
     321             :                 } else {
     322          10 :                         oplock = "NONE";
     323             :                 }
     324             : 
     325          10 :                 timestr = time_to_asc((time_t)e->time.tv_sec);
     326             : 
     327          10 :                 if (!state->json_output) {
     328           6 :                         print_share_mode_stdout(state,
     329             :                                                 pid,
     330             :                                                 user_str,
     331             :                                                 denymode,
     332           6 :                                                 (unsigned int)e->access_mask,
     333             :                                                 rw,
     334             :                                                 oplock,
     335           6 :                                                 d->servicepath,
     336             :                                                 filename,
     337             :                                                 timestr);
     338             :                 } else {
     339           4 :                         print_share_mode_json(state,
     340             :                                               d,
     341             :                                               e,
     342             :                                               fid,
     343             :                                               user_str,
     344             :                                               oplock,
     345             :                                               lstate,
     346             :                                               filename);
     347             :                 }
     348             :         }
     349          10 :         TALLOC_FREE(tmp_ctx);
     350          10 :         return 0;
     351             : }
     352             : 
     353           0 : static void print_brl_stdout(struct traverse_state *state,
     354             :                              char *pid,
     355             :                              char *id,
     356             :                              const char *desc,
     357             :                              intmax_t start,
     358             :                              intmax_t size,
     359             :                              const char *sharepath,
     360             :                              char *fname)
     361             : {
     362           0 :         if (state->first) {
     363           0 :                 d_printf("Byte range locks:\n");
     364           0 :                 d_printf("Pid        dev:inode       R/W  start     size      SharePath               Name\n");
     365           0 :                 d_printf("--------------------------------------------------------------------------------\n");
     366             : 
     367           0 :                 state->first = false;
     368             :         }
     369           0 :         d_printf("%-10s %-15s %-4s %-9jd %-9jd %-24s %-24s\n",
     370             :                  pid, id, desc, start, size, sharepath, fname);
     371           0 : }
     372             : 
     373           2 : static int prepare_brl(struct traverse_state *state)
     374             : {
     375           2 :         if (!state->json_output) {
     376             :                 /* only print header line if there are locked files */
     377           0 :                 state->first = true;
     378             :         } else {
     379           2 :                 add_section_to_json(state, "byte_range_locks");
     380             :         }
     381           2 :         return 0;
     382             : }
     383             : 
     384           0 : static void print_brl(struct file_id id,
     385             :                         struct server_id pid,
     386             :                         enum brl_type lock_type,
     387             :                         enum brl_flavour lock_flav,
     388             :                         br_off start,
     389             :                         br_off size,
     390             :                         void *private_data)
     391             : {
     392             :         unsigned int i;
     393             :         static const struct {
     394             :                 enum brl_type lock_type;
     395             :                 const char *desc;
     396             :         } lock_types[] = {
     397             :                 { READ_LOCK, "R" },
     398             :                 { WRITE_LOCK, "W" },
     399             :                 { UNLOCK_LOCK, "U" }
     400             :         };
     401           0 :         const char *desc="X";
     402           0 :         const char *sharepath = "";
     403           0 :         char *fname = NULL;
     404             :         struct share_mode_lock *share_mode;
     405             :         struct server_id_buf tmp;
     406             :         struct file_id_buf ftmp;
     407           0 :         struct traverse_state *state = (struct traverse_state *)private_data;
     408             : 
     409           0 :         share_mode = fetch_share_mode_unlocked(NULL, id);
     410           0 :         if (share_mode) {
     411           0 :                 fname = share_mode_filename(NULL, share_mode);
     412           0 :                 sharepath = share_mode_servicepath(share_mode);
     413             :         } else {
     414           0 :                 fname = talloc_strdup(NULL, "");
     415           0 :                 if (fname == NULL) {
     416           0 :                         return;
     417             :                 }
     418             :         }
     419             : 
     420           0 :         for (i=0;i<ARRAY_SIZE(lock_types);i++) {
     421           0 :                 if (lock_type == lock_types[i].lock_type) {
     422           0 :                         desc = lock_types[i].desc;
     423             :                 }
     424             :         }
     425             : 
     426           0 :         if (!state->json_output) {
     427           0 :                 print_brl_stdout(state,
     428             :                                  server_id_str_buf(pid, &tmp),
     429             :                                  file_id_str_buf(id, &ftmp),
     430             :                                  desc,
     431             :                                  (intmax_t)start,
     432             :                                  (intmax_t)size,
     433             :                                  sharepath,
     434             :                                  fname);
     435             :         } else {
     436           0 :                 print_brl_json(state,
     437             :                                pid,
     438             :                                id,
     439             :                                desc,
     440             :                                lock_flav,
     441             :                                (intmax_t)start,
     442             :                                (intmax_t)size,
     443             :                                sharepath,
     444             :                                fname);
     445             : 
     446             :         }
     447             : 
     448           0 :         TALLOC_FREE(fname);
     449           0 :         TALLOC_FREE(share_mode);
     450             : }
     451             : 
     452          12 : static const char *session_dialect_str(uint16_t dialect)
     453             : {
     454             :         static fstring unknown_dialect;
     455             : 
     456          12 :         switch(dialect){
     457           0 :         case SMB2_DIALECT_REVISION_000:
     458           0 :                 return "NT1";
     459           0 :         case SMB2_DIALECT_REVISION_202:
     460           0 :                 return "SMB2_02";
     461           0 :         case SMB2_DIALECT_REVISION_210:
     462           0 :                 return "SMB2_10";
     463           0 :         case SMB2_DIALECT_REVISION_222:
     464           0 :                 return "SMB2_22";
     465           0 :         case SMB2_DIALECT_REVISION_224:
     466           0 :                 return "SMB2_24";
     467           0 :         case SMB3_DIALECT_REVISION_300:
     468           0 :                 return "SMB3_00";
     469           0 :         case SMB3_DIALECT_REVISION_302:
     470           0 :                 return "SMB3_02";
     471           0 :         case SMB3_DIALECT_REVISION_310:
     472           0 :                 return "SMB3_10";
     473          12 :         case SMB3_DIALECT_REVISION_311:
     474          12 :                 return "SMB3_11";
     475             :         }
     476             : 
     477           0 :         fstr_sprintf(unknown_dialect, "Unknown (0x%04x)", dialect);
     478           0 :         return unknown_dialect;
     479             : }
     480             : 
     481           6 : static int traverse_connections_stdout(struct traverse_state *state,
     482             :                                        const char *servicename,
     483             :                                        char *server_id,
     484             :                                        const char *machine,
     485             :                                        const char *timestr,
     486             :                                        const char *encryption_cipher,
     487             :                                        enum crypto_degree encryption_degree,
     488             :                                        const char *signing_cipher,
     489             :                                        enum crypto_degree signing_degree)
     490             : {
     491             :         fstring encryption;
     492             :         fstring signing;
     493             : 
     494           6 :         if (encryption_degree == CRYPTO_DEGREE_FULL) {
     495           0 :                 fstr_sprintf(encryption, "%s", encryption_cipher);
     496           6 :         } else if (encryption_degree == CRYPTO_DEGREE_ANONYMOUS) {
     497           0 :                 fstr_sprintf(encryption, "anonymous(%s)", encryption_cipher);
     498           6 :         } else if (encryption_degree == CRYPTO_DEGREE_PARTIAL) {
     499           0 :                 fstr_sprintf(encryption, "partial(%s)", encryption_cipher);
     500             :         } else {
     501           6 :                 fstr_sprintf(encryption, "-");
     502             :         }
     503           6 :         if (signing_degree == CRYPTO_DEGREE_FULL) {
     504           0 :                 fstr_sprintf(signing, "%s", signing_cipher);
     505           6 :         } else if (signing_degree == CRYPTO_DEGREE_ANONYMOUS) {
     506           0 :                 fstr_sprintf(signing, "anonymous(%s)", signing_cipher);
     507           6 :         } else if (signing_degree == CRYPTO_DEGREE_PARTIAL) {
     508           0 :                 fstr_sprintf(signing, "partial(%s)", signing_cipher);
     509             :         } else {
     510           6 :                 fstr_sprintf(signing, "-");
     511             :         }
     512             : 
     513           6 :         d_printf("%-12s %-7s %-13s %-32s %-12s %-12s\n",
     514             :                  servicename, server_id, machine, timestr, encryption, signing);
     515             : 
     516           6 :         return 0;
     517             : }
     518             : 
     519          10 : static int prepare_connections(struct traverse_state *state)
     520             : {
     521          10 :         if (!state->json_output) {
     522             :                 /* always print header line */
     523           6 :                 d_printf("\n%-12s %-7s %-13s %-32s %-12s %-12s\n", "Service", "pid", "Machine", "Connected at", "Encryption", "Signing");
     524           6 :                 d_printf("---------------------------------------------------------------------------------------------\n");
     525             :         } else {
     526           4 :                 add_section_to_json(state, "tcons");
     527             :         }
     528          10 :         return 0;
     529             : }
     530             : 
     531          10 : static int traverse_connections(const struct connections_data *crec,
     532             :                                 void *private_data)
     533             : {
     534             :         struct server_id_buf tmp;
     535          10 :         char *timestr = NULL;
     536          10 :         int result = 0;
     537          10 :         const char *encryption = "-";
     538          10 :         enum crypto_degree encryption_degree = CRYPTO_DEGREE_NONE;
     539          10 :         const char *signing = "-";
     540          10 :         enum crypto_degree signing_degree = CRYPTO_DEGREE_NONE;
     541          10 :         struct traverse_state *state = (struct traverse_state *)private_data;
     542             : 
     543          10 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     544          10 :         if (tmp_ctx == NULL) {
     545           0 :                 return -1;
     546             :         }
     547             : 
     548          10 :         if (crec->cnum == TID_FIELD_INVALID) {
     549           0 :                 TALLOC_FREE(tmp_ctx);
     550           0 :                 return 0;
     551             :         }
     552             : 
     553          10 :         if (do_checks &&
     554          10 :             (!process_exists(crec->pid) || !Ucrit_checkUid(crec->uid))) {
     555           0 :                 TALLOC_FREE(tmp_ctx);
     556           0 :                 return 0;
     557             :         }
     558             : 
     559          10 :         timestr = timestring(tmp_ctx, nt_time_to_unix(crec->start));
     560          10 :         if (timestr == NULL) {
     561           0 :                 TALLOC_FREE(tmp_ctx);
     562           0 :                 return -1;
     563             :         }
     564             : 
     565          20 :         if (smbXsrv_is_encrypted(crec->encryption_flags) ||
     566          10 :             smbXsrv_is_partially_encrypted(crec->encryption_flags))
     567             :         {
     568           0 :                 switch (crec->cipher) {
     569           0 :                 case SMB_ENCRYPTION_GSSAPI:
     570           0 :                         encryption = "GSSAPI";
     571           0 :                         break;
     572           0 :                 case SMB2_ENCRYPTION_AES128_CCM:
     573           0 :                         encryption = "AES-128-CCM";
     574           0 :                         break;
     575           0 :                 case SMB2_ENCRYPTION_AES128_GCM:
     576           0 :                         encryption = "AES-128-GCM";
     577           0 :                         break;
     578           0 :                 case SMB2_ENCRYPTION_AES256_CCM:
     579           0 :                         encryption = "AES-256-CCM";
     580           0 :                         break;
     581           0 :                 case SMB2_ENCRYPTION_AES256_GCM:
     582           0 :                         encryption = "AES-256-GCM";
     583           0 :                         break;
     584           0 :                 default:
     585           0 :                         encryption = "???";
     586           0 :                         break;
     587             :                 }
     588           0 :                 if (smbXsrv_is_encrypted(crec->encryption_flags)) {
     589           0 :                         encryption_degree = CRYPTO_DEGREE_FULL;
     590           0 :                 } else if (smbXsrv_is_partially_encrypted(crec->encryption_flags)) {
     591           0 :                         encryption_degree = CRYPTO_DEGREE_PARTIAL;
     592             :                 }
     593           0 :                 if (encryption_degree != CRYPTO_DEGREE_NONE &&
     594           0 :                     !crec->authenticated)
     595             :                 {
     596           0 :                         encryption_degree = CRYPTO_DEGREE_ANONYMOUS;
     597             :                 }
     598             :         }
     599             : 
     600          20 :         if (smbXsrv_is_signed(crec->signing_flags) ||
     601          10 :             smbXsrv_is_partially_signed(crec->signing_flags))
     602             :         {
     603           0 :                 switch (crec->signing) {
     604           0 :                 case SMB2_SIGNING_MD5_SMB1:
     605           0 :                         signing = "HMAC-MD5";
     606           0 :                         break;
     607           0 :                 case SMB2_SIGNING_HMAC_SHA256:
     608           0 :                         signing = "HMAC-SHA256";
     609           0 :                         break;
     610           0 :                 case SMB2_SIGNING_AES128_CMAC:
     611           0 :                         signing = "AES-128-CMAC";
     612           0 :                         break;
     613           0 :                 case SMB2_SIGNING_AES128_GMAC:
     614           0 :                         signing = "AES-128-GMAC";
     615           0 :                         break;
     616           0 :                 default:
     617           0 :                         signing = "???";
     618           0 :                         break;
     619             :                 }
     620           0 :                 if (smbXsrv_is_signed(crec->signing_flags)) {
     621           0 :                         signing_degree = CRYPTO_DEGREE_FULL;
     622           0 :                 } else if (smbXsrv_is_partially_signed(crec->signing_flags)) {
     623           0 :                         signing_degree = CRYPTO_DEGREE_PARTIAL;
     624             :                 }
     625           0 :                 if (signing_degree != CRYPTO_DEGREE_NONE &&
     626           0 :                     !crec->authenticated)
     627             :                 {
     628           0 :                         signing_degree = CRYPTO_DEGREE_ANONYMOUS;
     629             :                 }
     630             :         }
     631             : 
     632          10 :         if (!state->json_output) {
     633          12 :                 result = traverse_connections_stdout(state,
     634           6 :                                                      crec->servicename,
     635             :                                                      server_id_str_buf(crec->pid, &tmp),
     636           6 :                                                      crec->machine,
     637             :                                                      timestr,
     638             :                                                      encryption,
     639             :                                                      encryption_degree,
     640             :                                                      signing,
     641             :                                                      signing_degree);
     642             :         } else {
     643           4 :                 result = traverse_connections_json(state,
     644             :                                                    crec,
     645             :                                                    encryption,
     646             :                                                    encryption_degree,
     647             :                                                    signing,
     648             :                                                    signing_degree);
     649             :         }
     650             : 
     651          10 :         TALLOC_FREE(timestr);
     652          10 :         TALLOC_FREE(tmp_ctx);
     653             : 
     654          10 :         return result;
     655             : }
     656             : 
     657           8 : static int traverse_sessionid_stdout(struct traverse_state *state,
     658             :                                      char *server_id,
     659             :                                      char *uid_gid_str,
     660             :                                      char *machine_hostname,
     661             :                                      const char *dialect,
     662             :                                      const char *encryption_cipher,
     663             :                                      enum crypto_degree encryption_degree,
     664             :                                      const char *signing_cipher,
     665             :                                      enum crypto_degree signing_degree)
     666             : {
     667             :         fstring encryption;
     668             :         fstring signing;
     669             : 
     670           8 :         if (encryption_degree == CRYPTO_DEGREE_FULL) {
     671           0 :                 fstr_sprintf(encryption, "%s", encryption_cipher);
     672           8 :         } else if (encryption_degree == CRYPTO_DEGREE_ANONYMOUS) {
     673           0 :                 fstr_sprintf(encryption, "anonymous(%s)", encryption_cipher);
     674           8 :         } else if (encryption_degree == CRYPTO_DEGREE_PARTIAL) {
     675           0 :                 fstr_sprintf(encryption, "partial(%s)", encryption_cipher);
     676             :         } else {
     677           8 :                 fstr_sprintf(encryption, "-");
     678             :         }
     679           8 :         if (signing_degree == CRYPTO_DEGREE_FULL) {
     680           0 :                 fstr_sprintf(signing, "%s", signing_cipher);
     681           8 :         } else if (signing_degree == CRYPTO_DEGREE_ANONYMOUS) {
     682           0 :                 fstr_sprintf(signing, "anonymous(%s)", signing_cipher);
     683           8 :         } else if (signing_degree == CRYPTO_DEGREE_PARTIAL) {
     684           7 :                 fstr_sprintf(signing, "partial(%s)", signing_cipher);
     685             :         } else {
     686           1 :                 fstr_sprintf(signing, "-");
     687             :         }
     688             : 
     689           8 :         d_printf("%-7s %-25s %-41s %-17s %-20s %-21s\n",
     690             :                  server_id, uid_gid_str, machine_hostname, dialect, encryption,
     691             :                  signing);
     692             : 
     693           8 :         return 0;
     694             : }
     695             : 
     696          12 : static int prepare_sessionid(struct traverse_state *state)
     697             : {
     698          12 :         if (!state->json_output) {
     699             :                 /* always print header line */
     700           8 :                 d_printf("\nSamba version %s\n",samba_version_string());
     701           8 :                 d_printf("%-7s %-12s %-12s %-41s %-17s %-20s %-21s\n", "PID", "Username", "Group", "Machine", "Protocol Version", "Encryption", "Signing");
     702           8 :                 d_printf("----------------------------------------------------------------------------------------------------------------------------------------\n");
     703             :         } else {
     704           4 :                 add_section_to_json(state, "sessions");
     705             :         }
     706          12 :         return 0;
     707             : 
     708             : }
     709             : 
     710          12 : static int traverse_sessionid(const char *key, struct sessionid *session,
     711             :                               void *private_data)
     712             : {
     713             :         fstring uid_gid_str;
     714             :         fstring uid_str;
     715             :         fstring gid_str;
     716             :         struct server_id_buf tmp;
     717          12 :         char *machine_hostname = NULL;
     718          12 :         int result = 0;
     719          12 :         const char *encryption = "-";
     720          12 :         enum crypto_degree encryption_degree = CRYPTO_DEGREE_NONE;
     721          12 :         const char *signing = "-";
     722          12 :         enum crypto_degree signing_degree = CRYPTO_DEGREE_NONE;
     723          12 :         struct traverse_state *state = (struct traverse_state *)private_data;
     724             : 
     725          12 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     726          12 :         if (tmp_ctx == NULL) {
     727           0 :                 return -1;
     728             :         }
     729             : 
     730          12 :         if (do_checks &&
     731          24 :             (!process_exists(session->pid) ||
     732          12 :              !Ucrit_checkUid(session->uid))) {
     733           0 :                 TALLOC_FREE(tmp_ctx);
     734           0 :                 return 0;
     735             :         }
     736             : 
     737          12 :         Ucrit_addPid(session->pid);
     738             : 
     739          12 :         if (numeric_only) {
     740           0 :                 fstr_sprintf(gid_str, "%u", (unsigned int)session->gid);
     741           0 :                 fstr_sprintf(uid_str, "%u", (unsigned int)session->uid);
     742           0 :                 fstr_sprintf(uid_gid_str, "%-12u %-12u",
     743           0 :                              (unsigned int)session->uid,
     744           0 :                              (unsigned int)session->gid);
     745             :         } else {
     746          12 :                 if (session->uid == -1 && session->gid == -1) {
     747             :                         /*
     748             :                          * The session is not fully authenticated yet.
     749             :                          */
     750           0 :                         fstrcpy(uid_gid_str, "(auth in progress)");
     751           0 :                         fstrcpy(gid_str, "(auth in progress)");
     752           0 :                         fstrcpy(uid_str, "(auth in progress)");
     753             :                 } else {
     754             :                         /*
     755             :                          * In theory it should not happen that one of
     756             :                          * session->uid and session->gid is valid (ie != -1)
     757             :                          * while the other is not (ie = -1), so we a check for
     758             :                          * that case that bails out would be reasonable.
     759             :                          */
     760          12 :                         const char *uid_name = "-1";
     761          12 :                         const char *gid_name = "-1";
     762             : 
     763          12 :                         if (session->uid != -1) {
     764          12 :                                 uid_name = uidtoname(session->uid);
     765          12 :                                 if (uid_name == NULL) {
     766           0 :                                         TALLOC_FREE(tmp_ctx);
     767           0 :                                         return -1;
     768             :                                 }
     769             :                         }
     770          12 :                         if (session->gid != -1) {
     771          12 :                                 gid_name = gidtoname(session->gid);
     772          12 :                                 if (gid_name == NULL) {
     773           0 :                                         TALLOC_FREE(tmp_ctx);
     774           0 :                                         return -1;
     775             :                                 }
     776             :                         }
     777          12 :                         fstr_sprintf(gid_str, "%s", gid_name);
     778          12 :                         fstr_sprintf(uid_str, "%s", uid_name);
     779          12 :                         fstr_sprintf(uid_gid_str, "%-12s %-12s",
     780             :                                      uid_name, gid_name);
     781             :                 }
     782             :         }
     783             : 
     784          12 :         machine_hostname = talloc_asprintf(tmp_ctx, "%s (%s)",
     785          12 :                                            session->remote_machine,
     786          12 :                                            session->hostname);
     787          12 :         if (machine_hostname == NULL) {
     788           0 :                 TALLOC_FREE(tmp_ctx);
     789           0 :                 return -1;
     790             :         }
     791             : 
     792          24 :         if (smbXsrv_is_encrypted(session->encryption_flags) ||
     793          12 :                         smbXsrv_is_partially_encrypted(session->encryption_flags)) {
     794           0 :                 switch (session->cipher) {
     795           0 :                 case SMB2_ENCRYPTION_AES128_CCM:
     796           0 :                         encryption = "AES-128-CCM";
     797           0 :                         break;
     798           0 :                 case SMB2_ENCRYPTION_AES128_GCM:
     799           0 :                         encryption = "AES-128-GCM";
     800           0 :                         break;
     801           0 :                 case SMB2_ENCRYPTION_AES256_CCM:
     802           0 :                         encryption = "AES-256-CCM";
     803           0 :                         break;
     804           0 :                 case SMB2_ENCRYPTION_AES256_GCM:
     805           0 :                         encryption = "AES-256-GCM";
     806           0 :                         break;
     807           0 :                 default:
     808           0 :                         encryption = "???";
     809           0 :                         result = -1;
     810           0 :                         break;
     811             :                 }
     812           0 :                 if (smbXsrv_is_encrypted(session->encryption_flags)) {
     813           0 :                         encryption_degree = CRYPTO_DEGREE_FULL;
     814           0 :                 } else if (smbXsrv_is_partially_encrypted(session->encryption_flags)) {
     815           0 :                         encryption_degree = CRYPTO_DEGREE_PARTIAL;
     816             :                 }
     817           0 :                 if (encryption_degree != CRYPTO_DEGREE_NONE &&
     818           0 :                     !session->authenticated)
     819             :                 {
     820           0 :                         encryption_degree = CRYPTO_DEGREE_ANONYMOUS;
     821             :                 }
     822             :         }
     823             : 
     824          24 :         if (smbXsrv_is_signed(session->signing_flags) ||
     825          12 :                         smbXsrv_is_partially_signed(session->signing_flags)) {
     826          11 :                 switch (session->signing) {
     827           0 :                 case SMB2_SIGNING_MD5_SMB1:
     828           0 :                         signing = "HMAC-MD5";
     829           0 :                         break;
     830           0 :                 case SMB2_SIGNING_HMAC_SHA256:
     831           0 :                         signing = "HMAC-SHA256";
     832           0 :                         break;
     833           0 :                 case SMB2_SIGNING_AES128_CMAC:
     834           0 :                         signing = "AES-128-CMAC";
     835           0 :                         break;
     836          11 :                 case SMB2_SIGNING_AES128_GMAC:
     837          11 :                         signing = "AES-128-GMAC";
     838          11 :                         break;
     839           0 :                 default:
     840           0 :                         signing = "???";
     841           0 :                         result = -1;
     842           0 :                         break;
     843             :                 }
     844          11 :                 if (smbXsrv_is_signed(session->signing_flags)) {
     845           0 :                         signing_degree = CRYPTO_DEGREE_FULL;
     846          11 :                 } else if (smbXsrv_is_partially_signed(session->signing_flags)) {
     847          11 :                         signing_degree = CRYPTO_DEGREE_PARTIAL;
     848             :                 }
     849          11 :                 if (signing_degree != CRYPTO_DEGREE_NONE &&
     850          11 :                     !session->authenticated)
     851             :                 {
     852           0 :                         signing_degree = CRYPTO_DEGREE_ANONYMOUS;
     853             :                 }
     854             :         }
     855             : 
     856             : 
     857          12 :         if (!state->json_output) {
     858           8 :                 traverse_sessionid_stdout(state,
     859             :                          server_id_str_buf(session->pid, &tmp),
     860             :                          uid_gid_str,
     861             :                          machine_hostname,
     862           8 :                          session_dialect_str(session->connection_dialect),
     863             :                          encryption,
     864             :                          encryption_degree,
     865             :                          signing,
     866             :                          signing_degree);
     867             :         } else {
     868           4 :                 result = traverse_sessionid_json(state,
     869             :                                                  session,
     870             :                                                  uid_str,
     871             :                                                  gid_str,
     872             :                                                  encryption,
     873             :                                                  encryption_degree,
     874             :                                                  signing,
     875             :                                                  signing_degree,
     876           4 :                                                  session_dialect_str(session->connection_dialect));
     877             :         }
     878             : 
     879          12 :         TALLOC_FREE(machine_hostname);
     880          12 :         TALLOC_FREE(tmp_ctx);
     881             : 
     882          12 :         return result;
     883             : }
     884             : 
     885             : 
     886           0 : static bool print_notify_rec_stdout(struct traverse_state *state,
     887             :                                     const char *path,
     888             :                                     char *server_id_str,
     889             :                                     unsigned filter,
     890             :                                     unsigned subdir_filter)
     891             : {
     892           0 :         d_printf("%s\\%s\\%x\\%x\n", path, server_id_str,
     893             :                  filter, subdir_filter);
     894             : 
     895           0 :         return true;
     896             : }
     897             : 
     898           2 : static int prepare_notify(struct traverse_state *state)
     899             : {
     900           2 :         if (!state->json_output) {
     901             :                 /* don't print header line */
     902             :         } else {
     903           2 :                 add_section_to_json(state, "notifies");
     904             :         }
     905           2 :         return 0;
     906             : }
     907             : 
     908           0 : static bool print_notify_rec(const char *path, struct server_id server,
     909             :                              const struct notify_instance *instance,
     910             :                              void *private_data)
     911             : {
     912             :         struct server_id_buf idbuf;
     913           0 :         struct traverse_state *state = (struct traverse_state *)private_data;
     914             :         bool result;
     915             : 
     916           0 :         if (!state->json_output) {
     917           0 :                 result = print_notify_rec_stdout(state,
     918             :                                                  path,
     919             :                                                  server_id_str_buf(server, &idbuf),
     920           0 :                                                  (unsigned)instance->filter,
     921           0 :                                                  (unsigned)instance->subdir_filter);
     922             : 
     923             :         } else {
     924           0 :                 result = print_notify_rec_json(state,
     925             :                                                instance,
     926             :                                                server,
     927             :                                                path);
     928             :         }
     929             : 
     930           0 :         return result;
     931             : }
     932             : 
     933             : enum {
     934             :         OPT_RESOLVE_UIDS = 1000,
     935             : };
     936             : 
     937          18 : int main(int argc, const char *argv[])
     938             : {
     939             :         int c;
     940          18 :         int profile_only = 0;
     941             :         bool show_processes, show_locks, show_shares;
     942          18 :         bool show_notify = false;
     943          18 :         poptContext pc = NULL;
     944          18 :         struct traverse_state state = {0};
     945          54 :         struct poptOption long_options[] = {
     946             :                 POPT_AUTOHELP
     947             :                 {
     948             :                         .longName   = "processes",
     949             :                         .shortName  = 'p',
     950             :                         .argInfo    = POPT_ARG_NONE,
     951             :                         .arg        = NULL,
     952             :                         .val        = 'p',
     953             :                         .descrip    = "Show processes only",
     954             :                 },
     955             :                 {
     956             :                         .longName   = "verbose",
     957             :                         .shortName  = 'v',
     958             :                         .argInfo    = POPT_ARG_NONE,
     959             :                         .arg        = NULL,
     960             :                         .val        = 'v',
     961             :                         .descrip    = "Be verbose",
     962             :                 },
     963             :                 {
     964             :                         .longName   = "locks",
     965             :                         .shortName  = 'L',
     966             :                         .argInfo    = POPT_ARG_NONE,
     967             :                         .arg        = NULL,
     968             :                         .val        = 'L',
     969             :                         .descrip    = "Show locks only",
     970             :                 },
     971             :                 {
     972             :                         .longName   = "shares",
     973             :                         .shortName  = 'S',
     974             :                         .argInfo    = POPT_ARG_NONE,
     975             :                         .arg        = NULL,
     976             :                         .val        = 'S',
     977             :                         .descrip    = "Show shares only",
     978             :                 },
     979             :                 {
     980             :                         .longName   = "notify",
     981             :                         .shortName  = 'N',
     982             :                         .argInfo    = POPT_ARG_NONE,
     983             :                         .arg        = NULL,
     984             :                         .val        = 'N',
     985             :                         .descrip    = "Show notifies",
     986             :                 },
     987             :                 {
     988             :                         .longName   = "user",
     989             :                         .shortName  = 'u',
     990             :                         .argInfo    = POPT_ARG_STRING,
     991             :                         .arg        = &username,
     992             :                         .val        = 'u',
     993             :                         .descrip    = "Switch to user",
     994             :                 },
     995             :                 {
     996             :                         .longName   = "brief",
     997             :                         .shortName  = 'b',
     998             :                         .argInfo    = POPT_ARG_NONE,
     999             :                         .arg        = NULL,
    1000             :                         .val        = 'b',
    1001             :                         .descrip    = "Be brief",
    1002             :                 },
    1003             :                 {
    1004             :                         .longName   = "profile",
    1005             :                         .shortName  =     'P',
    1006             :                         .argInfo    = POPT_ARG_NONE,
    1007             :                         .arg        = NULL,
    1008             :                         .val        = 'P',
    1009             :                         .descrip    = "Do profiling",
    1010             :                 },
    1011             :                 {
    1012             :                         .longName   = "profile-rates",
    1013             :                         .shortName  = 'R',
    1014             :                         .argInfo    = POPT_ARG_NONE,
    1015             :                         .arg        = NULL,
    1016             :                         .val        = 'R',
    1017             :                         .descrip    = "Show call rates",
    1018             :                 },
    1019             :                 {
    1020             :                         .longName   = "byterange",
    1021             :                         .shortName  = 'B',
    1022             :                         .argInfo    = POPT_ARG_NONE,
    1023             :                         .arg        = NULL,
    1024             :                         .val        = 'B',
    1025             :                         .descrip    = "Include byte range locks"
    1026             :                 },
    1027             :                 {
    1028             :                         .longName   = "numeric",
    1029             :                         .shortName  = 'n',
    1030             :                         .argInfo    = POPT_ARG_NONE,
    1031             :                         .arg        = NULL,
    1032             :                         .val        = 'n',
    1033             :                         .descrip    = "Numeric uid/gid"
    1034             :                 },
    1035             :                 {
    1036             :                         .longName   = "json",
    1037             :                         .shortName  = 'j',
    1038             :                         .argInfo    = POPT_ARG_NONE,
    1039             :                         .arg        = NULL,
    1040             :                         .val        = 'j',
    1041             :                         .descrip    = "JSON output"
    1042             :                 },
    1043             :                 {
    1044             :                         .longName   = "fast",
    1045             :                         .shortName  = 'f',
    1046             :                         .argInfo    = POPT_ARG_NONE,
    1047             :                         .arg        = NULL,
    1048             :                         .val        = 'f',
    1049             :                         .descrip    = "Skip checks if processes still exist"
    1050             :                 },
    1051             :                 {
    1052             :                         .longName   = "resolve-uids",
    1053             :                         .shortName  = 0,
    1054             :                         .argInfo    = POPT_ARG_NONE,
    1055             :                         .arg        = NULL,
    1056             :                         .val        = OPT_RESOLVE_UIDS,
    1057             :                         .descrip    = "Try to resolve UIDs to usernames"
    1058             :                 },
    1059          18 :                 POPT_COMMON_SAMBA
    1060          18 :                 POPT_COMMON_VERSION
    1061             :                 POPT_TABLEEND
    1062             :         };
    1063          18 :         TALLOC_CTX *frame = talloc_stackframe();
    1064          18 :         int ret = 0;
    1065          18 :         struct messaging_context *msg_ctx = NULL;
    1066             :         char *db_path;
    1067             :         bool ok;
    1068          18 :         struct loadparm_context *lp_ctx = NULL;
    1069             : 
    1070          18 :         state.first = true;
    1071          18 :         state.json_output = false;
    1072          18 :         state.resolve_uids = false;
    1073             : 
    1074          18 :         smb_init_locale();
    1075             : 
    1076          18 :         ok = samba_cmdline_init(frame,
    1077             :                                 SAMBA_CMDLINE_CONFIG_CLIENT,
    1078             :                                 false /* require_smbconf */);
    1079          18 :         if (!ok) {
    1080           0 :                 DBG_ERR("Failed to init cmdline parser!\n");
    1081           0 :                 TALLOC_FREE(frame);
    1082           0 :                 exit(1);
    1083             :         }
    1084          18 :         lp_ctx = samba_cmdline_get_lp_ctx();
    1085          18 :         lpcfg_set_cmdline(lp_ctx, "log level", "0");
    1086             : 
    1087          18 :         pc = samba_popt_get_context(getprogname(),
    1088             :                                     argc,
    1089             :                                     argv,
    1090             :                                     long_options,
    1091             :                                     POPT_CONTEXT_KEEP_FIRST);
    1092          18 :         if (pc == NULL) {
    1093           0 :                 DBG_ERR("Failed to setup popt context!\n");
    1094           0 :                 TALLOC_FREE(frame);
    1095           0 :                 exit(1);
    1096             :         }
    1097             : 
    1098          40 :         while ((c = poptGetNextOpt(pc)) != -1) {
    1099          22 :                 switch (c) {
    1100           4 :                 case 'p':
    1101           4 :                         processes_only = true;
    1102           4 :                         break;
    1103           2 :                 case 'v':
    1104           2 :                         verbose = true;
    1105           2 :                         break;
    1106           2 :                 case 'L':
    1107           2 :                         locks_only = true;
    1108           2 :                         break;
    1109           2 :                 case 'S':
    1110           2 :                         shares_only = true;
    1111           2 :                         break;
    1112           2 :                 case 'N':
    1113           2 :                         show_notify = true;
    1114           2 :                         break;
    1115           0 :                 case 'b':
    1116           0 :                         brief = true;
    1117           0 :                         break;
    1118           0 :                 case 'u':
    1119           0 :                         Ucrit_addUid(nametouid(poptGetOptArg(pc)));
    1120           0 :                         break;
    1121           2 :                 case 'P':
    1122             :                 case 'R':
    1123           2 :                         profile_only = c;
    1124           2 :                         break;
    1125           2 :                 case 'B':
    1126           2 :                         show_brl = true;
    1127           2 :                         break;
    1128           0 :                 case 'n':
    1129           0 :                         numeric_only = true;
    1130           0 :                         break;
    1131           6 :                 case 'j':
    1132           6 :                         state.json_output = true;
    1133           6 :                         break;
    1134           0 :                 case 'f':
    1135           0 :                         do_checks = false;
    1136           0 :                         break;
    1137           0 :                 case OPT_RESOLVE_UIDS:
    1138           0 :                         state.resolve_uids = true;
    1139           0 :                         break;
    1140           0 :                 case POPT_ERROR_BADOPT:
    1141           0 :                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
    1142             :                                 poptBadOption(pc, 0), poptStrerror(c));
    1143           0 :                         poptPrintUsage(pc, stderr, 0);
    1144           0 :                         exit(1);
    1145             :                 }
    1146             :         }
    1147             : 
    1148          18 :         sec_init();
    1149             : 
    1150             : #ifdef HAVE_JANSSON
    1151          18 :         state.root_json = json_new_object();
    1152          18 :         if (!json_is_invalid(&state.root_json)) {
    1153          18 :                 add_general_information_to_json(&state);
    1154             :         }
    1155             : #else /* HAVE_JANSSON */
    1156             :         if (state.json_output) {
    1157             :                 fprintf(stderr, "JSON support not available, please install lib Jansson\n");
    1158             :                 goto done;
    1159             :         }
    1160             : #endif /* HAVE_JANSSON */
    1161             : 
    1162          18 :         if (getuid() != geteuid()) {
    1163           0 :                 fprintf(stderr, "smbstatus should not be run setuid\n");
    1164           0 :                 ret = 1;
    1165           0 :                 goto done;
    1166             :         }
    1167             : 
    1168          18 :         if (getuid() != 0) {
    1169           0 :                 fprintf(stderr, "smbstatus only works as root!\n");
    1170           0 :                 ret = 1;
    1171           0 :                 goto done;
    1172             :         }
    1173             : 
    1174             :         /* setup the flags based on the possible combincations */
    1175             : 
    1176          18 :         show_processes = !(shares_only || locks_only || profile_only) || processes_only;
    1177          18 :         show_locks     = !(shares_only || processes_only || profile_only) || locks_only;
    1178          18 :         show_shares    = !(processes_only || locks_only || profile_only) || shares_only;
    1179             : 
    1180          18 :         if ( username )
    1181           0 :                 Ucrit_addUid( nametouid(username) );
    1182             : 
    1183          18 :         if (verbose && !state.json_output) {
    1184           0 :                 d_printf("using configfile = %s\n", get_dyn_CONFIGFILE());
    1185             :         }
    1186             : 
    1187          18 :         msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE());
    1188          18 :         if (msg_ctx == NULL) {
    1189           0 :                 fprintf(stderr, "Could not initialize messaging, not root?\n");
    1190           0 :                 ret = -1;
    1191           0 :                 goto done;
    1192             :         }
    1193             : 
    1194          18 :         switch (profile_only) {
    1195           2 :                 case 'P':
    1196             :                         /* Dump profile data */
    1197           2 :                         ok = status_profile_dump(verbose, &state);
    1198           2 :                         ret = ok ? 0 : 1;
    1199           2 :                         goto done;
    1200           0 :                 case 'R':
    1201             :                         /* Continuously display rate-converted data */
    1202           0 :                         if (!state.json_output) {
    1203           0 :                                 ok = status_profile_rates(verbose);
    1204           0 :                                 ret = ok ? 0 : 1;
    1205             :                         } else {
    1206           0 :                                 fprintf(stderr, "Call rates not available in a json output.\n");
    1207           0 :                                 ret = 1;
    1208             :                         }
    1209           0 :                         goto done;
    1210          16 :                 default:
    1211          16 :                         break;
    1212             :         }
    1213             : 
    1214          16 :         if ( show_processes ) {
    1215          12 :                 prepare_sessionid(&state);
    1216          12 :                 sessionid_traverse_read(traverse_sessionid, &state);
    1217             : 
    1218          12 :                 if (processes_only) {
    1219           4 :                         goto done;
    1220             :                 }
    1221             :         }
    1222             : 
    1223          12 :         if ( show_shares ) {
    1224          10 :                 if (brief) {
    1225           0 :                         goto done;
    1226             :                 }
    1227          10 :                 prepare_connections(&state);
    1228          10 :                 connections_forall_read(traverse_connections, &state);
    1229             : 
    1230          10 :                 if (!state.json_output) {
    1231           6 :                         d_printf("\n");
    1232             :                 }
    1233             : 
    1234          10 :                 if ( shares_only ) {
    1235           2 :                         goto done;
    1236             :                 }
    1237             :         }
    1238             : 
    1239          10 :         if ( show_locks ) {
    1240             :                 int result;
    1241             :                 struct db_context *db;
    1242             : 
    1243          10 :                 db_path = lock_path(talloc_tos(), "locking.tdb");
    1244          10 :                 if (db_path == NULL) {
    1245           0 :                         fprintf(stderr, "Out of memory - exiting\n");
    1246           0 :                         ret = -1;
    1247           0 :                         goto done;
    1248             :                 }
    1249             : 
    1250          10 :                 db = db_open(NULL, db_path, 0,
    1251             :                              TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, O_RDONLY, 0,
    1252             :                              DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
    1253             : 
    1254          10 :                 if (!db) {
    1255           0 :                         fprintf(stderr, "%s not initialised\n", db_path);
    1256           0 :                         fprintf(stderr, "This is normal if an SMB client has never "
    1257             :                                  "connected to your server.\n");
    1258           0 :                         TALLOC_FREE(db_path);
    1259           0 :                         ret = 0;
    1260           0 :                         goto done;
    1261             :                 } else {
    1262          10 :                         TALLOC_FREE(db);
    1263          10 :                         TALLOC_FREE(db_path);
    1264             :                 }
    1265             : 
    1266          10 :                 if (!locking_init_readonly()) {
    1267           0 :                         fprintf(stderr, "Can't initialise locking module - exiting\n");
    1268           0 :                         ret = 1;
    1269           0 :                         goto done;
    1270             :                 }
    1271             : 
    1272          10 :                 prepare_share_mode(&state);
    1273          10 :                 result = share_entry_forall(print_share_mode, &state);
    1274             : 
    1275          10 :                 if (result == 0 && !state.json_output) {
    1276           0 :                         fprintf(stderr, "No locked files\n");
    1277          10 :                 } else if (result < 0 && !state.json_output) {
    1278           0 :                         fprintf(stderr, "locked file list truncated\n");
    1279             :                 }
    1280             : 
    1281          10 :                 if (!state.json_output) {
    1282           6 :                         d_printf("\n");
    1283             :                 }
    1284             : 
    1285          10 :                 if (show_brl) {
    1286           2 :                         prepare_brl(&state);
    1287           2 :                         brl_forall(print_brl, &state);
    1288             :                 }
    1289             : 
    1290          10 :                 locking_end();
    1291             :         }
    1292             : 
    1293          10 :         if (show_notify) {
    1294           2 :                 prepare_notify(&state);
    1295           2 :                 notify_walk(msg_ctx, print_notify_rec, &state);
    1296             :         }
    1297             : 
    1298           8 : done:
    1299          18 :         cmdline_messaging_context_free();
    1300          18 :         poptFreeContext(pc);
    1301             : #ifdef HAVE_JANSSON
    1302          18 :         if (state.json_output) {
    1303           6 :                 d_printf("%s\n", json_to_string(frame, &state.root_json));
    1304             :         }
    1305          18 :         json_free(&state.root_json);
    1306             : #endif /* HAVE_JANSSON */
    1307          18 :         TALLOC_FREE(frame);
    1308          18 :         return ret;
    1309             : }

Generated by: LCOV version 1.14