LCOV - code coverage report
Current view: top level - source3/utils - status_json.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 393 781 50.3 %
Date: 2024-05-31 13:13:24 Functions: 18 22 81.8 %

          Line data    Source code
       1             : /*
       2             :  * Samba Unix/Linux SMB client library
       3             :  * Json output
       4             :  * Copyright (C) Jule Anger 2022
       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             : 
      20             : #include "includes.h"
      21             : #include "smbprofile.h"
      22             : #include "lib/util/time_basic.h"
      23             : #include "conn_tdb.h"
      24             : #include "session.h"
      25             : #include "librpc/gen_ndr/smbXsrv.h"
      26             : #include "librpc/gen_ndr/open_files.h"
      27             : #include "status_json.h"
      28             : #include "../libcli/security/security.h"
      29             : #include "status.h"
      30             : #include "lib/util/server_id.h"
      31             : #include "lib/util/string_wrappers.h"
      32             : 
      33             : #include <jansson.h>
      34             : #include "audit_logging.h" /* various JSON helpers */
      35             : #include "auth/common_auth.h"
      36             : 
      37          18 : int add_general_information_to_json(struct traverse_state *state)
      38             : {
      39             :         int result;
      40             : 
      41          18 :         result = json_add_timestamp(&state->root_json);
      42          18 :         if (result < 0) {
      43           0 :                 return -1;
      44             :         }
      45             : 
      46          18 :         result = json_add_string(&state->root_json, "version", samba_version_string());
      47          18 :         if (result < 0) {
      48           0 :                 return -1;
      49             :         }
      50             : 
      51          18 :         result = json_add_string(&state->root_json, "smb_conf", get_dyn_CONFIGFILE());
      52          18 :         if (result < 0) {
      53           0 :                 return -1;
      54             :         }
      55             : 
      56          18 :         return 0;
      57             : }
      58             : 
      59          12 : static int add_server_id_to_json(struct json_object *parent_json,
      60             :                                  const struct server_id server_id)
      61             : {
      62             :         struct json_object sub_json;
      63          12 :         char *pid_str = NULL;
      64          12 :         char *task_id_str = NULL;
      65          12 :         char *vnn_str = NULL;
      66          12 :         char *unique_id_str = NULL;
      67             :         int result;
      68             : 
      69          12 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
      70          12 :         if (tmp_ctx == NULL) {
      71           0 :                 return -1;
      72             :         }
      73             : 
      74          12 :         sub_json = json_new_object();
      75          12 :         if (json_is_invalid(&sub_json)) {
      76           0 :                 goto failure;
      77             :         }
      78             : 
      79          12 :         pid_str = talloc_asprintf(
      80          12 :                 tmp_ctx, "%lu", (unsigned long)server_id.pid);
      81          12 :         result = json_add_string(&sub_json, "pid", pid_str);
      82          12 :         if (result < 0) {
      83           0 :                 goto failure;
      84             :         }
      85          12 :         task_id_str = talloc_asprintf(tmp_ctx, "%u", server_id.task_id);
      86          12 :         result = json_add_string(&sub_json, "task_id", task_id_str);
      87          12 :         if (result < 0) {
      88           0 :                 goto failure;
      89             :         }
      90          12 :         vnn_str = talloc_asprintf(tmp_ctx, "%u", server_id.vnn);
      91          12 :         result = json_add_string(&sub_json, "vnn", vnn_str);
      92          12 :         if (result < 0) {
      93           0 :                 goto failure;
      94             :         }
      95          12 :         unique_id_str = talloc_asprintf(
      96          12 :                 tmp_ctx, "%"PRIu64, server_id.unique_id);
      97          12 :         result = json_add_string(&sub_json, "unique_id", unique_id_str);
      98          12 :         if (result < 0) {
      99           0 :                 goto failure;
     100             :         }
     101             : 
     102          12 :         result = json_add_object(parent_json, "server_id", &sub_json);
     103          12 :         if (result < 0) {
     104           0 :                 goto failure;
     105             :         }
     106             : 
     107          12 :         TALLOC_FREE(tmp_ctx);
     108          12 :         return 0;
     109           0 : failure:
     110           0 :         json_free(&sub_json);
     111           0 :         TALLOC_FREE(tmp_ctx);
     112           0 :         return -1;
     113             : }
     114             : 
     115             : struct mask2txt {
     116             :         uint32_t mask;
     117             :         const char *string_desc;
     118             : };
     119             : 
     120             : /*
     121             :  * Convert a mask of some sort (access, oplock, leases),
     122             :  * to key/value pairs in a JSON object.
     123             :  */
     124          12 : static int map_mask_to_json(struct json_object *root_json,
     125             :                             uint32_t tomap,
     126             :                             const struct mask2txt *table)
     127             : {
     128          12 :         const struct mask2txt *a = NULL;
     129          12 :         int result = 0;
     130             : 
     131          92 :         for (a = table; a->string_desc != 0; a++) {
     132          80 :                 result = json_add_bool(root_json, a->string_desc,
     133          80 :                                       (tomap & a->mask) ? true : false);
     134             : 
     135          80 :                 if (result < 0) {
     136           0 :                         return result;
     137             :                 }
     138          80 :                 tomap &= ~a->mask;
     139             :         }
     140             : 
     141             :         /* Assert we know about all requested "tomap" values */
     142          12 :         SMB_ASSERT(tomap == 0);
     143             : 
     144          12 :         return 0;
     145             : }
     146             : 
     147             : static const struct mask2txt access_mask[] = {
     148             :         {FILE_READ_DATA, "READ_DATA"},
     149             :         {FILE_WRITE_DATA, "WRITE_DATA"},
     150             :         {FILE_APPEND_DATA, "APPEND_DATA"},
     151             :         {FILE_READ_EA, "READ_EA"},
     152             :         {FILE_WRITE_EA, "WRITE_EA"},
     153             :         {FILE_EXECUTE, "EXECUTE"},
     154             :         {FILE_READ_ATTRIBUTES, "READ_ATTRIBUTES"},
     155             :         {FILE_WRITE_ATTRIBUTES, "WRITE_ATTRIBUTES"},
     156             :         {FILE_DELETE_CHILD, "DELETE_CHILD"},
     157             :         {SEC_STD_DELETE, "DELETE"},
     158             :         {SEC_STD_READ_CONTROL, "READ_CONTROL"},
     159             :         {SEC_STD_WRITE_DAC, "WRITE_DAC"},
     160             :         {SEC_STD_SYNCHRONIZE, "SYNCHRONIZE"},
     161             :         {SEC_FLAG_SYSTEM_SECURITY, "ACCESS_SYSTEM_SECURITY"},
     162             :         {0, NULL}
     163             : };
     164             : 
     165             : static const struct mask2txt oplock_mask[] = {
     166             :         {EXCLUSIVE_OPLOCK, "EXCLUSIVE"},
     167             :         {BATCH_OPLOCK, "BATCH"},
     168             :         {LEVEL_II_OPLOCK, "LEVEL_II"},
     169             :         {LEASE_OPLOCK, "LEASE"},
     170             :         {0, NULL}
     171             : };
     172             : 
     173             : static const struct mask2txt sharemode_mask[] = {
     174             :         {FILE_SHARE_READ, "READ"},
     175             :         {FILE_SHARE_WRITE, "WRITE"},
     176             :         {FILE_SHARE_DELETE, "DELETE"},
     177             :         {0, NULL}
     178             : };
     179             : 
     180             : static const struct mask2txt lease_mask[] = {
     181             :         {SMB2_LEASE_READ, "READ"},
     182             :         {SMB2_LEASE_WRITE, "WRITE"},
     183             :         {SMB2_LEASE_HANDLE, "HANDLE"},
     184             :         {0, NULL}
     185             : };
     186             : 
     187         878 : int add_profile_item_to_json(struct traverse_state *state,
     188             :                              const char *section,
     189             :                              const char *subsection,
     190             :                              const char *key,
     191             :                              uintmax_t value)
     192             : {
     193         878 :         struct json_object section_json = {
     194             :                 .valid = false,
     195             :         };
     196         878 :         struct json_object subsection_json = {
     197             :                 .valid = false,
     198             :         };
     199         878 :         int result = 0;
     200             : 
     201         878 :         section_json = json_get_object(&state->root_json, section);
     202         878 :         if (json_is_invalid(&section_json)) {
     203           0 :                 goto failure;
     204             :         }
     205         878 :         subsection_json = json_get_object(&section_json, subsection);
     206         878 :         if (json_is_invalid(&subsection_json)) {
     207           0 :                 goto failure;
     208             :         }
     209             : 
     210         878 :         result = json_add_int(&subsection_json, key, value);
     211         878 :         if (result < 0) {
     212           0 :                 goto failure;
     213             :         }
     214             : 
     215         878 :         result = json_update_object(&section_json, subsection,  &subsection_json);
     216         878 :         if (result < 0) {
     217           0 :                 goto failure;
     218             :         }
     219         878 :         result = json_update_object(&state->root_json, section, &section_json);
     220         878 :         if (result < 0) {
     221           0 :                 goto failure;
     222             :         }
     223             : 
     224         878 :         return 0;
     225           0 : failure:
     226           0 :         json_free(&section_json);
     227           0 :         json_free(&subsection_json);
     228           0 :         return -1;
     229             : }
     230             : 
     231          16 : int add_section_to_json(struct traverse_state *state,
     232             :                         const char *key)
     233             : {
     234             :         struct json_object empty_json;
     235             :         int result;
     236             : 
     237          16 :         empty_json = json_new_object();
     238          16 :         if (json_is_invalid(&empty_json)) {
     239           0 :                 return -1;
     240             :         }
     241             : 
     242          16 :         result = json_add_object(&state->root_json, key, &empty_json);
     243          16 :         if (result < 0) {
     244           0 :                 return -1;
     245             :         }
     246             : 
     247          16 :         return result;
     248             : }
     249             : 
     250          16 : static int add_crypto_to_json(struct json_object *parent_json,
     251             :                               const char *key,
     252             :                               const char *cipher,
     253             :                               enum crypto_degree degree)
     254             : {
     255             :         struct json_object sub_json;
     256             :         const char *degree_str;
     257             :         int result;
     258             : 
     259          16 :         if (degree == CRYPTO_DEGREE_NONE) {
     260          12 :                 degree_str = "none";
     261           4 :         } else if (degree == CRYPTO_DEGREE_ANONYMOUS) {
     262           0 :                 degree_str = "anonymous";
     263           4 :         } else if (degree == CRYPTO_DEGREE_PARTIAL) {
     264           4 :                 degree_str = "partial";
     265             :         } else {
     266           0 :                 degree_str = "full";
     267             :         }
     268             : 
     269          16 :         sub_json = json_new_object();
     270          16 :         if (json_is_invalid(&sub_json)) {
     271           0 :                 goto failure;
     272             :         }
     273             : 
     274          16 :         result = json_add_string(&sub_json, "cipher", cipher);
     275          16 :         if (result < 0) {
     276           0 :                 goto failure;
     277             :         }
     278          16 :         result = json_add_string(&sub_json, "degree", degree_str);
     279          16 :         if (result < 0) {
     280           0 :                 goto failure;
     281             :         }
     282          16 :         result = json_add_object(parent_json, key, &sub_json);
     283          16 :         if (result < 0) {
     284           0 :                 goto failure;
     285             :         }
     286             : 
     287          16 :         return 0;
     288           0 : failure:
     289           0 :         json_free(&sub_json);
     290           0 :         return -1;
     291             : }
     292             : 
     293           4 : static int add_channel_to_json(struct json_object *parent_json,
     294             :                                const struct smbXsrv_channel_global0 *channel)
     295             : {
     296           4 :         TALLOC_CTX *frame = talloc_stackframe();
     297             :         struct json_object sub_json;
     298           4 :         char *id_str = NULL;
     299             :         struct timeval tv;
     300             :         struct timeval_buf tv_buf;
     301           4 :         char *time_str = NULL;
     302             :         int result;
     303             : 
     304           4 :         sub_json = json_new_object();
     305           4 :         if (json_is_invalid(&sub_json)) {
     306           0 :                 goto failure;
     307             :         }
     308             : 
     309           4 :         id_str = talloc_asprintf(frame, "%"PRIu64"", channel->channel_id);
     310           4 :         if (id_str == NULL) {
     311           0 :                 goto failure;
     312             :         }
     313           4 :         result = json_add_string(&sub_json, "channel_id", id_str);
     314           4 :         if (result < 0) {
     315           0 :                 goto failure;
     316             :         }
     317           4 :         nttime_to_timeval(&tv, channel->creation_time);
     318           4 :         time_str = timeval_str_buf(&tv, true, true, &tv_buf);
     319           4 :         if (time_str == NULL) {
     320           0 :                 goto failure;
     321             :         }
     322           4 :         result = json_add_string(&sub_json, "creation_time", time_str);
     323           4 :         if (result < 0) {
     324           0 :                 goto failure;
     325             :         }
     326           4 :         result = json_add_string(&sub_json, "local_address", channel->local_address);
     327           4 :         if (result < 0) {
     328           0 :                 goto failure;
     329             :         }
     330           4 :         result = json_add_string(&sub_json, "remote_address", channel->remote_address);
     331           4 :         if (result < 0) {
     332           0 :                 goto failure;
     333             :         }
     334             : 
     335           4 :         result = json_add_object(parent_json, id_str, &sub_json);
     336           4 :         if (result < 0) {
     337           0 :                 goto failure;
     338             :         }
     339             : 
     340           4 :         TALLOC_FREE(frame);
     341           4 :         return 0;
     342           0 : failure:
     343           0 :         json_free(&sub_json);
     344           0 :         TALLOC_FREE(frame);
     345           0 :         return -1;
     346             : }
     347             : 
     348           4 : static int add_channels_to_json(struct json_object *parent_json,
     349             :                                 const struct smbXsrv_session_global0 *global)
     350             : {
     351             :         struct json_object sub_json;
     352             :         uint32_t i;
     353             :         int result;
     354             : 
     355           4 :         sub_json = json_new_object();
     356           4 :         if (json_is_invalid(&sub_json)) {
     357           0 :                 goto failure;
     358             :         }
     359             : 
     360           8 :         for (i = 0; i < global->num_channels; i++) {
     361           4 :                 const struct smbXsrv_channel_global0 *c = &global->channels[i];
     362             : 
     363           4 :                 result = add_channel_to_json(&sub_json, c);
     364           4 :                 if (result < 0) {
     365           0 :                         goto failure;
     366             :                 }
     367             :         }
     368             : 
     369           4 :         result = json_add_object(parent_json, "channels", &sub_json);
     370           4 :         if (result < 0) {
     371           0 :                 goto failure;
     372             :         }
     373             : 
     374           4 :         return 0;
     375           0 : failure:
     376           0 :         json_free(&sub_json);
     377           0 :         return -1;
     378             : }
     379             : 
     380           4 : int traverse_connections_json(struct traverse_state *state,
     381             :                               const struct connections_data *crec,
     382             :                               const char *encryption_cipher,
     383             :                               enum crypto_degree encryption_degree,
     384             :                               const char *signing_cipher,
     385             :                               enum crypto_degree signing_degree)
     386             : {
     387             :         struct json_object sub_json;
     388             :         struct json_object connections_json;
     389             :         struct timeval tv;
     390             :         struct timeval_buf tv_buf;
     391           4 :         char *time = NULL;
     392           4 :         int result = 0;
     393           4 :         char *sess_id_str = NULL;
     394           4 :         char *tcon_id_str = NULL;
     395             : 
     396           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     397           4 :         if (tmp_ctx == NULL) {
     398           0 :                 return -1;
     399             :         }
     400             : 
     401           4 :         sub_json = json_new_object();
     402           4 :         if (json_is_invalid(&sub_json)) {
     403           0 :                 goto failure;
     404             :         }
     405           4 :         connections_json = json_get_object(&state->root_json, "tcons");
     406           4 :         if (json_is_invalid(&connections_json)) {
     407           0 :                 goto failure;
     408             :         }
     409             : 
     410           4 :         result = json_add_string(&sub_json, "service", crec->servicename);
     411           4 :         if (result < 0) {
     412           0 :                 goto failure;
     413             :         }
     414           4 :         result = add_server_id_to_json(&sub_json, crec->pid);
     415           4 :         if (result < 0) {
     416           0 :                 goto failure;
     417             :         }
     418           4 :         tcon_id_str = talloc_asprintf(tmp_ctx, "%u", crec->cnum);
     419           4 :         if (tcon_id_str == NULL) {
     420           0 :                 goto failure;
     421             :         }
     422           4 :         result = json_add_string(&sub_json, "tcon_id", tcon_id_str);
     423           4 :         if (result < 0) {
     424           0 :                 goto failure;
     425             :         }
     426           4 :         sess_id_str = talloc_asprintf(tmp_ctx, "%u", crec->sess_id);
     427           4 :         if (sess_id_str == NULL) {
     428           0 :                 goto failure;
     429             :         }
     430           4 :         result = json_add_string(&sub_json, "session_id", sess_id_str);
     431           4 :         if (result < 0) {
     432           0 :                 goto failure;
     433             :         }
     434           4 :         result = json_add_string(&sub_json, "machine", crec->machine);
     435           4 :         if (result < 0) {
     436           0 :                 goto failure;
     437             :         }
     438           4 :         nttime_to_timeval(&tv, crec->start);
     439           4 :         time = timeval_str_buf(&tv, true, true, &tv_buf);
     440           4 :         if (time == NULL) {
     441           0 :                 goto failure;
     442             :         }
     443           4 :         result = json_add_string(&sub_json, "connected_at", time);
     444           4 :         if (result < 0) {
     445           0 :                 goto failure;
     446             :         }
     447           4 :         result = add_crypto_to_json(&sub_json, "encryption",
     448             :                                    encryption_cipher, encryption_degree);
     449           4 :         if (result < 0) {
     450           0 :                 goto failure;
     451             :         }
     452           4 :         result = add_crypto_to_json(&sub_json, "signing",
     453             :                                    signing_cipher, signing_degree);
     454           4 :         if (result < 0) {
     455           0 :                 goto failure;
     456             :         }
     457             : 
     458           4 :         result = json_add_object(&connections_json, tcon_id_str, &sub_json);
     459           4 :         if (result < 0) {
     460           0 :                 goto failure;
     461             :         }
     462             : 
     463           4 :         result = json_update_object(&state->root_json, "tcons", &connections_json);
     464           4 :         if (result < 0) {
     465           0 :                 goto failure;
     466             :         }
     467             : 
     468           4 :         TALLOC_FREE(tmp_ctx);
     469           4 :         return 0;
     470           0 : failure:
     471           0 :         json_free(&sub_json);
     472           0 :         TALLOC_FREE(tmp_ctx);
     473           0 :         return -1;
     474             : }
     475             : 
     476           4 : int traverse_sessionid_json(struct traverse_state *state,
     477             :                             struct sessionid *session,
     478             :                             char *uid_str,
     479             :                             char *gid_str,
     480             :                             const char *encryption_cipher,
     481             :                             enum crypto_degree encryption_degree,
     482             :                             const char *signing_cipher,
     483             :                             enum crypto_degree signing_degree,
     484             :                             const char *connection_dialect)
     485             : {
     486             :         struct json_object sub_json;
     487             :         struct json_object session_json;
     488           4 :         int result = 0;
     489           4 :         char *id_str = NULL;
     490             :         struct timeval tv;
     491             :         struct timeval_buf tv_buf;
     492           4 :         char *time_str = NULL;
     493             : 
     494           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     495           4 :         if (tmp_ctx == NULL) {
     496           0 :                 return -1;
     497             :         }
     498             : 
     499           4 :         sub_json = json_new_object();
     500           4 :         if (json_is_invalid(&sub_json)) {
     501           0 :                 goto failure;
     502             :         }
     503             : 
     504           4 :         session_json = json_get_object(&state->root_json, "sessions");
     505           4 :         if (json_is_invalid(&session_json)) {
     506           0 :                 goto failure;
     507             :         }
     508             : 
     509           4 :         id_str = talloc_asprintf(tmp_ctx, "%u", session->id_num);
     510           4 :         result = json_add_string(&sub_json, "session_id", id_str);
     511           4 :         if (result < 0) {
     512           0 :                 goto failure;
     513             :         }
     514           4 :         result = add_server_id_to_json(&sub_json, session->pid);
     515           4 :         if (result < 0) {
     516           0 :                 goto failure;
     517             :         }
     518           4 :         result = json_add_int(&sub_json, "uid", session->uid);
     519           4 :         if (result < 0) {
     520           0 :                 goto failure;
     521             :         }
     522           4 :         result = json_add_int(&sub_json, "gid", session->gid);
     523           4 :         if (result < 0) {
     524           0 :                 goto failure;
     525             :         }
     526           4 :         result = json_add_string(&sub_json, "username", uid_str);
     527           4 :         if (result < 0) {
     528           0 :                 goto failure;
     529             :         }
     530           4 :         result = json_add_string(&sub_json, "groupname", gid_str);
     531           4 :         if (result < 0) {
     532           0 :                 goto failure;
     533             :         }
     534             : 
     535           4 :         nttime_to_timeval(&tv, session->global->creation_time);
     536           4 :         time_str = timeval_str_buf(&tv, true, true, &tv_buf);
     537           4 :         if (time_str == NULL) {
     538           0 :                 goto failure;
     539             :         }
     540           4 :         result = json_add_string(&sub_json, "creation_time", time_str);
     541           4 :         if (result < 0) {
     542           0 :                 goto failure;
     543             :         }
     544             : 
     545           4 :         nttime_to_timeval(&tv, session->global->expiration_time);
     546           4 :         time_str = timeval_str_buf(&tv, true, true, &tv_buf);
     547           4 :         if (time_str == NULL) {
     548           0 :                 goto failure;
     549             :         }
     550           4 :         result = json_add_string(&sub_json, "expiration_time", time_str);
     551           4 :         if (result < 0) {
     552           0 :                 goto failure;
     553             :         }
     554             : 
     555           4 :         nttime_to_timeval(&tv, session->global->auth_time);
     556           4 :         time_str = timeval_str_buf(&tv, true, true, &tv_buf);
     557           4 :         if (time_str == NULL) {
     558           0 :                 goto failure;
     559             :         }
     560           4 :         result = json_add_string(&sub_json, "auth_time", time_str);
     561           4 :         if (result < 0) {
     562           0 :                 goto failure;
     563             :         }
     564             : 
     565           4 :         result = json_add_string(&sub_json, "remote_machine", session->remote_machine);
     566           4 :         if (result < 0) {
     567           0 :                 goto failure;
     568             :         }
     569           4 :         result = json_add_string(&sub_json, "hostname", session->hostname);
     570           4 :         if (result < 0) {
     571           0 :                 goto failure;
     572             :         }
     573           4 :         result = json_add_string(&sub_json, "session_dialect", connection_dialect);
     574           4 :         if (result < 0) {
     575           0 :                 goto failure;
     576             :         }
     577           4 :         result = json_add_guid(&sub_json,
     578             :                                "client_guid",
     579           4 :                                &session->global->client_guid);
     580           4 :         if (result < 0) {
     581           0 :                 goto failure;
     582             :         }
     583           4 :         result = add_crypto_to_json(&sub_json, "encryption",
     584             :                                     encryption_cipher, encryption_degree);
     585           4 :         if (result < 0) {
     586           0 :                 goto failure;
     587             :         }
     588           4 :         result = add_crypto_to_json(&sub_json, "signing",
     589             :                                     signing_cipher, signing_degree);
     590           4 :         if (result < 0) {
     591           0 :                 goto failure;
     592             :         }
     593             : 
     594           4 :         result = add_channels_to_json(&sub_json, session->global);
     595           4 :         if (result < 0) {
     596           0 :                 goto failure;
     597             :         }
     598             : 
     599           4 :         result = json_add_object(&session_json, id_str, &sub_json);
     600           4 :         if (result < 0) {
     601           0 :                 goto failure;
     602             :         }
     603             : 
     604           4 :         result = json_update_object(&state->root_json, "sessions", &session_json);
     605           4 :         if (result < 0) {
     606           0 :                 goto failure;
     607             :         }
     608             : 
     609           4 :         TALLOC_FREE(tmp_ctx);
     610           4 :         return 0;
     611           0 : failure:
     612           0 :         json_free(&sub_json);
     613           0 :         TALLOC_FREE(tmp_ctx);
     614           0 :         return -1;
     615             : }
     616             : 
     617           4 : static int add_access_mode_to_json(struct json_object *parent_json,
     618             :                                    int access_int)
     619             : {
     620             :         struct json_object access_json;
     621           4 :         char *access_hex = NULL;
     622           4 :         const char *access_str = NULL;
     623             :         int result;
     624             : 
     625           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     626           4 :         if (tmp_ctx == NULL) {
     627           0 :                 return -1;
     628             :         }
     629             : 
     630           4 :         access_json = json_new_object();
     631           4 :         if (json_is_invalid(&access_json)) {
     632           0 :                 goto failure;
     633             :         }
     634             : 
     635           4 :         access_hex = talloc_asprintf(tmp_ctx, "0x%08x", access_int);
     636           4 :         result = json_add_string(&access_json, "hex", access_hex);
     637           4 :         if (result < 0) {
     638           0 :                   goto failure;
     639             :         }
     640           4 :         result = map_mask_to_json(&access_json, access_int, access_mask);
     641           4 :         if (result < 0) {
     642           0 :                 goto failure;
     643             :         }
     644             : 
     645           8 :         access_str = talloc_asprintf(tmp_ctx, "%s%s",
     646           4 :                                      (access_int & FILE_READ_DATA)?"R":"",
     647           4 :                                      (access_int & (FILE_WRITE_DATA|FILE_APPEND_DATA))?"W":"");
     648           4 :         result = json_add_string(&access_json, "text", access_str);
     649           4 :         if (result < 0) {
     650           0 :                   goto failure;
     651             :         }
     652             : 
     653           4 :         result = json_add_object(parent_json, "access_mask", &access_json);
     654           4 :         if (result < 0) {
     655           0 :                 goto failure;
     656             :         }
     657             : 
     658           4 :         TALLOC_FREE(tmp_ctx);
     659           4 :         return 0;
     660           0 : failure:
     661           0 :         json_free(&access_json);
     662           0 :         TALLOC_FREE(tmp_ctx);
     663           0 :         return -1;
     664             : }
     665             : 
     666           4 : static int add_caching_to_json(struct json_object *parent_json,
     667             :                               int op_type,
     668             :                               int lease_type)
     669             : {
     670             :         struct json_object caching_json;
     671           4 :         char *hex = NULL;
     672           4 :         char *caching_text = NULL;
     673           4 :         int caching_type = 0;
     674             :         int result;
     675             : 
     676           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     677           4 :         if (tmp_ctx == NULL) {
     678           0 :                 return -1;
     679             :         }
     680             : 
     681           4 :         caching_json = json_new_object();
     682           4 :         if (json_is_invalid(&caching_json)) {
     683           0 :                 goto failure;
     684             :         }
     685             : 
     686           4 :         if (op_type & LEASE_OPLOCK) {
     687           0 :                 caching_type = lease_type;
     688             :         } else {
     689           4 :                 if (op_type & LEVEL_II_OPLOCK) {
     690           0 :                         caching_type = SMB2_LEASE_READ;
     691           4 :                 } else if (op_type & EXCLUSIVE_OPLOCK) {
     692           0 :                         caching_type = SMB2_LEASE_READ + SMB2_LEASE_WRITE;
     693           4 :                 } else if (op_type & BATCH_OPLOCK) {
     694           0 :                         caching_type = SMB2_LEASE_READ + SMB2_LEASE_WRITE + SMB2_LEASE_HANDLE;
     695             :                 }
     696             :         }
     697           4 :         result = map_mask_to_json(&caching_json, caching_type, lease_mask);
     698           4 :         if (result < 0) {
     699           0 :                 goto failure;
     700             :         }
     701             : 
     702           4 :         hex = talloc_asprintf(tmp_ctx, "0x%08x", caching_type);
     703           4 :         if (hex == NULL) {
     704           0 :                 goto failure;
     705             :         }
     706           4 :         result = json_add_string(&caching_json, "hex", hex);
     707           4 :         if (result < 0) {
     708           0 :                 goto failure;
     709             :         }
     710             : 
     711          12 :         caching_text = talloc_asprintf(tmp_ctx, "%s%s%s",
     712           4 :                                        (caching_type & SMB2_LEASE_READ)?"R":"",
     713           4 :                                        (caching_type & SMB2_LEASE_WRITE)?"W":"",
     714           4 :                                        (caching_type & SMB2_LEASE_HANDLE)?"H":"");
     715           4 :         if (caching_text == NULL) {
     716           0 :                 return -1;
     717             :         }
     718             : 
     719           4 :         result = json_add_string(&caching_json, "text", caching_text);
     720           4 :         if (result < 0) {
     721           0 :                 goto failure;
     722             :         }
     723             : 
     724           4 :         result = json_add_object(parent_json, "caching", &caching_json);
     725           4 :         if (result < 0) {
     726           0 :                 goto failure;
     727             :         }
     728             : 
     729           4 :         TALLOC_FREE(tmp_ctx);
     730           4 :         return 0;
     731           0 : failure:
     732           0 :         json_free(&caching_json);
     733           0 :         TALLOC_FREE(tmp_ctx);
     734           0 :         return -1;
     735             : }
     736             : 
     737           4 : static int add_oplock_to_json(struct json_object *parent_json,
     738             :                               uint16_t op_type,
     739             :                               const char *op_str)
     740             : {
     741             :         struct json_object oplock_json;
     742             :         int result;
     743             : 
     744           4 :         oplock_json = json_new_object();
     745           4 :         if (json_is_invalid(&oplock_json)) {
     746           0 :                 goto failure;
     747             :         }
     748             : 
     749           4 :         if (op_type != 0) {
     750           0 :                 result = map_mask_to_json(&oplock_json, op_type, oplock_mask);
     751           0 :                 if (result < 0) {
     752           0 :                         goto failure;
     753             :                 }
     754           0 :                 result = json_add_string(&oplock_json, "text", op_str);
     755           0 :                 if (result < 0) {
     756           0 :                         goto failure;
     757             :                 }
     758             :         }
     759             : 
     760           4 :         result = json_add_object(parent_json, "oplock", &oplock_json);
     761           4 :         if (result < 0) {
     762           0 :                 goto failure;
     763             :         }
     764             : 
     765           4 :         return 0;
     766           0 : failure:
     767           0 :         json_free(&oplock_json);
     768           0 :         return -1;
     769             : }
     770             : 
     771           0 : static int lease_key_to_str(struct smb2_lease_key lease_key,
     772             :                             char *lease_str)
     773             : {
     774           0 :         uint8_t _buf[16] = {0};
     775           0 :         DATA_BLOB blob = data_blob_const(_buf, sizeof(_buf));
     776             :         struct GUID guid;
     777             :         NTSTATUS status;
     778           0 :         char *tmp = NULL;
     779             : 
     780           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     781           0 :         if (tmp_ctx == NULL) {
     782           0 :                 return -1;
     783             :         }
     784             : 
     785           0 :         PUSH_LE_U64(_buf, 0, lease_key.data[0]);
     786           0 :         PUSH_LE_U64(_buf, 8, lease_key.data[1]);
     787             : 
     788           0 :         status = GUID_from_ndr_blob(&blob, &guid);
     789           0 :         if (!NT_STATUS_IS_OK(status)) {
     790           0 :                 goto failure;
     791             :         }
     792           0 :         tmp = GUID_string(tmp_ctx, &guid);
     793           0 :         if (tmp == NULL) {
     794           0 :                 goto failure;
     795             :         }
     796           0 :         fstrcpy(lease_str, tmp);
     797             : 
     798           0 :         TALLOC_FREE(tmp_ctx);
     799           0 :         return 0;
     800           0 : failure:
     801           0 :         TALLOC_FREE(tmp_ctx);
     802           0 :         return -1;
     803             : }
     804             : 
     805           4 : static int add_lease_to_json(struct json_object *parent_json,
     806             :                              int lease_type,
     807             :                              struct smb2_lease_key lease_key,
     808             :                              bool add_lease)
     809             : {
     810             :         struct json_object lease_json;
     811           4 :         char *lease_hex = NULL;
     812           4 :         char *lease_text = NULL;
     813             :         fstring lease_key_str;
     814             :         int result;
     815             : 
     816           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     817           4 :         if (tmp_ctx == NULL) {
     818           0 :                 return -1;
     819             :         }
     820             : 
     821           4 :         lease_json = json_new_object();
     822           4 :         if (json_is_invalid(&lease_json)) {
     823           0 :                 goto failure;
     824             :         }
     825             : 
     826             : 
     827           4 :         if (add_lease) {
     828           0 :                 result = lease_key_to_str(lease_key, lease_key_str);
     829           0 :                 if (result < 0) {
     830           0 :                         goto failure;
     831             :                 }
     832           0 :                 result = json_add_string(&lease_json, "lease_key", lease_key_str);
     833           0 :                 if (result < 0) {
     834           0 :                         goto failure;
     835             :                 }
     836           0 :                 lease_hex = talloc_asprintf(tmp_ctx, "0x%08x", lease_type);
     837           0 :                 result = json_add_string(&lease_json, "hex", lease_hex);
     838           0 :                 if (result < 0) {
     839           0 :                         goto failure;
     840             :                 }
     841           0 :                 if (lease_type > (SMB2_LEASE_WRITE + SMB2_LEASE_HANDLE + SMB2_LEASE_READ)) {
     842           0 :                         result = json_add_bool(&lease_json, "UNKNOWN", true);
     843           0 :                         if (result < 0) {
     844           0 :                                 goto failure;
     845             :                         }
     846             :                 } else {
     847           0 :                         result = map_mask_to_json(&lease_json, lease_type, lease_mask);
     848           0 :                         if (result < 0) {
     849           0 :                                 goto failure;
     850             :                         }
     851             :                 }
     852           0 :                 lease_text = talloc_asprintf(tmp_ctx, "%s%s%s",
     853           0 :                                              (lease_type & SMB2_LEASE_READ)?"R":"",
     854           0 :                                              (lease_type & SMB2_LEASE_WRITE)?"W":"",
     855           0 :                                              (lease_type & SMB2_LEASE_HANDLE)?"H":"");
     856             : 
     857           0 :                 result = json_add_string(&lease_json, "text", lease_text);
     858           0 :                 if (result < 0) {
     859           0 :                         goto failure;
     860             :                 }
     861             :         }
     862             : 
     863           4 :         result = json_add_object(parent_json, "lease", &lease_json);
     864           4 :         if (result < 0) {
     865           0 :                 goto failure;
     866             :         }
     867             : 
     868           4 :         TALLOC_FREE(tmp_ctx);
     869           4 :         return 0;
     870           0 : failure:
     871           0 :         json_free(&lease_json);
     872           0 :         TALLOC_FREE(tmp_ctx);
     873           0 :         return -1;
     874             : }
     875             : 
     876           4 : static int add_sharemode_to_json(struct json_object *parent_json,
     877             :                                  int sharemode)
     878             : {
     879             :         struct json_object sharemode_json;
     880           4 :         char *hex = NULL;
     881           4 :         char *text = NULL;
     882             :         int result;
     883             : 
     884           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     885           4 :         if (tmp_ctx == NULL) {
     886           0 :                 return -1;
     887             :         }
     888             : 
     889           4 :         sharemode_json = json_new_object();
     890           4 :         if (json_is_invalid(&sharemode_json)) {
     891           0 :                 goto failure;
     892             :         }
     893             : 
     894           4 :         hex = talloc_asprintf(tmp_ctx, "0x%08x", sharemode);
     895           4 :         if (hex == NULL) {
     896           0 :                 goto failure;
     897             :         }
     898           4 :         result = json_add_string(&sharemode_json, "hex", hex);
     899           4 :         if (result < 0) {
     900           0 :                 goto failure;
     901             :         }
     902           4 :         result = map_mask_to_json(&sharemode_json, sharemode, sharemode_mask);
     903           4 :         if (result < 0) {
     904           0 :                 goto failure;
     905             :         }
     906             : 
     907          12 :         text = talloc_asprintf(tmp_ctx, "%s%s%s",
     908           4 :                                (sharemode & FILE_SHARE_READ)?"R":"",
     909           4 :                                (sharemode & FILE_SHARE_WRITE)?"W":"",
     910           4 :                                (sharemode & FILE_SHARE_DELETE)?"D":"");
     911           4 :         if (text == NULL) {
     912           0 :                 goto failure;
     913             :         }
     914           4 :         result = json_add_string(&sharemode_json, "text", text);
     915           4 :         if (result < 0) {
     916           0 :                 goto failure;
     917             :         }
     918             : 
     919           4 :         result = json_add_object(parent_json, "sharemode", &sharemode_json);
     920           4 :         if (result < 0) {
     921           0 :                 goto failure;
     922             :         }
     923             : 
     924           4 :         TALLOC_FREE(tmp_ctx);
     925           4 :         return 0;
     926           0 : failure:
     927           0 :         json_free(&sharemode_json);
     928           0 :         TALLOC_FREE(tmp_ctx);
     929           0 :         return -1;
     930             : }
     931             : 
     932           4 : static int add_open_to_json(struct json_object *parent_json,
     933             :                             const struct share_mode_entry *e,
     934             :                             bool resolve_uids,
     935             :                             const char *op_str,
     936             :                             uint32_t lease_type,
     937             :                             const char *uid_str)
     938             : {
     939           4 :         struct json_object sub_json = {
     940             :                 .valid = false,
     941             :         };
     942           4 :         struct json_object opens_json = {
     943             :                 .valid = false,
     944             :         };
     945             :         struct timeval_buf tv_buf;
     946           4 :         int result = 0;
     947             :         char *timestr;
     948           4 :         bool add_lease = false;
     949           4 :         char *key = NULL;
     950           4 :         char *share_file_id = NULL;
     951           4 :         char *pid = NULL;
     952             :         struct server_id_buf tmp;
     953             : 
     954           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     955           4 :         if (tmp_ctx == NULL) {
     956           0 :                 return -1;
     957             :         }
     958             : 
     959           4 :         opens_json = json_get_object(parent_json, "opens");
     960           4 :         if (json_is_invalid(&opens_json)) {
     961           0 :                 goto failure;
     962             :         }
     963           4 :         sub_json = json_new_object();
     964           4 :         if (json_is_invalid(&sub_json)) {
     965           0 :                 goto failure;
     966             :         }
     967             : 
     968             : 
     969           4 :         result = add_server_id_to_json(&sub_json, e->pid);
     970           4 :         if (result < 0) {
     971           0 :                 goto failure;
     972             :         }
     973           4 :         if (resolve_uids) {
     974           0 :                 result = json_add_string(&sub_json, "username", uid_str);
     975           0 :                 if (result < 0) {
     976           0 :                         goto failure;
     977             :                 }
     978             :         }
     979           4 :         result = json_add_int(&sub_json, "uid", e->uid);
     980           4 :         if (result < 0) {
     981           0 :                 goto failure;
     982             :         }
     983           4 :         share_file_id = talloc_asprintf(tmp_ctx, "%"PRIu64, e->share_file_id);
     984           4 :         result = json_add_string(&sub_json, "share_file_id", share_file_id);
     985           4 :         if (result < 0) {
     986           0 :                 goto failure;
     987             :         }
     988           4 :         result = add_sharemode_to_json(&sub_json, e->share_access);
     989           4 :         if (result < 0) {
     990           0 :                 goto failure;
     991             :         }
     992           4 :         result = add_access_mode_to_json(&sub_json, e->access_mask);
     993           4 :         if (result < 0) {
     994           0 :                 goto failure;
     995             :         }
     996           4 :         result = add_caching_to_json(&sub_json, e->op_type, lease_type);
     997           4 :         if (result < 0) {
     998           0 :                 goto failure;
     999             :         }
    1000           4 :         result = add_oplock_to_json(&sub_json, e->op_type, op_str);
    1001           4 :         if (result < 0) {
    1002           0 :                 goto failure;
    1003             :         }
    1004           4 :         add_lease = e->op_type & LEASE_OPLOCK;
    1005           4 :         result = add_lease_to_json(&sub_json, lease_type, e->lease_key, add_lease);
    1006           4 :         if (result < 0) {
    1007           0 :                 goto failure;
    1008             :         }
    1009             : 
    1010           4 :         timestr = timeval_str_buf(&e->time, true, true, &tv_buf);
    1011           4 :         if (timestr == NULL) {
    1012           0 :                 goto failure;
    1013             :         }
    1014           4 :         result = json_add_string(&sub_json, "opened_at", timestr);
    1015           4 :         if (result < 0) {
    1016           0 :                 goto failure;
    1017             :         }
    1018             : 
    1019           4 :         pid = server_id_str_buf(e->pid, &tmp);
    1020           4 :         key = talloc_asprintf(tmp_ctx, "%s/%"PRIu64, pid, e->share_file_id);
    1021           4 :         result = json_add_object(&opens_json, key, &sub_json);
    1022           4 :         if (result < 0) {
    1023           0 :                 goto failure;
    1024             :         }
    1025           4 :         result = json_update_object(parent_json, "opens", &opens_json);
    1026           4 :         if (result < 0) {
    1027           0 :                 goto failure;
    1028             :         }
    1029             : 
    1030           4 :         TALLOC_FREE(tmp_ctx);
    1031           4 :         return 0;
    1032           0 : failure:
    1033           0 :         json_free(&opens_json);
    1034           0 :         json_free(&sub_json);
    1035           0 :         TALLOC_FREE(tmp_ctx);
    1036           0 :         return -1;
    1037             : }
    1038             : 
    1039           4 : static int add_fileid_to_json(struct json_object *parent_json,
    1040             :                               struct file_id fid)
    1041             : {
    1042             :         struct json_object fid_json;
    1043             :         int result;
    1044             : 
    1045           4 :         fid_json = json_new_object();
    1046           4 :         if (json_is_invalid(&fid_json)) {
    1047           0 :                 goto failure;
    1048             :         }
    1049             : 
    1050           4 :         result = json_add_int(&fid_json, "devid", fid.devid);
    1051           4 :         if (result < 0) {
    1052           0 :                 goto failure;
    1053             :         }
    1054           4 :         result = json_add_int(&fid_json, "inode", fid.inode);
    1055           4 :         if (result < 0) {
    1056           0 :                 goto failure;
    1057             :         }
    1058           4 :         result = json_add_int(&fid_json, "extid", fid.extid);
    1059           4 :         if (result < 0) {
    1060           0 :                 goto failure;
    1061             :         }
    1062             : 
    1063           4 :         result = json_add_object(parent_json, "fileid", &fid_json);
    1064           4 :         if (result < 0) {
    1065           0 :                 goto failure;
    1066             :         }
    1067             : 
    1068           4 :         return 0;
    1069           0 : failure:
    1070           0 :         json_free(&fid_json);
    1071           0 :         return -1;
    1072             : }
    1073             : 
    1074           4 : int print_share_mode_json(struct traverse_state *state,
    1075             :                           const struct share_mode_data *d,
    1076             :                           const struct share_mode_entry *e,
    1077             :                           struct file_id fid,
    1078             :                           const char *uid_str,
    1079             :                           const char *op_str,
    1080             :                           uint32_t lease_type,
    1081             :                           const char *filename)
    1082             : {
    1083           4 :         struct json_object locks_json = {
    1084             :                 .valid = false,
    1085             :         };
    1086           4 :         struct json_object file_json = {
    1087             :                 .valid = false,
    1088             :         };
    1089           4 :         char *key = NULL;
    1090           4 :         int result = 0;
    1091             : 
    1092           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1093           4 :         if (tmp_ctx == NULL) {
    1094           0 :                 return -1;
    1095             :         }
    1096             : 
    1097           4 :         if (d->servicepath[strlen(d->servicepath)-1] == '/') {
    1098           0 :                 key = talloc_asprintf(tmp_ctx, "%s%s", d->servicepath, filename);
    1099             :         } else {
    1100           4 :                 key = talloc_asprintf(tmp_ctx, "%s/%s", d->servicepath, filename);
    1101             :         }
    1102             : 
    1103           4 :         locks_json = json_get_object(&state->root_json, "open_files");
    1104           4 :         if (json_is_invalid(&locks_json)) {
    1105           0 :                 goto failure;
    1106             :         }
    1107           4 :         file_json = json_get_object(&locks_json, key);
    1108           4 :         if (json_is_invalid(&file_json)) {
    1109           0 :                 goto failure;
    1110             :         }
    1111             : 
    1112           4 :         result = json_add_string(&file_json, "service_path", d->servicepath);
    1113           4 :         if (result < 0) {
    1114           0 :                 goto failure;
    1115             :         }
    1116           4 :         result = json_add_string(&file_json, "filename", filename);
    1117           4 :         if (result < 0) {
    1118           0 :                 goto failure;
    1119             :         }
    1120           4 :         result = add_fileid_to_json(&file_json, fid);
    1121           4 :         if (result < 0) {
    1122           0 :                 goto failure;
    1123             :         }
    1124           4 :         result = json_add_int(&file_json, "num_pending_deletes", d->num_delete_tokens);
    1125           4 :         if (result < 0) {
    1126           0 :                 goto failure;
    1127             :         }
    1128             : 
    1129           4 :         result = add_open_to_json(&file_json,
    1130             :                                   e,
    1131           4 :                                   state->resolve_uids,
    1132             :                                   op_str,
    1133             :                                   lease_type,
    1134             :                                   uid_str);
    1135           4 :         if (result < 0) {
    1136           0 :                 goto failure;
    1137             :         }
    1138             : 
    1139           4 :         result = json_update_object(&locks_json, key, &file_json);
    1140           4 :         if (result < 0) {
    1141           0 :                 goto failure;
    1142             :         }
    1143           4 :         result = json_update_object(&state->root_json, "open_files", &locks_json);
    1144           4 :         if (result < 0) {
    1145           0 :                 goto failure;
    1146             :         }
    1147             : 
    1148           4 :         TALLOC_FREE(tmp_ctx);
    1149           4 :         return 0;
    1150           0 : failure:
    1151           0 :         json_free(&file_json);
    1152           0 :         json_free(&locks_json);
    1153           0 :         TALLOC_FREE(tmp_ctx);
    1154           0 :         return -1;
    1155             : }
    1156             : 
    1157           0 : static int add_lock_to_json(struct json_object *parent_json,
    1158             :                             struct server_id server_id,
    1159             :                             const char *type,
    1160             :                             enum brl_flavour flavour,
    1161             :                             intmax_t start,
    1162             :                             intmax_t size)
    1163             : {
    1164           0 :         struct json_object sub_json = {
    1165             :                 .valid = false,
    1166             :         };
    1167           0 :         struct json_object locks_json = {
    1168             :                 .valid = false,
    1169             :         };
    1170             :         const char *flavour_str;
    1171           0 :         int result = 0;
    1172             : 
    1173           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1174           0 :         if (tmp_ctx == NULL) {
    1175           0 :                 return -1;
    1176             :         }
    1177             : 
    1178           0 :         locks_json = json_get_array(parent_json, "locks");
    1179           0 :         if (json_is_invalid(&locks_json)) {
    1180           0 :                 goto failure;
    1181             :         }
    1182           0 :         sub_json = json_new_object();
    1183           0 :         if (json_is_invalid(&sub_json)) {
    1184           0 :                 goto failure;
    1185             :         }
    1186             : 
    1187           0 :         result = add_server_id_to_json(&sub_json, server_id);
    1188           0 :         if (result < 0) {
    1189           0 :                 goto failure;
    1190             :         }
    1191           0 :         result = json_add_string(&sub_json, "type", type);
    1192           0 :         if (result < 0) {
    1193           0 :                 goto failure;
    1194             :         }
    1195           0 :         flavour_str = talloc_asprintf(tmp_ctx, "%s%s",
    1196             :                                       (flavour == WINDOWS_LOCK)?"Windows":"",
    1197             :                                       (flavour == POSIX_LOCK)?"Posix":"");
    1198           0 :         result = json_add_string(&sub_json, "flavour", flavour_str);
    1199           0 :         if (result < 0) {
    1200           0 :                 goto failure;
    1201             :         }
    1202           0 :         result = json_add_int(&sub_json, "start", start);
    1203           0 :         if (result < 0) {
    1204           0 :                 goto failure;
    1205             :         }
    1206           0 :         result = json_add_int(&sub_json, "size", size);
    1207           0 :         if (result < 0) {
    1208           0 :                 goto failure;
    1209             :         }
    1210             : 
    1211           0 :         result = json_add_object(&locks_json, NULL, &sub_json);
    1212           0 :         if (result < 0) {
    1213           0 :                 goto failure;
    1214             :         }
    1215           0 :         result = json_update_object(parent_json, "locks", &locks_json);
    1216           0 :         if (result < 0) {
    1217           0 :                 goto failure;
    1218             :         }
    1219             : 
    1220           0 :         TALLOC_FREE(tmp_ctx);
    1221           0 :         return 0;
    1222           0 : failure:
    1223           0 :         json_free(&locks_json);
    1224           0 :         json_free(&sub_json);
    1225           0 :         TALLOC_FREE(tmp_ctx);
    1226           0 :         return -1;
    1227             : }
    1228             : 
    1229           0 : int print_brl_json(struct traverse_state *state,
    1230             :                    const struct server_id server_id,
    1231             :                    struct file_id fid,
    1232             :                    const char *type,
    1233             :                    enum brl_flavour flavour,
    1234             :                    intmax_t start,
    1235             :                    intmax_t size,
    1236             :                    const char *sharepath,
    1237             :                    const char *filename)
    1238             : {
    1239           0 :         struct json_object file_json = {
    1240             :                 .valid = false,
    1241             :         };
    1242           0 :         struct json_object brl_json = {
    1243             :                 .valid = false,
    1244             :         };
    1245           0 :         int result = 0;
    1246             :         char *key;
    1247             : 
    1248           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1249           0 :         if (tmp_ctx == NULL) {
    1250           0 :                 return -1;
    1251             :         }
    1252             : 
    1253           0 :         if (sharepath[strlen(sharepath)-1] == '/') {
    1254           0 :                 key = talloc_asprintf(tmp_ctx, "%s%s", sharepath, filename);
    1255             :         } else {
    1256           0 :                 key = talloc_asprintf(tmp_ctx, "%s/%s", sharepath, filename);
    1257             :         }
    1258           0 :         if (key == NULL) {
    1259           0 :                 goto failure;
    1260             :         }
    1261             : 
    1262           0 :         brl_json = json_get_object(&state->root_json, "byte_range_locks");
    1263           0 :         if (json_is_invalid(&brl_json)) {
    1264           0 :                 goto failure;
    1265             :         }
    1266           0 :         file_json = json_get_object(&brl_json, key);
    1267           0 :         if (json_is_invalid(&file_json)) {
    1268           0 :                 goto failure;
    1269             :         }
    1270             : 
    1271           0 :         result = add_fileid_to_json(&file_json, fid);
    1272           0 :         if (result < 0) {
    1273           0 :                 goto failure;
    1274             :         }
    1275           0 :         result = json_add_string(&file_json, "file_name", filename);
    1276           0 :         if (result < 0) {
    1277           0 :                 goto failure;
    1278             :         }
    1279           0 :         result = json_add_string(&file_json, "share_path", sharepath);
    1280           0 :         if (result < 0) {
    1281           0 :                 goto failure;
    1282             :         }
    1283           0 :         result = add_server_id_to_json(&file_json, server_id);
    1284           0 :         if (result < 0) {
    1285           0 :                 goto failure;
    1286             :         }
    1287           0 :         result = add_lock_to_json(&file_json, server_id, type, flavour, start, size);
    1288           0 :         if (result < 0) {
    1289           0 :                 goto failure;
    1290             :         }
    1291             : 
    1292           0 :         result = json_add_object(&brl_json, key, &file_json);
    1293           0 :         if (result < 0) {
    1294           0 :                 goto failure;
    1295             :         }
    1296           0 :         result = json_update_object(&state->root_json, "byte_range_locks", &brl_json);
    1297           0 :         if (result < 0) {
    1298           0 :                 goto failure;
    1299             :          }
    1300             : 
    1301           0 :         TALLOC_FREE(tmp_ctx);
    1302           0 :         return 0;
    1303           0 : failure:
    1304           0 :         json_free(&file_json);
    1305           0 :         json_free(&brl_json);
    1306           0 :         TALLOC_FREE(tmp_ctx);
    1307           0 :         return -1;
    1308             : }
    1309             : 
    1310           0 : bool print_notify_rec_json(struct traverse_state *state,
    1311             :                            const struct notify_instance *instance,
    1312             :                            const struct server_id server_id,
    1313             :                            const char *path)
    1314             : {
    1315             :         struct json_object sub_json;
    1316             :         struct json_object notify_json;
    1317           0 :         char *filter = NULL;
    1318           0 :         char *subdir_filter = NULL;
    1319             :         struct timeval_buf tv_buf;
    1320             :         struct timeval val;
    1321           0 :         char *time = NULL;
    1322           0 :         char *pid = NULL;
    1323             :         struct server_id_buf tmp;
    1324           0 :         int result = 0;
    1325             : 
    1326           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1327           0 :         if (tmp_ctx == NULL) {
    1328           0 :                 return -1;
    1329             :         }
    1330             : 
    1331           0 :         sub_json = json_new_object();
    1332           0 :         if (json_is_invalid(&sub_json)) {
    1333           0 :                 return false;
    1334             :         }
    1335           0 :         notify_json = json_get_object(&state->root_json, "notifies");
    1336           0 :         if (json_is_invalid(&notify_json)) {
    1337           0 :                 goto failure;
    1338             :         }
    1339             : 
    1340           0 :         result = add_server_id_to_json(&sub_json, server_id);
    1341           0 :         if (result < 0) {
    1342           0 :                 goto failure;
    1343             :         }
    1344           0 :         result = json_add_string(&sub_json, "path", path);
    1345           0 :         if (result < 0) {
    1346           0 :                 goto failure;
    1347             :         }
    1348           0 :         filter = talloc_asprintf(tmp_ctx, "%u", instance->filter);
    1349           0 :         if (filter == NULL) {
    1350           0 :                 goto failure;
    1351             :         }
    1352           0 :         result = json_add_string(&sub_json, "filter", filter);
    1353           0 :         if (result < 0) {
    1354           0 :                 goto failure;
    1355             :         }
    1356           0 :         subdir_filter = talloc_asprintf(tmp_ctx, "%u", instance->subdir_filter);
    1357           0 :         if (subdir_filter == NULL) {
    1358           0 :                 goto failure;
    1359             :         }
    1360           0 :         result = json_add_string(&sub_json, "subdir_filter", subdir_filter);
    1361           0 :         if (result < 0) {
    1362           0 :                 goto failure;
    1363             :         }
    1364           0 :         val = convert_timespec_to_timeval(instance->creation_time);
    1365           0 :         time = timeval_str_buf(&val, true, true, &tv_buf);
    1366           0 :         result = json_add_string(&sub_json, "creation_time", time);
    1367           0 :         if (result < 0) {
    1368           0 :                 goto failure;
    1369             :         }
    1370             : 
    1371           0 :         pid = server_id_str_buf(server_id, &tmp);
    1372           0 :         result = json_add_object(&notify_json, pid, &sub_json);
    1373           0 :         if (result < 0) {
    1374           0 :                 goto failure;
    1375             :         }
    1376             : 
    1377           0 :         result = json_update_object(&state->root_json, "notifies", &notify_json);
    1378           0 :         if (result < 0) {
    1379           0 :                 goto failure;
    1380             :         }
    1381             : 
    1382           0 :         TALLOC_FREE(tmp_ctx);
    1383           0 :         return true;
    1384           0 : failure:
    1385           0 :         json_free(&sub_json);
    1386           0 :         TALLOC_FREE(tmp_ctx);
    1387           0 :         return false;
    1388             : }

Generated by: LCOV version 1.14