LCOV - code coverage report
Current view: top level - source3/utils - status.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 295 577 51.1 %
Date: 2024-02-28 12:06:22 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          33 : static unsigned int Ucrit_checkUid(uid_t uid)
      89             : {
      90          33 :         if ( !Ucrit_IsActive )
      91          33 :                 return 1;
      92             : 
      93           0 :         if ( uid == Ucrit_uid )
      94           0 :                 return 1;
      95             : 
      96           0 :         return 0;
      97             : }
      98             : 
      99          15 : static unsigned int Ucrit_checkPid(struct server_id pid)
     100             : {
     101             :         int i;
     102             : 
     103          15 :         if ( !Ucrit_IsActive )
     104          15 :                 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          18 : static bool Ucrit_addPid( struct server_id pid )
     116             : {
     117          18 :         if ( !Ucrit_IsActive )
     118          18 :                 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           9 : 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           9 :         if (state->first) {
     144           9 :                 d_printf("\nLocked files:\n");
     145           9 :                 d_printf("Pid          User(ID)   DenyMode   Access      R/W        Oplock           SharePath   Name   Time\n");
     146           9 :                 d_printf("--------------------------------------------------------------------------------------------------\n");
     147             : 
     148           9 :                 state->first = false;
     149             :         }
     150             : 
     151           9 :         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           9 :         return 0;
     155             : }
     156             : 
     157          15 : static int prepare_share_mode(struct traverse_state *state)
     158             : {
     159          15 :         if (!state->json_output) {
     160             :                 /* only print header line if there are open files */
     161           9 :                 state->first = true;
     162             :         } else {
     163           6 :                 add_section_to_json(state, "open_files");
     164             :         }
     165          15 :         return 0;
     166             : }
     167             : 
     168          15 : static uint32_t map_share_mode_to_deny_mode(
     169             :         uint32_t share_access, uint32_t private_options)
     170             : {
     171          15 :         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          15 :         case FILE_SHARE_READ|FILE_SHARE_WRITE:
     179          15 :                 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          15 : 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          15 :         const char *denymode = NULL;
     196             :         uint denymode_int;
     197          15 :         const char *oplock = NULL;
     198          15 :         const char *pid = NULL;
     199          15 :         const char *rw = NULL;
     200          15 :         const char *filename = NULL;
     201          15 :         const char *timestr = NULL;
     202          15 :         const char *user_str = NULL;
     203             :         uint32_t lstate;
     204          15 :         struct traverse_state *state = (struct traverse_state *)private_data;
     205             : 
     206          15 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     207          15 :         if (tmp_ctx == NULL) {
     208           0 :                 return -1;
     209             :         }
     210             : 
     211          15 :         if (do_checks && !is_valid_share_mode_entry(e)) {
     212           0 :                 TALLOC_FREE(tmp_ctx);
     213           0 :                 return 0;
     214             :         }
     215             : 
     216          15 :         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          15 :         if (Ucrit_checkPid(e->pid)) {
     223             :                 struct server_id_buf tmp;
     224          15 :                 pid = server_id_str_buf(e->pid, &tmp);
     225          15 :                 if (state->resolve_uids) {
     226           0 :                         user_str = talloc_asprintf(tmp_ctx, "%s", uidtoname(e->uid));
     227             :                 } else {
     228          15 :                         user_str = talloc_asprintf(tmp_ctx, "%u", (unsigned int)e->uid);
     229             :                 }
     230          15 :                 if (user_str == NULL) {
     231           0 :                         TALLOC_FREE(tmp_ctx);
     232           0 :                         return -1;
     233             :                 }
     234             : 
     235          15 :                 denymode_int = map_share_mode_to_deny_mode(e->share_access,
     236          15 :                                                            e->private_options);
     237          15 :                 switch (denymode_int) {
     238          15 :                         case DENY_NONE:
     239          15 :                                 denymode = "DENY_NONE";
     240          15 :                                 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          15 :                 filename = talloc_asprintf(tmp_ctx,
     274             :                                            "%s%s",
     275          15 :                                            d->base_name,
     276          15 :                                            (d->stream_name != NULL) ? d->stream_name : "");
     277          15 :                 if (filename == NULL) {
     278           0 :                         TALLOC_FREE(tmp_ctx);
     279           0 :                         return -1;
     280             :                 }
     281          15 :                 if ((e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA))==
     282             :                                 (FILE_READ_DATA|FILE_WRITE_DATA)) {
     283          15 :                         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          15 :                 if (e->op_type & BATCH_OPLOCK) {
     291           0 :                         oplock = "BATCH";
     292          15 :                 } else if (e->op_type & EXCLUSIVE_OPLOCK) {
     293           0 :                         oplock = "EXCLUSIVE";
     294          15 :                 } else if (e->op_type & LEVEL_II_OPLOCK) {
     295           0 :                         oplock = "LEVEL_II";
     296          15 :                 } 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          15 :                         oplock = "NONE";
     323             :                 }
     324             : 
     325          15 :                 timestr = time_to_asc((time_t)e->time.tv_sec);
     326             : 
     327          15 :                 if (!state->json_output) {
     328           9 :                         print_share_mode_stdout(state,
     329             :                                                 pid,
     330             :                                                 user_str,
     331             :                                                 denymode,
     332           9 :                                                 (unsigned int)e->access_mask,
     333             :                                                 rw,
     334             :                                                 oplock,
     335           9 :                                                 d->servicepath,
     336             :                                                 filename,
     337             :                                                 timestr);
     338             :                 } else {
     339           6 :                         print_share_mode_json(state,
     340             :                                               d,
     341             :                                               e,
     342             :                                               fid,
     343             :                                               user_str,
     344             :                                               oplock,
     345             :                                               lstate,
     346             :                                               filename);
     347             :                 }
     348             :         }
     349          15 :         TALLOC_FREE(tmp_ctx);
     350          15 :         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           3 : static int prepare_brl(struct traverse_state *state)
     374             : {
     375           3 :         if (!state->json_output) {
     376             :                 /* only print header line if there are locked files */
     377           0 :                 state->first = true;
     378             :         } else {
     379           3 :                 add_section_to_json(state, "byte_range_locks");
     380             :         }
     381           3 :         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          18 : static const char *session_dialect_str(uint16_t dialect)
     453             : {
     454             :         static fstring unknown_dialect;
     455             : 
     456          18 :         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          18 :         case SMB3_DIALECT_REVISION_311:
     474          18 :                 return "SMB3_11";
     475             :         }
     476             : 
     477           0 :         fstr_sprintf(unknown_dialect, "Unknown (0x%04x)", dialect);
     478           0 :         return unknown_dialect;
     479             : }
     480             : 
     481           9 : 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,
     487             :                                        const char *signing)
     488             : {
     489           9 :         d_printf("%-12s %-7s %-13s %-32s %-12s %-12s\n",
     490             :                  servicename, server_id, machine, timestr, encryption, signing);
     491             : 
     492           9 :         return 0;
     493             : }
     494             : 
     495          15 : static int prepare_connections(struct traverse_state *state)
     496             : {
     497          15 :         if (!state->json_output) {
     498             :                 /* always print header line */
     499           9 :                 d_printf("\n%-12s %-7s %-13s %-32s %-12s %-12s\n", "Service", "pid", "Machine", "Connected at", "Encryption", "Signing");
     500           9 :                 d_printf("---------------------------------------------------------------------------------------------\n");
     501             :         } else {
     502           6 :                 add_section_to_json(state, "tcons");
     503             :         }
     504          15 :         return 0;
     505             : }
     506             : 
     507          15 : static int traverse_connections(const struct connections_data *crec,
     508             :                                 void *private_data)
     509             : {
     510             :         struct server_id_buf tmp;
     511          15 :         char *timestr = NULL;
     512          15 :         int result = 0;
     513          15 :         const char *encryption = "-";
     514          15 :         enum crypto_degree encryption_degree = CRYPTO_DEGREE_NONE;
     515          15 :         const char *signing = "-";
     516          15 :         enum crypto_degree signing_degree = CRYPTO_DEGREE_NONE;
     517          15 :         struct traverse_state *state = (struct traverse_state *)private_data;
     518             : 
     519          15 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     520          15 :         if (tmp_ctx == NULL) {
     521           0 :                 return -1;
     522             :         }
     523             : 
     524          15 :         if (crec->cnum == TID_FIELD_INVALID) {
     525           0 :                 TALLOC_FREE(tmp_ctx);
     526           0 :                 return 0;
     527             :         }
     528             : 
     529          15 :         if (do_checks &&
     530          15 :             (!process_exists(crec->pid) || !Ucrit_checkUid(crec->uid))) {
     531           0 :                 TALLOC_FREE(tmp_ctx);
     532           0 :                 return 0;
     533             :         }
     534             : 
     535          15 :         timestr = timestring(tmp_ctx, nt_time_to_unix(crec->start));
     536          15 :         if (timestr == NULL) {
     537           0 :                 TALLOC_FREE(tmp_ctx);
     538           0 :                 return -1;
     539             :         }
     540             : 
     541          15 :         if (smbXsrv_is_encrypted(crec->encryption_flags)) {
     542           0 :                 switch (crec->cipher) {
     543           0 :                 case SMB_ENCRYPTION_GSSAPI:
     544           0 :                         encryption = "GSSAPI";
     545           0 :                         break;
     546           0 :                 case SMB2_ENCRYPTION_AES128_CCM:
     547           0 :                         encryption = "AES-128-CCM";
     548           0 :                         break;
     549           0 :                 case SMB2_ENCRYPTION_AES128_GCM:
     550           0 :                         encryption = "AES-128-GCM";
     551           0 :                         break;
     552           0 :                 default:
     553           0 :                         encryption = "???";
     554           0 :                         break;
     555             :                 }
     556           0 :                 encryption_degree = CRYPTO_DEGREE_FULL;
     557             :         }
     558             : 
     559          15 :         if (smbXsrv_is_signed(crec->signing_flags)) {
     560           0 :                 switch (crec->signing) {
     561           0 :                 case SMB2_SIGNING_MD5_SMB1:
     562           0 :                         signing = "HMAC-MD5";
     563           0 :                         break;
     564           0 :                 case SMB2_SIGNING_HMAC_SHA256:
     565           0 :                         signing = "HMAC-SHA256";
     566           0 :                         break;
     567           0 :                 case SMB2_SIGNING_AES128_CMAC:
     568           0 :                         signing = "AES-128-CMAC";
     569           0 :                         break;
     570           0 :                 case SMB2_SIGNING_AES128_GMAC:
     571           0 :                         signing = "AES-128-GMAC";
     572           0 :                         break;
     573           0 :                 default:
     574           0 :                         signing = "???";
     575           0 :                         break;
     576             :                 }
     577           0 :                 signing_degree = CRYPTO_DEGREE_FULL;
     578             :         }
     579             : 
     580          15 :         if (!state->json_output) {
     581          18 :                 result = traverse_connections_stdout(state,
     582           9 :                                                      crec->servicename,
     583             :                                                      server_id_str_buf(crec->pid, &tmp),
     584           9 :                                                      crec->machine,
     585             :                                                      timestr,
     586             :                                                      encryption,
     587             :                                                      signing);
     588             :         } else {
     589           6 :                 result = traverse_connections_json(state,
     590             :                                                    crec,
     591             :                                                    encryption,
     592             :                                                    encryption_degree,
     593             :                                                    signing,
     594             :                                                    signing_degree);
     595             :         }
     596             : 
     597          15 :         TALLOC_FREE(timestr);
     598          15 :         TALLOC_FREE(tmp_ctx);
     599             : 
     600          15 :         return result;
     601             : }
     602             : 
     603          12 : static int traverse_sessionid_stdout(struct traverse_state *state,
     604             :                                      char *server_id,
     605             :                                      char *uid_gid_str,
     606             :                                      char *machine_hostname,
     607             :                                      const char *dialect,
     608             :                                      const char *encryption_cipher,
     609             :                                      enum crypto_degree encryption_degree,
     610             :                                      const char *signing_cipher,
     611             :                                      enum crypto_degree signing_degree)
     612             : {
     613             :         fstring encryption;
     614             :         fstring signing;
     615             : 
     616          12 :         if (encryption_degree == CRYPTO_DEGREE_FULL) {
     617           0 :                 fstr_sprintf(encryption, "%s", encryption_cipher);
     618          12 :         } else if (encryption_degree == CRYPTO_DEGREE_PARTIAL) {
     619           0 :                 fstr_sprintf(encryption, "partial(%s)", encryption_cipher);
     620             :         } else {
     621          12 :                 fstr_sprintf(encryption, "-");
     622             :         }
     623          12 :         if (signing_degree == CRYPTO_DEGREE_FULL) {
     624           0 :                 fstr_sprintf(signing, "%s", signing_cipher);
     625          12 :         } else if (signing_degree == CRYPTO_DEGREE_PARTIAL) {
     626           9 :                 fstr_sprintf(signing, "partial(%s)", signing_cipher);
     627             :         } else {
     628           3 :                 fstr_sprintf(signing, "-");
     629             :         }
     630             : 
     631          12 :         d_printf("%-7s %-25s %-41s %-17s %-20s %-21s\n",
     632             :                  server_id, uid_gid_str, machine_hostname, dialect, encryption,
     633             :                  signing);
     634             : 
     635          12 :         return 0;
     636             : }
     637             : 
     638          18 : static int prepare_sessionid(struct traverse_state *state)
     639             : {
     640          18 :         if (!state->json_output) {
     641             :                 /* always print header line */
     642          12 :                 d_printf("\nSamba version %s\n",samba_version_string());
     643          12 :                 d_printf("%-7s %-12s %-12s %-41s %-17s %-20s %-21s\n", "PID", "Username", "Group", "Machine", "Protocol Version", "Encryption", "Signing");
     644          12 :                 d_printf("----------------------------------------------------------------------------------------------------------------------------------------\n");
     645             :         } else {
     646           6 :                 add_section_to_json(state, "sessions");
     647             :         }
     648          18 :         return 0;
     649             : 
     650             : }
     651             : 
     652          18 : static int traverse_sessionid(const char *key, struct sessionid *session,
     653             :                               void *private_data)
     654             : {
     655             :         fstring uid_gid_str;
     656             :         fstring uid_str;
     657             :         fstring gid_str;
     658             :         struct server_id_buf tmp;
     659          18 :         char *machine_hostname = NULL;
     660          18 :         int result = 0;
     661          18 :         const char *encryption = "-";
     662          18 :         enum crypto_degree encryption_degree = CRYPTO_DEGREE_NONE;
     663          18 :         const char *signing = "-";
     664          18 :         enum crypto_degree signing_degree = CRYPTO_DEGREE_NONE;
     665          18 :         struct traverse_state *state = (struct traverse_state *)private_data;
     666             : 
     667          18 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     668          18 :         if (tmp_ctx == NULL) {
     669           0 :                 return -1;
     670             :         }
     671             : 
     672          18 :         if (do_checks &&
     673          36 :             (!process_exists(session->pid) ||
     674          18 :              !Ucrit_checkUid(session->uid))) {
     675           0 :                 TALLOC_FREE(tmp_ctx);
     676           0 :                 return 0;
     677             :         }
     678             : 
     679          18 :         Ucrit_addPid(session->pid);
     680             : 
     681          18 :         if (numeric_only) {
     682           0 :                 fstr_sprintf(gid_str, "%u", (unsigned int)session->gid);
     683           0 :                 fstr_sprintf(uid_str, "%u", (unsigned int)session->uid);
     684           0 :                 fstr_sprintf(uid_gid_str, "%-12u %-12u",
     685           0 :                              (unsigned int)session->uid,
     686           0 :                              (unsigned int)session->gid);
     687             :         } else {
     688          18 :                 if (session->uid == -1 && session->gid == -1) {
     689             :                         /*
     690             :                          * The session is not fully authenticated yet.
     691             :                          */
     692           3 :                         fstrcpy(uid_gid_str, "(auth in progress)");
     693           3 :                         fstrcpy(gid_str, "(auth in progress)");
     694           3 :                         fstrcpy(uid_str, "(auth in progress)");
     695             :                 } else {
     696             :                         /*
     697             :                          * In theory it should not happen that one of
     698             :                          * session->uid and session->gid is valid (ie != -1)
     699             :                          * while the other is not (ie = -1), so we a check for
     700             :                          * that case that bails out would be reasonable.
     701             :                          */
     702          15 :                         const char *uid_name = "-1";
     703          15 :                         const char *gid_name = "-1";
     704             : 
     705          15 :                         if (session->uid != -1) {
     706          15 :                                 uid_name = uidtoname(session->uid);
     707          15 :                                 if (uid_name == NULL) {
     708           0 :                                         TALLOC_FREE(tmp_ctx);
     709           0 :                                         return -1;
     710             :                                 }
     711             :                         }
     712          15 :                         if (session->gid != -1) {
     713          15 :                                 gid_name = gidtoname(session->gid);
     714          15 :                                 if (gid_name == NULL) {
     715           0 :                                         TALLOC_FREE(tmp_ctx);
     716           0 :                                         return -1;
     717             :                                 }
     718             :                         }
     719          15 :                         fstr_sprintf(gid_str, "%s", gid_name);
     720          15 :                         fstr_sprintf(uid_str, "%s", uid_name);
     721          15 :                         fstr_sprintf(uid_gid_str, "%-12s %-12s",
     722             :                                      uid_name, gid_name);
     723             :                 }
     724             :         }
     725             : 
     726          18 :         machine_hostname = talloc_asprintf(tmp_ctx, "%s (%s)",
     727          18 :                                            session->remote_machine,
     728          18 :                                            session->hostname);
     729          18 :         if (machine_hostname == NULL) {
     730           0 :                 TALLOC_FREE(tmp_ctx);
     731           0 :                 return -1;
     732             :         }
     733             : 
     734          36 :         if (smbXsrv_is_encrypted(session->encryption_flags) ||
     735          18 :                         smbXsrv_is_partially_encrypted(session->encryption_flags)) {
     736           0 :                 switch (session->cipher) {
     737           0 :                 case SMB2_ENCRYPTION_AES128_CCM:
     738           0 :                         encryption = "AES-128-CCM";
     739           0 :                         break;
     740           0 :                 case SMB2_ENCRYPTION_AES128_GCM:
     741           0 :                         encryption = "AES-128-GCM";
     742           0 :                         break;
     743           0 :                 case SMB2_ENCRYPTION_AES256_CCM:
     744           0 :                         encryption = "AES-256-CCM";
     745           0 :                         break;
     746           0 :                 case SMB2_ENCRYPTION_AES256_GCM:
     747           0 :                         encryption = "AES-256-GCM";
     748           0 :                         break;
     749           0 :                 default:
     750           0 :                         encryption = "???";
     751           0 :                         result = -1;
     752           0 :                         break;
     753             :                 }
     754           0 :                 if (smbXsrv_is_encrypted(session->encryption_flags)) {
     755           0 :                         encryption_degree = CRYPTO_DEGREE_FULL;
     756           0 :                 } else if (smbXsrv_is_partially_encrypted(session->encryption_flags)) {
     757           0 :                         encryption_degree = CRYPTO_DEGREE_PARTIAL;
     758             :                 }
     759             :         }
     760             : 
     761          36 :         if (smbXsrv_is_signed(session->signing_flags) ||
     762          18 :                         smbXsrv_is_partially_signed(session->signing_flags)) {
     763          15 :                 switch (session->signing) {
     764           0 :                 case SMB2_SIGNING_MD5_SMB1:
     765           0 :                         signing = "HMAC-MD5";
     766           0 :                         break;
     767           0 :                 case SMB2_SIGNING_HMAC_SHA256:
     768           0 :                         signing = "HMAC-SHA256";
     769           0 :                         break;
     770           0 :                 case SMB2_SIGNING_AES128_CMAC:
     771           0 :                         signing = "AES-128-CMAC";
     772           0 :                         break;
     773          15 :                 case SMB2_SIGNING_AES128_GMAC:
     774          15 :                         signing = "AES-128-GMAC";
     775          15 :                         break;
     776           0 :                 default:
     777           0 :                         signing = "???";
     778           0 :                         result = -1;
     779           0 :                         break;
     780             :                 }
     781          15 :                 if (smbXsrv_is_signed(session->signing_flags)) {
     782           0 :                         signing_degree = CRYPTO_DEGREE_FULL;
     783          15 :                 } else if (smbXsrv_is_partially_signed(session->signing_flags)) {
     784          15 :                         signing_degree = CRYPTO_DEGREE_PARTIAL;
     785             :                 }
     786             :         }
     787             : 
     788             : 
     789          18 :         if (!state->json_output) {
     790          12 :                 traverse_sessionid_stdout(state,
     791             :                          server_id_str_buf(session->pid, &tmp),
     792             :                          uid_gid_str,
     793             :                          machine_hostname,
     794          12 :                          session_dialect_str(session->connection_dialect),
     795             :                          encryption,
     796             :                          encryption_degree,
     797             :                          signing,
     798             :                          signing_degree);
     799             :         } else {
     800           6 :                 result = traverse_sessionid_json(state,
     801             :                                                  session,
     802             :                                                  uid_str,
     803             :                                                  gid_str,
     804             :                                                  encryption,
     805             :                                                  encryption_degree,
     806             :                                                  signing,
     807             :                                                  signing_degree,
     808           6 :                                                  session_dialect_str(session->connection_dialect));
     809             :         }
     810             : 
     811          18 :         TALLOC_FREE(machine_hostname);
     812          18 :         TALLOC_FREE(tmp_ctx);
     813             : 
     814          18 :         return result;
     815             : }
     816             : 
     817             : 
     818           0 : static bool print_notify_rec_stdout(struct traverse_state *state,
     819             :                                     const char *path,
     820             :                                     char *server_id_str,
     821             :                                     unsigned filter,
     822             :                                     unsigned subdir_filter)
     823             : {
     824           0 :         d_printf("%s\\%s\\%x\\%x\n", path, server_id_str,
     825             :                  filter, subdir_filter);
     826             : 
     827           0 :         return true;
     828             : }
     829             : 
     830           3 : static int prepare_notify(struct traverse_state *state)
     831             : {
     832           3 :         if (!state->json_output) {
     833             :                 /* don't print header line */
     834             :         } else {
     835           3 :                 add_section_to_json(state, "notifies");
     836             :         }
     837           3 :         return 0;
     838             : }
     839             : 
     840           0 : static bool print_notify_rec(const char *path, struct server_id server,
     841             :                              const struct notify_instance *instance,
     842             :                              void *private_data)
     843             : {
     844             :         struct server_id_buf idbuf;
     845           0 :         struct traverse_state *state = (struct traverse_state *)private_data;
     846             :         bool result;
     847             : 
     848           0 :         if (!state->json_output) {
     849           0 :                 result = print_notify_rec_stdout(state,
     850             :                                                  path,
     851             :                                                  server_id_str_buf(server, &idbuf),
     852           0 :                                                  (unsigned)instance->filter,
     853           0 :                                                  (unsigned)instance->subdir_filter);
     854             : 
     855             :         } else {
     856           0 :                 result = print_notify_rec_json(state,
     857             :                                                instance,
     858             :                                                server,
     859             :                                                path);
     860             :         }
     861             : 
     862           0 :         return result;
     863             : }
     864             : 
     865             : enum {
     866             :         OPT_RESOLVE_UIDS = 1000,
     867             : };
     868             : 
     869          27 : int main(int argc, const char *argv[])
     870             : {
     871             :         int c;
     872          27 :         int profile_only = 0;
     873             :         bool show_processes, show_locks, show_shares;
     874          27 :         bool show_notify = false;
     875          27 :         poptContext pc = NULL;
     876          27 :         struct traverse_state state = {0};
     877          81 :         struct poptOption long_options[] = {
     878             :                 POPT_AUTOHELP
     879             :                 {
     880             :                         .longName   = "processes",
     881             :                         .shortName  = 'p',
     882             :                         .argInfo    = POPT_ARG_NONE,
     883             :                         .arg        = NULL,
     884             :                         .val        = 'p',
     885             :                         .descrip    = "Show processes only",
     886             :                 },
     887             :                 {
     888             :                         .longName   = "verbose",
     889             :                         .shortName  = 'v',
     890             :                         .argInfo    = POPT_ARG_NONE,
     891             :                         .arg        = NULL,
     892             :                         .val        = 'v',
     893             :                         .descrip    = "Be verbose",
     894             :                 },
     895             :                 {
     896             :                         .longName   = "locks",
     897             :                         .shortName  = 'L',
     898             :                         .argInfo    = POPT_ARG_NONE,
     899             :                         .arg        = NULL,
     900             :                         .val        = 'L',
     901             :                         .descrip    = "Show locks only",
     902             :                 },
     903             :                 {
     904             :                         .longName   = "shares",
     905             :                         .shortName  = 'S',
     906             :                         .argInfo    = POPT_ARG_NONE,
     907             :                         .arg        = NULL,
     908             :                         .val        = 'S',
     909             :                         .descrip    = "Show shares only",
     910             :                 },
     911             :                 {
     912             :                         .longName   = "notify",
     913             :                         .shortName  = 'N',
     914             :                         .argInfo    = POPT_ARG_NONE,
     915             :                         .arg        = NULL,
     916             :                         .val        = 'N',
     917             :                         .descrip    = "Show notifies",
     918             :                 },
     919             :                 {
     920             :                         .longName   = "user",
     921             :                         .shortName  = 'u',
     922             :                         .argInfo    = POPT_ARG_STRING,
     923             :                         .arg        = &username,
     924             :                         .val        = 'u',
     925             :                         .descrip    = "Switch to user",
     926             :                 },
     927             :                 {
     928             :                         .longName   = "brief",
     929             :                         .shortName  = 'b',
     930             :                         .argInfo    = POPT_ARG_NONE,
     931             :                         .arg        = NULL,
     932             :                         .val        = 'b',
     933             :                         .descrip    = "Be brief",
     934             :                 },
     935             :                 {
     936             :                         .longName   = "profile",
     937             :                         .shortName  =     'P',
     938             :                         .argInfo    = POPT_ARG_NONE,
     939             :                         .arg        = NULL,
     940             :                         .val        = 'P',
     941             :                         .descrip    = "Do profiling",
     942             :                 },
     943             :                 {
     944             :                         .longName   = "profile-rates",
     945             :                         .shortName  = 'R',
     946             :                         .argInfo    = POPT_ARG_NONE,
     947             :                         .arg        = NULL,
     948             :                         .val        = 'R',
     949             :                         .descrip    = "Show call rates",
     950             :                 },
     951             :                 {
     952             :                         .longName   = "byterange",
     953             :                         .shortName  = 'B',
     954             :                         .argInfo    = POPT_ARG_NONE,
     955             :                         .arg        = NULL,
     956             :                         .val        = 'B',
     957             :                         .descrip    = "Include byte range locks"
     958             :                 },
     959             :                 {
     960             :                         .longName   = "numeric",
     961             :                         .shortName  = 'n',
     962             :                         .argInfo    = POPT_ARG_NONE,
     963             :                         .arg        = NULL,
     964             :                         .val        = 'n',
     965             :                         .descrip    = "Numeric uid/gid"
     966             :                 },
     967             :                 {
     968             :                         .longName   = "json",
     969             :                         .shortName  = 'j',
     970             :                         .argInfo    = POPT_ARG_NONE,
     971             :                         .arg        = NULL,
     972             :                         .val        = 'j',
     973             :                         .descrip    = "JSON output"
     974             :                 },
     975             :                 {
     976             :                         .longName   = "fast",
     977             :                         .shortName  = 'f',
     978             :                         .argInfo    = POPT_ARG_NONE,
     979             :                         .arg        = NULL,
     980             :                         .val        = 'f',
     981             :                         .descrip    = "Skip checks if processes still exist"
     982             :                 },
     983             :                 {
     984             :                         .longName   = "resolve-uids",
     985             :                         .shortName  = 0,
     986             :                         .argInfo    = POPT_ARG_NONE,
     987             :                         .arg        = NULL,
     988             :                         .val        = OPT_RESOLVE_UIDS,
     989             :                         .descrip    = "Try to resolve UIDs to usernames"
     990             :                 },
     991          27 :                 POPT_COMMON_SAMBA
     992          27 :                 POPT_COMMON_VERSION
     993             :                 POPT_TABLEEND
     994             :         };
     995          27 :         TALLOC_CTX *frame = talloc_stackframe();
     996          27 :         int ret = 0;
     997          27 :         struct messaging_context *msg_ctx = NULL;
     998             :         char *db_path;
     999             :         bool ok;
    1000          27 :         struct loadparm_context *lp_ctx = NULL;
    1001             : 
    1002          27 :         state.first = true;
    1003          27 :         state.json_output = false;
    1004          27 :         state.resolve_uids = false;
    1005             : 
    1006          27 :         smb_init_locale();
    1007             : 
    1008          27 :         ok = samba_cmdline_init(frame,
    1009             :                                 SAMBA_CMDLINE_CONFIG_CLIENT,
    1010             :                                 false /* require_smbconf */);
    1011          27 :         if (!ok) {
    1012           0 :                 DBG_ERR("Failed to init cmdline parser!\n");
    1013           0 :                 TALLOC_FREE(frame);
    1014           0 :                 exit(1);
    1015             :         }
    1016          27 :         lp_ctx = samba_cmdline_get_lp_ctx();
    1017          27 :         lpcfg_set_cmdline(lp_ctx, "log level", "0");
    1018             : 
    1019          27 :         pc = samba_popt_get_context(getprogname(),
    1020             :                                     argc,
    1021             :                                     argv,
    1022             :                                     long_options,
    1023             :                                     POPT_CONTEXT_KEEP_FIRST);
    1024          27 :         if (pc == NULL) {
    1025           0 :                 DBG_ERR("Failed to setup popt context!\n");
    1026           0 :                 TALLOC_FREE(frame);
    1027           0 :                 exit(1);
    1028             :         }
    1029             : 
    1030          60 :         while ((c = poptGetNextOpt(pc)) != -1) {
    1031          33 :                 switch (c) {
    1032           6 :                 case 'p':
    1033           6 :                         processes_only = true;
    1034           6 :                         break;
    1035           3 :                 case 'v':
    1036           3 :                         verbose = true;
    1037           3 :                         break;
    1038           3 :                 case 'L':
    1039           3 :                         locks_only = true;
    1040           3 :                         break;
    1041           3 :                 case 'S':
    1042           3 :                         shares_only = true;
    1043           3 :                         break;
    1044           3 :                 case 'N':
    1045           3 :                         show_notify = true;
    1046           3 :                         break;
    1047           0 :                 case 'b':
    1048           0 :                         brief = true;
    1049           0 :                         break;
    1050           0 :                 case 'u':
    1051           0 :                         Ucrit_addUid(nametouid(poptGetOptArg(pc)));
    1052           0 :                         break;
    1053           3 :                 case 'P':
    1054             :                 case 'R':
    1055           3 :                         profile_only = c;
    1056           3 :                         break;
    1057           3 :                 case 'B':
    1058           3 :                         show_brl = true;
    1059           3 :                         break;
    1060           0 :                 case 'n':
    1061           0 :                         numeric_only = true;
    1062           0 :                         break;
    1063           9 :                 case 'j':
    1064           9 :                         state.json_output = true;
    1065           9 :                         break;
    1066           0 :                 case 'f':
    1067           0 :                         do_checks = false;
    1068           0 :                         break;
    1069           0 :                 case OPT_RESOLVE_UIDS:
    1070           0 :                         state.resolve_uids = true;
    1071           0 :                         break;
    1072           0 :                 case POPT_ERROR_BADOPT:
    1073           0 :                         fprintf(stderr, "\nInvalid option %s: %s\n\n",
    1074             :                                 poptBadOption(pc, 0), poptStrerror(c));
    1075           0 :                         poptPrintUsage(pc, stderr, 0);
    1076           0 :                         exit(1);
    1077             :                 }
    1078             :         }
    1079             : 
    1080          27 :         sec_init();
    1081             : 
    1082             : #ifdef HAVE_JANSSON
    1083          27 :         state.root_json = json_new_object();
    1084          27 :         if (!json_is_invalid(&state.root_json)) {
    1085          27 :                 add_general_information_to_json(&state);
    1086             :         }
    1087             : #else /* HAVE_JANSSON */
    1088             :         if (state.json_output) {
    1089             :                 fprintf(stderr, "JSON support not available, please install lib Jansson\n");
    1090             :                 goto done;
    1091             :         }
    1092             : #endif /* HAVE_JANSSON */
    1093             : 
    1094          27 :         if (getuid() != geteuid()) {
    1095           0 :                 fprintf(stderr, "smbstatus should not be run setuid\n");
    1096           0 :                 ret = 1;
    1097           0 :                 goto done;
    1098             :         }
    1099             : 
    1100          27 :         if (getuid() != 0) {
    1101           0 :                 fprintf(stderr, "smbstatus only works as root!\n");
    1102           0 :                 ret = 1;
    1103           0 :                 goto done;
    1104             :         }
    1105             : 
    1106             :         /* setup the flags based on the possible combincations */
    1107             : 
    1108          27 :         show_processes = !(shares_only || locks_only || profile_only) || processes_only;
    1109          27 :         show_locks     = !(shares_only || processes_only || profile_only) || locks_only;
    1110          27 :         show_shares    = !(processes_only || locks_only || profile_only) || shares_only;
    1111             : 
    1112          27 :         if ( username )
    1113           0 :                 Ucrit_addUid( nametouid(username) );
    1114             : 
    1115          27 :         if (verbose && !state.json_output) {
    1116           0 :                 d_printf("using configfile = %s\n", get_dyn_CONFIGFILE());
    1117             :         }
    1118             : 
    1119          27 :         msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE());
    1120          27 :         if (msg_ctx == NULL) {
    1121           0 :                 fprintf(stderr, "Could not initialize messaging, not root?\n");
    1122           0 :                 ret = -1;
    1123           0 :                 goto done;
    1124             :         }
    1125             : 
    1126          27 :         switch (profile_only) {
    1127           3 :                 case 'P':
    1128             :                         /* Dump profile data */
    1129           3 :                         ok = status_profile_dump(verbose, &state);
    1130           3 :                         ret = ok ? 0 : 1;
    1131           3 :                         goto done;
    1132           0 :                 case 'R':
    1133             :                         /* Continuously display rate-converted data */
    1134           0 :                         if (!state.json_output) {
    1135           0 :                                 ok = status_profile_rates(verbose);
    1136           0 :                                 ret = ok ? 0 : 1;
    1137             :                         } else {
    1138           0 :                                 fprintf(stderr, "Call rates not available in a json output.\n");
    1139           0 :                                 ret = 1;
    1140             :                         }
    1141           0 :                         goto done;
    1142          24 :                 default:
    1143          24 :                         break;
    1144             :         }
    1145             : 
    1146          24 :         if ( show_processes ) {
    1147          18 :                 prepare_sessionid(&state);
    1148          18 :                 sessionid_traverse_read(traverse_sessionid, &state);
    1149             : 
    1150          18 :                 if (processes_only) {
    1151           6 :                         goto done;
    1152             :                 }
    1153             :         }
    1154             : 
    1155          18 :         if ( show_shares ) {
    1156          15 :                 if (brief) {
    1157           0 :                         goto done;
    1158             :                 }
    1159          15 :                 prepare_connections(&state);
    1160          15 :                 connections_forall_read(traverse_connections, &state);
    1161             : 
    1162          15 :                 if (!state.json_output) {
    1163           9 :                         d_printf("\n");
    1164             :                 }
    1165             : 
    1166          15 :                 if ( shares_only ) {
    1167           3 :                         goto done;
    1168             :                 }
    1169             :         }
    1170             : 
    1171          15 :         if ( show_locks ) {
    1172             :                 int result;
    1173             :                 struct db_context *db;
    1174             : 
    1175          15 :                 db_path = lock_path(talloc_tos(), "locking.tdb");
    1176          15 :                 if (db_path == NULL) {
    1177           0 :                         fprintf(stderr, "Out of memory - exiting\n");
    1178           0 :                         ret = -1;
    1179           0 :                         goto done;
    1180             :                 }
    1181             : 
    1182          15 :                 db = db_open(NULL, db_path, 0,
    1183             :                              TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, O_RDONLY, 0,
    1184             :                              DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
    1185             : 
    1186          15 :                 if (!db) {
    1187           0 :                         fprintf(stderr, "%s not initialised\n", db_path);
    1188           0 :                         fprintf(stderr, "This is normal if an SMB client has never "
    1189             :                                  "connected to your server.\n");
    1190           0 :                         TALLOC_FREE(db_path);
    1191           0 :                         ret = 0;
    1192           0 :                         goto done;
    1193             :                 } else {
    1194          15 :                         TALLOC_FREE(db);
    1195          15 :                         TALLOC_FREE(db_path);
    1196             :                 }
    1197             : 
    1198          15 :                 if (!locking_init_readonly()) {
    1199           0 :                         fprintf(stderr, "Can't initialise locking module - exiting\n");
    1200           0 :                         ret = 1;
    1201           0 :                         goto done;
    1202             :                 }
    1203             : 
    1204          15 :                 prepare_share_mode(&state);
    1205          15 :                 result = share_entry_forall(print_share_mode, &state);
    1206             : 
    1207          15 :                 if (result == 0 && !state.json_output) {
    1208           0 :                         fprintf(stderr, "No locked files\n");
    1209          15 :                 } else if (result < 0 && !state.json_output) {
    1210           0 :                         fprintf(stderr, "locked file list truncated\n");
    1211             :                 }
    1212             : 
    1213          15 :                 if (!state.json_output) {
    1214           9 :                         d_printf("\n");
    1215             :                 }
    1216             : 
    1217          15 :                 if (show_brl) {
    1218           3 :                         prepare_brl(&state);
    1219           3 :                         brl_forall(print_brl, &state);
    1220             :                 }
    1221             : 
    1222          15 :                 locking_end();
    1223             :         }
    1224             : 
    1225          15 :         if (show_notify) {
    1226           3 :                 prepare_notify(&state);
    1227           3 :                 notify_walk(msg_ctx, print_notify_rec, &state);
    1228             :         }
    1229             : 
    1230          12 : done:
    1231          27 :         cmdline_messaging_context_free();
    1232          27 :         poptFreeContext(pc);
    1233             : #ifdef HAVE_JANSSON
    1234          27 :         if (state.json_output) {
    1235           9 :                 d_printf("%s\n", json_to_string(frame, &state.root_json));
    1236             :         }
    1237          27 :         json_free(&state.root_json);
    1238             : #endif /* HAVE_JANSSON */
    1239          27 :         TALLOC_FREE(frame);
    1240          27 :         return ret;
    1241             : }

Generated by: LCOV version 1.14