LCOV - code coverage report
Current view: top level - source3/utils - status_json.c (source / functions) Hit Total Coverage
Test: coverage report for vadcx-master-patch-75612 fe003de8 Lines: 392 779 50.3 %
Date: 2024-02-29 22:57:05 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_PARTIAL) {
     262           4 :                 degree_str = "partial";
     263             :         } else {
     264           0 :                 degree_str = "full";
     265             :         }
     266             : 
     267          16 :         sub_json = json_new_object();
     268          16 :         if (json_is_invalid(&sub_json)) {
     269           0 :                 goto failure;
     270             :         }
     271             : 
     272          16 :         result = json_add_string(&sub_json, "cipher", cipher);
     273          16 :         if (result < 0) {
     274           0 :                 goto failure;
     275             :         }
     276          16 :         result = json_add_string(&sub_json, "degree", degree_str);
     277          16 :         if (result < 0) {
     278           0 :                 goto failure;
     279             :         }
     280          16 :         result = json_add_object(parent_json, key, &sub_json);
     281          16 :         if (result < 0) {
     282           0 :                 goto failure;
     283             :         }
     284             : 
     285          16 :         return 0;
     286           0 : failure:
     287           0 :         json_free(&sub_json);
     288           0 :         return -1;
     289             : }
     290             : 
     291           4 : static int add_channel_to_json(struct json_object *parent_json,
     292             :                                const struct smbXsrv_channel_global0 *channel)
     293             : {
     294           4 :         TALLOC_CTX *frame = talloc_stackframe();
     295             :         struct json_object sub_json;
     296           4 :         char *id_str = NULL;
     297             :         struct timeval tv;
     298             :         struct timeval_buf tv_buf;
     299           4 :         char *time_str = NULL;
     300             :         int result;
     301             : 
     302           4 :         sub_json = json_new_object();
     303           4 :         if (json_is_invalid(&sub_json)) {
     304           0 :                 goto failure;
     305             :         }
     306             : 
     307           4 :         id_str = talloc_asprintf(frame, "%"PRIu64"", channel->channel_id);
     308           4 :         if (id_str == NULL) {
     309           0 :                 goto failure;
     310             :         }
     311           4 :         result = json_add_string(&sub_json, "channel_id", id_str);
     312           4 :         if (result < 0) {
     313           0 :                 goto failure;
     314             :         }
     315           4 :         nttime_to_timeval(&tv, channel->creation_time);
     316           4 :         time_str = timeval_str_buf(&tv, true, true, &tv_buf);
     317           4 :         if (time_str == NULL) {
     318           0 :                 goto failure;
     319             :         }
     320           4 :         result = json_add_string(&sub_json, "creation_time", time_str);
     321           4 :         if (result < 0) {
     322           0 :                 goto failure;
     323             :         }
     324           4 :         result = json_add_string(&sub_json, "local_address", channel->local_address);
     325           4 :         if (result < 0) {
     326           0 :                 goto failure;
     327             :         }
     328           4 :         result = json_add_string(&sub_json, "remote_address", channel->remote_address);
     329           4 :         if (result < 0) {
     330           0 :                 goto failure;
     331             :         }
     332             : 
     333           4 :         result = json_add_object(parent_json, id_str, &sub_json);
     334           4 :         if (result < 0) {
     335           0 :                 goto failure;
     336             :         }
     337             : 
     338           4 :         TALLOC_FREE(frame);
     339           4 :         return 0;
     340           0 : failure:
     341           0 :         json_free(&sub_json);
     342           0 :         TALLOC_FREE(frame);
     343           0 :         return -1;
     344             : }
     345             : 
     346           4 : static int add_channels_to_json(struct json_object *parent_json,
     347             :                                 const struct smbXsrv_session_global0 *global)
     348             : {
     349             :         struct json_object sub_json;
     350             :         uint32_t i;
     351             :         int result;
     352             : 
     353           4 :         sub_json = json_new_object();
     354           4 :         if (json_is_invalid(&sub_json)) {
     355           0 :                 goto failure;
     356             :         }
     357             : 
     358           8 :         for (i = 0; i < global->num_channels; i++) {
     359           4 :                 const struct smbXsrv_channel_global0 *c = &global->channels[i];
     360             : 
     361           4 :                 result = add_channel_to_json(&sub_json, c);
     362           4 :                 if (result < 0) {
     363           0 :                         goto failure;
     364             :                 }
     365             :         }
     366             : 
     367           4 :         result = json_add_object(parent_json, "channels", &sub_json);
     368           4 :         if (result < 0) {
     369           0 :                 goto failure;
     370             :         }
     371             : 
     372           4 :         return 0;
     373           0 : failure:
     374           0 :         json_free(&sub_json);
     375           0 :         return -1;
     376             : }
     377             : 
     378           4 : int traverse_connections_json(struct traverse_state *state,
     379             :                               const struct connections_data *crec,
     380             :                               const char *encryption_cipher,
     381             :                               enum crypto_degree encryption_degree,
     382             :                               const char *signing_cipher,
     383             :                               enum crypto_degree signing_degree)
     384             : {
     385             :         struct json_object sub_json;
     386             :         struct json_object connections_json;
     387             :         struct timeval tv;
     388             :         struct timeval_buf tv_buf;
     389           4 :         char *time = NULL;
     390           4 :         int result = 0;
     391           4 :         char *sess_id_str = NULL;
     392           4 :         char *tcon_id_str = NULL;
     393             : 
     394           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     395           4 :         if (tmp_ctx == NULL) {
     396           0 :                 return -1;
     397             :         }
     398             : 
     399           4 :         sub_json = json_new_object();
     400           4 :         if (json_is_invalid(&sub_json)) {
     401           0 :                 goto failure;
     402             :         }
     403           4 :         connections_json = json_get_object(&state->root_json, "tcons");
     404           4 :         if (json_is_invalid(&connections_json)) {
     405           0 :                 goto failure;
     406             :         }
     407             : 
     408           4 :         result = json_add_string(&sub_json, "service", crec->servicename);
     409           4 :         if (result < 0) {
     410           0 :                 goto failure;
     411             :         }
     412           4 :         result = add_server_id_to_json(&sub_json, crec->pid);
     413           4 :         if (result < 0) {
     414           0 :                 goto failure;
     415             :         }
     416           4 :         tcon_id_str = talloc_asprintf(tmp_ctx, "%u", crec->cnum);
     417           4 :         if (tcon_id_str == NULL) {
     418           0 :                 goto failure;
     419             :         }
     420           4 :         result = json_add_string(&sub_json, "tcon_id", tcon_id_str);
     421           4 :         if (result < 0) {
     422           0 :                 goto failure;
     423             :         }
     424           4 :         sess_id_str = talloc_asprintf(tmp_ctx, "%u", crec->sess_id);
     425           4 :         if (sess_id_str == NULL) {
     426           0 :                 goto failure;
     427             :         }
     428           4 :         result = json_add_string(&sub_json, "session_id", sess_id_str);
     429           4 :         if (result < 0) {
     430           0 :                 goto failure;
     431             :         }
     432           4 :         result = json_add_string(&sub_json, "machine", crec->machine);
     433           4 :         if (result < 0) {
     434           0 :                 goto failure;
     435             :         }
     436           4 :         nttime_to_timeval(&tv, crec->start);
     437           4 :         time = timeval_str_buf(&tv, true, true, &tv_buf);
     438           4 :         if (time == NULL) {
     439           0 :                 goto failure;
     440             :         }
     441           4 :         result = json_add_string(&sub_json, "connected_at", time);
     442           4 :         if (result < 0) {
     443           0 :                 goto failure;
     444             :         }
     445           4 :         result = add_crypto_to_json(&sub_json, "encryption",
     446             :                                    encryption_cipher, encryption_degree);
     447           4 :         if (result < 0) {
     448           0 :                 goto failure;
     449             :         }
     450           4 :         result = add_crypto_to_json(&sub_json, "signing",
     451             :                                    signing_cipher, signing_degree);
     452           4 :         if (result < 0) {
     453           0 :                 goto failure;
     454             :         }
     455             : 
     456           4 :         result = json_add_object(&connections_json, tcon_id_str, &sub_json);
     457           4 :         if (result < 0) {
     458           0 :                 goto failure;
     459             :         }
     460             : 
     461           4 :         result = json_update_object(&state->root_json, "tcons", &connections_json);
     462           4 :         if (result < 0) {
     463           0 :                 goto failure;
     464             :         }
     465             : 
     466           4 :         TALLOC_FREE(tmp_ctx);
     467           4 :         return 0;
     468           0 : failure:
     469           0 :         json_free(&sub_json);
     470           0 :         TALLOC_FREE(tmp_ctx);
     471           0 :         return -1;
     472             : }
     473             : 
     474           4 : int traverse_sessionid_json(struct traverse_state *state,
     475             :                             struct sessionid *session,
     476             :                             char *uid_str,
     477             :                             char *gid_str,
     478             :                             const char *encryption_cipher,
     479             :                             enum crypto_degree encryption_degree,
     480             :                             const char *signing_cipher,
     481             :                             enum crypto_degree signing_degree,
     482             :                             const char *connection_dialect)
     483             : {
     484             :         struct json_object sub_json;
     485             :         struct json_object session_json;
     486           4 :         int result = 0;
     487           4 :         char *id_str = NULL;
     488             :         struct timeval tv;
     489             :         struct timeval_buf tv_buf;
     490           4 :         char *time_str = NULL;
     491             : 
     492           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     493           4 :         if (tmp_ctx == NULL) {
     494           0 :                 return -1;
     495             :         }
     496             : 
     497           4 :         sub_json = json_new_object();
     498           4 :         if (json_is_invalid(&sub_json)) {
     499           0 :                 goto failure;
     500             :         }
     501             : 
     502           4 :         session_json = json_get_object(&state->root_json, "sessions");
     503           4 :         if (json_is_invalid(&session_json)) {
     504           0 :                 goto failure;
     505             :         }
     506             : 
     507           4 :         id_str = talloc_asprintf(tmp_ctx, "%u", session->id_num);
     508           4 :         result = json_add_string(&sub_json, "session_id", id_str);
     509           4 :         if (result < 0) {
     510           0 :                 goto failure;
     511             :         }
     512           4 :         result = add_server_id_to_json(&sub_json, session->pid);
     513           4 :         if (result < 0) {
     514           0 :                 goto failure;
     515             :         }
     516           4 :         result = json_add_int(&sub_json, "uid", session->uid);
     517           4 :         if (result < 0) {
     518           0 :                 goto failure;
     519             :         }
     520           4 :         result = json_add_int(&sub_json, "gid", session->gid);
     521           4 :         if (result < 0) {
     522           0 :                 goto failure;
     523             :         }
     524           4 :         result = json_add_string(&sub_json, "username", uid_str);
     525           4 :         if (result < 0) {
     526           0 :                 goto failure;
     527             :         }
     528           4 :         result = json_add_string(&sub_json, "groupname", gid_str);
     529           4 :         if (result < 0) {
     530           0 :                 goto failure;
     531             :         }
     532             : 
     533           4 :         nttime_to_timeval(&tv, session->global->creation_time);
     534           4 :         time_str = timeval_str_buf(&tv, true, true, &tv_buf);
     535           4 :         if (time_str == NULL) {
     536           0 :                 goto failure;
     537             :         }
     538           4 :         result = json_add_string(&sub_json, "creation_time", time_str);
     539           4 :         if (result < 0) {
     540           0 :                 goto failure;
     541             :         }
     542             : 
     543           4 :         nttime_to_timeval(&tv, session->global->expiration_time);
     544           4 :         time_str = timeval_str_buf(&tv, true, true, &tv_buf);
     545           4 :         if (time_str == NULL) {
     546           0 :                 goto failure;
     547             :         }
     548           4 :         result = json_add_string(&sub_json, "expiration_time", time_str);
     549           4 :         if (result < 0) {
     550           0 :                 goto failure;
     551             :         }
     552             : 
     553           4 :         nttime_to_timeval(&tv, session->global->auth_time);
     554           4 :         time_str = timeval_str_buf(&tv, true, true, &tv_buf);
     555           4 :         if (time_str == NULL) {
     556           0 :                 goto failure;
     557             :         }
     558           4 :         result = json_add_string(&sub_json, "auth_time", time_str);
     559           4 :         if (result < 0) {
     560           0 :                 goto failure;
     561             :         }
     562             : 
     563           4 :         result = json_add_string(&sub_json, "remote_machine", session->remote_machine);
     564           4 :         if (result < 0) {
     565           0 :                 goto failure;
     566             :         }
     567           4 :         result = json_add_string(&sub_json, "hostname", session->hostname);
     568           4 :         if (result < 0) {
     569           0 :                 goto failure;
     570             :         }
     571           4 :         result = json_add_string(&sub_json, "session_dialect", connection_dialect);
     572           4 :         if (result < 0) {
     573           0 :                 goto failure;
     574             :         }
     575           4 :         result = json_add_guid(&sub_json,
     576             :                                "client_guid",
     577           4 :                                &session->global->client_guid);
     578           4 :         if (result < 0) {
     579           0 :                 goto failure;
     580             :         }
     581           4 :         result = add_crypto_to_json(&sub_json, "encryption",
     582             :                                     encryption_cipher, encryption_degree);
     583           4 :         if (result < 0) {
     584           0 :                 goto failure;
     585             :         }
     586           4 :         result = add_crypto_to_json(&sub_json, "signing",
     587             :                                     signing_cipher, signing_degree);
     588           4 :         if (result < 0) {
     589           0 :                 goto failure;
     590             :         }
     591             : 
     592           4 :         result = add_channels_to_json(&sub_json, session->global);
     593           4 :         if (result < 0) {
     594           0 :                 goto failure;
     595             :         }
     596             : 
     597           4 :         result = json_add_object(&session_json, id_str, &sub_json);
     598           4 :         if (result < 0) {
     599           0 :                 goto failure;
     600             :         }
     601             : 
     602           4 :         result = json_update_object(&state->root_json, "sessions", &session_json);
     603           4 :         if (result < 0) {
     604           0 :                 goto failure;
     605             :         }
     606             : 
     607           4 :         TALLOC_FREE(tmp_ctx);
     608           4 :         return 0;
     609           0 : failure:
     610           0 :         json_free(&sub_json);
     611           0 :         TALLOC_FREE(tmp_ctx);
     612           0 :         return -1;
     613             : }
     614             : 
     615           4 : static int add_access_mode_to_json(struct json_object *parent_json,
     616             :                                    int access_int)
     617             : {
     618             :         struct json_object access_json;
     619           4 :         char *access_hex = NULL;
     620           4 :         const char *access_str = NULL;
     621             :         int result;
     622             : 
     623           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     624           4 :         if (tmp_ctx == NULL) {
     625           0 :                 return -1;
     626             :         }
     627             : 
     628           4 :         access_json = json_new_object();
     629           4 :         if (json_is_invalid(&access_json)) {
     630           0 :                 goto failure;
     631             :         }
     632             : 
     633           4 :         access_hex = talloc_asprintf(tmp_ctx, "0x%08x", access_int);
     634           4 :         result = json_add_string(&access_json, "hex", access_hex);
     635           4 :         if (result < 0) {
     636           0 :                   goto failure;
     637             :         }
     638           4 :         result = map_mask_to_json(&access_json, access_int, access_mask);
     639           4 :         if (result < 0) {
     640           0 :                 goto failure;
     641             :         }
     642             : 
     643           8 :         access_str = talloc_asprintf(tmp_ctx, "%s%s",
     644           4 :                                      (access_int & FILE_READ_DATA)?"R":"",
     645           4 :                                      (access_int & (FILE_WRITE_DATA|FILE_APPEND_DATA))?"W":"");
     646           4 :         result = json_add_string(&access_json, "text", access_str);
     647           4 :         if (result < 0) {
     648           0 :                   goto failure;
     649             :         }
     650             : 
     651           4 :         result = json_add_object(parent_json, "access_mask", &access_json);
     652           4 :         if (result < 0) {
     653           0 :                 goto failure;
     654             :         }
     655             : 
     656           4 :         TALLOC_FREE(tmp_ctx);
     657           4 :         return 0;
     658           0 : failure:
     659           0 :         json_free(&access_json);
     660           0 :         TALLOC_FREE(tmp_ctx);
     661           0 :         return -1;
     662             : }
     663             : 
     664           4 : static int add_caching_to_json(struct json_object *parent_json,
     665             :                               int op_type,
     666             :                               int lease_type)
     667             : {
     668             :         struct json_object caching_json;
     669           4 :         char *hex = NULL;
     670           4 :         char *caching_text = NULL;
     671           4 :         int caching_type = 0;
     672             :         int result;
     673             : 
     674           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     675           4 :         if (tmp_ctx == NULL) {
     676           0 :                 return -1;
     677             :         }
     678             : 
     679           4 :         caching_json = json_new_object();
     680           4 :         if (json_is_invalid(&caching_json)) {
     681           0 :                 goto failure;
     682             :         }
     683             : 
     684           4 :         if (op_type & LEASE_OPLOCK) {
     685           0 :                 caching_type = lease_type;
     686             :         } else {
     687           4 :                 if (op_type & LEVEL_II_OPLOCK) {
     688           0 :                         caching_type = SMB2_LEASE_READ;
     689           4 :                 } else if (op_type & EXCLUSIVE_OPLOCK) {
     690           0 :                         caching_type = SMB2_LEASE_READ + SMB2_LEASE_WRITE;
     691           4 :                 } else if (op_type & BATCH_OPLOCK) {
     692           0 :                         caching_type = SMB2_LEASE_READ + SMB2_LEASE_WRITE + SMB2_LEASE_HANDLE;
     693             :                 }
     694             :         }
     695           4 :         result = map_mask_to_json(&caching_json, caching_type, lease_mask);
     696           4 :         if (result < 0) {
     697           0 :                 goto failure;
     698             :         }
     699             : 
     700           4 :         hex = talloc_asprintf(tmp_ctx, "0x%08x", caching_type);
     701           4 :         if (hex == NULL) {
     702           0 :                 goto failure;
     703             :         }
     704           4 :         result = json_add_string(&caching_json, "hex", hex);
     705           4 :         if (result < 0) {
     706           0 :                 goto failure;
     707             :         }
     708             : 
     709          12 :         caching_text = talloc_asprintf(tmp_ctx, "%s%s%s",
     710           4 :                                        (caching_type & SMB2_LEASE_READ)?"R":"",
     711           4 :                                        (caching_type & SMB2_LEASE_WRITE)?"W":"",
     712           4 :                                        (caching_type & SMB2_LEASE_HANDLE)?"H":"");
     713           4 :         if (caching_text == NULL) {
     714           0 :                 return -1;
     715             :         }
     716             : 
     717           4 :         result = json_add_string(&caching_json, "text", caching_text);
     718           4 :         if (result < 0) {
     719           0 :                 goto failure;
     720             :         }
     721             : 
     722           4 :         result = json_add_object(parent_json, "caching", &caching_json);
     723           4 :         if (result < 0) {
     724           0 :                 goto failure;
     725             :         }
     726             : 
     727           4 :         TALLOC_FREE(tmp_ctx);
     728           4 :         return 0;
     729           0 : failure:
     730           0 :         json_free(&caching_json);
     731           0 :         TALLOC_FREE(tmp_ctx);
     732           0 :         return -1;
     733             : }
     734             : 
     735           4 : static int add_oplock_to_json(struct json_object *parent_json,
     736             :                               uint16_t op_type,
     737             :                               const char *op_str)
     738             : {
     739             :         struct json_object oplock_json;
     740             :         int result;
     741             : 
     742           4 :         oplock_json = json_new_object();
     743           4 :         if (json_is_invalid(&oplock_json)) {
     744           0 :                 goto failure;
     745             :         }
     746             : 
     747           4 :         if (op_type != 0) {
     748           0 :                 result = map_mask_to_json(&oplock_json, op_type, oplock_mask);
     749           0 :                 if (result < 0) {
     750           0 :                         goto failure;
     751             :                 }
     752           0 :                 result = json_add_string(&oplock_json, "text", op_str);
     753           0 :                 if (result < 0) {
     754           0 :                         goto failure;
     755             :                 }
     756             :         }
     757             : 
     758           4 :         result = json_add_object(parent_json, "oplock", &oplock_json);
     759           4 :         if (result < 0) {
     760           0 :                 goto failure;
     761             :         }
     762             : 
     763           4 :         return 0;
     764           0 : failure:
     765           0 :         json_free(&oplock_json);
     766           0 :         return -1;
     767             : }
     768             : 
     769           0 : static int lease_key_to_str(struct smb2_lease_key lease_key,
     770             :                             char *lease_str)
     771             : {
     772           0 :         uint8_t _buf[16] = {0};
     773           0 :         DATA_BLOB blob = data_blob_const(_buf, sizeof(_buf));
     774             :         struct GUID guid;
     775             :         NTSTATUS status;
     776           0 :         char *tmp = NULL;
     777             : 
     778           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     779           0 :         if (tmp_ctx == NULL) {
     780           0 :                 return -1;
     781             :         }
     782             : 
     783           0 :         PUSH_LE_U64(_buf, 0, lease_key.data[0]);
     784           0 :         PUSH_LE_U64(_buf, 8, lease_key.data[1]);
     785             : 
     786           0 :         status = GUID_from_ndr_blob(&blob, &guid);
     787           0 :         if (!NT_STATUS_IS_OK(status)) {
     788           0 :                 goto failure;
     789             :         }
     790           0 :         tmp = GUID_string(tmp_ctx, &guid);
     791           0 :         if (tmp == NULL) {
     792           0 :                 goto failure;
     793             :         }
     794           0 :         fstrcpy(lease_str, tmp);
     795             : 
     796           0 :         TALLOC_FREE(tmp_ctx);
     797           0 :         return 0;
     798           0 : failure:
     799           0 :         TALLOC_FREE(tmp_ctx);
     800           0 :         return -1;
     801             : }
     802             : 
     803           4 : static int add_lease_to_json(struct json_object *parent_json,
     804             :                              int lease_type,
     805             :                              struct smb2_lease_key lease_key,
     806             :                              bool add_lease)
     807             : {
     808             :         struct json_object lease_json;
     809           4 :         char *lease_hex = NULL;
     810           4 :         char *lease_text = NULL;
     811             :         fstring lease_key_str;
     812             :         int result;
     813             : 
     814           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     815           4 :         if (tmp_ctx == NULL) {
     816           0 :                 return -1;
     817             :         }
     818             : 
     819           4 :         lease_json = json_new_object();
     820           4 :         if (json_is_invalid(&lease_json)) {
     821           0 :                 goto failure;
     822             :         }
     823             : 
     824             : 
     825           4 :         if (add_lease) {
     826           0 :                 result = lease_key_to_str(lease_key, lease_key_str);
     827           0 :                 if (result < 0) {
     828           0 :                         goto failure;
     829             :                 }
     830           0 :                 result = json_add_string(&lease_json, "lease_key", lease_key_str);
     831           0 :                 if (result < 0) {
     832           0 :                         goto failure;
     833             :                 }
     834           0 :                 lease_hex = talloc_asprintf(tmp_ctx, "0x%08x", lease_type);
     835           0 :                 result = json_add_string(&lease_json, "hex", lease_hex);
     836           0 :                 if (result < 0) {
     837           0 :                         goto failure;
     838             :                 }
     839           0 :                 if (lease_type > (SMB2_LEASE_WRITE + SMB2_LEASE_HANDLE + SMB2_LEASE_READ)) {
     840           0 :                         result = json_add_bool(&lease_json, "UNKNOWN", true);
     841           0 :                         if (result < 0) {
     842           0 :                                 goto failure;
     843             :                         }
     844             :                 } else {
     845           0 :                         result = map_mask_to_json(&lease_json, lease_type, lease_mask);
     846           0 :                         if (result < 0) {
     847           0 :                                 goto failure;
     848             :                         }
     849             :                 }
     850           0 :                 lease_text = talloc_asprintf(tmp_ctx, "%s%s%s",
     851           0 :                                              (lease_type & SMB2_LEASE_READ)?"R":"",
     852           0 :                                              (lease_type & SMB2_LEASE_WRITE)?"W":"",
     853           0 :                                              (lease_type & SMB2_LEASE_HANDLE)?"H":"");
     854             : 
     855           0 :                 result = json_add_string(&lease_json, "text", lease_text);
     856           0 :                 if (result < 0) {
     857           0 :                         goto failure;
     858             :                 }
     859             :         }
     860             : 
     861           4 :         result = json_add_object(parent_json, "lease", &lease_json);
     862           4 :         if (result < 0) {
     863           0 :                 goto failure;
     864             :         }
     865             : 
     866           4 :         TALLOC_FREE(tmp_ctx);
     867           4 :         return 0;
     868           0 : failure:
     869           0 :         json_free(&lease_json);
     870           0 :         TALLOC_FREE(tmp_ctx);
     871           0 :         return -1;
     872             : }
     873             : 
     874           4 : static int add_sharemode_to_json(struct json_object *parent_json,
     875             :                                  int sharemode)
     876             : {
     877             :         struct json_object sharemode_json;
     878           4 :         char *hex = NULL;
     879           4 :         char *text = NULL;
     880             :         int result;
     881             : 
     882           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     883           4 :         if (tmp_ctx == NULL) {
     884           0 :                 return -1;
     885             :         }
     886             : 
     887           4 :         sharemode_json = json_new_object();
     888           4 :         if (json_is_invalid(&sharemode_json)) {
     889           0 :                 goto failure;
     890             :         }
     891             : 
     892           4 :         hex = talloc_asprintf(tmp_ctx, "0x%08x", sharemode);
     893           4 :         if (hex == NULL) {
     894           0 :                 goto failure;
     895             :         }
     896           4 :         result = json_add_string(&sharemode_json, "hex", hex);
     897           4 :         if (result < 0) {
     898           0 :                 goto failure;
     899             :         }
     900           4 :         result = map_mask_to_json(&sharemode_json, sharemode, sharemode_mask);
     901           4 :         if (result < 0) {
     902           0 :                 goto failure;
     903             :         }
     904             : 
     905          12 :         text = talloc_asprintf(tmp_ctx, "%s%s%s",
     906           4 :                                (sharemode & FILE_SHARE_READ)?"R":"",
     907           4 :                                (sharemode & FILE_SHARE_WRITE)?"W":"",
     908           4 :                                (sharemode & FILE_SHARE_DELETE)?"D":"");
     909           4 :         if (text == NULL) {
     910           0 :                 goto failure;
     911             :         }
     912           4 :         result = json_add_string(&sharemode_json, "text", text);
     913           4 :         if (result < 0) {
     914           0 :                 goto failure;
     915             :         }
     916             : 
     917           4 :         result = json_add_object(parent_json, "sharemode", &sharemode_json);
     918           4 :         if (result < 0) {
     919           0 :                 goto failure;
     920             :         }
     921             : 
     922           4 :         TALLOC_FREE(tmp_ctx);
     923           4 :         return 0;
     924           0 : failure:
     925           0 :         json_free(&sharemode_json);
     926           0 :         TALLOC_FREE(tmp_ctx);
     927           0 :         return -1;
     928             : }
     929             : 
     930           4 : static int add_open_to_json(struct json_object *parent_json,
     931             :                             const struct share_mode_entry *e,
     932             :                             bool resolve_uids,
     933             :                             const char *op_str,
     934             :                             uint32_t lease_type,
     935             :                             const char *uid_str)
     936             : {
     937           4 :         struct json_object sub_json = {
     938             :                 .valid = false,
     939             :         };
     940           4 :         struct json_object opens_json = {
     941             :                 .valid = false,
     942             :         };
     943             :         struct timeval_buf tv_buf;
     944           4 :         int result = 0;
     945             :         char *timestr;
     946           4 :         bool add_lease = false;
     947           4 :         char *key = NULL;
     948           4 :         char *share_file_id = NULL;
     949           4 :         char *pid = NULL;
     950             :         struct server_id_buf tmp;
     951             : 
     952           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     953           4 :         if (tmp_ctx == NULL) {
     954           0 :                 return -1;
     955             :         }
     956             : 
     957           4 :         opens_json = json_get_object(parent_json, "opens");
     958           4 :         if (json_is_invalid(&opens_json)) {
     959           0 :                 goto failure;
     960             :         }
     961           4 :         sub_json = json_new_object();
     962           4 :         if (json_is_invalid(&sub_json)) {
     963           0 :                 goto failure;
     964             :         }
     965             : 
     966             : 
     967           4 :         result = add_server_id_to_json(&sub_json, e->pid);
     968           4 :         if (result < 0) {
     969           0 :                 goto failure;
     970             :         }
     971           4 :         if (resolve_uids) {
     972           0 :                 result = json_add_string(&sub_json, "username", uid_str);
     973           0 :                 if (result < 0) {
     974           0 :                         goto failure;
     975             :                 }
     976             :         }
     977           4 :         result = json_add_int(&sub_json, "uid", e->uid);
     978           4 :         if (result < 0) {
     979           0 :                 goto failure;
     980             :         }
     981           4 :         share_file_id = talloc_asprintf(tmp_ctx, "%"PRIu64, e->share_file_id);
     982           4 :         result = json_add_string(&sub_json, "share_file_id", share_file_id);
     983           4 :         if (result < 0) {
     984           0 :                 goto failure;
     985             :         }
     986           4 :         result = add_sharemode_to_json(&sub_json, e->share_access);
     987           4 :         if (result < 0) {
     988           0 :                 goto failure;
     989             :         }
     990           4 :         result = add_access_mode_to_json(&sub_json, e->access_mask);
     991           4 :         if (result < 0) {
     992           0 :                 goto failure;
     993             :         }
     994           4 :         result = add_caching_to_json(&sub_json, e->op_type, lease_type);
     995           4 :         if (result < 0) {
     996           0 :                 goto failure;
     997             :         }
     998           4 :         result = add_oplock_to_json(&sub_json, e->op_type, op_str);
     999           4 :         if (result < 0) {
    1000           0 :                 goto failure;
    1001             :         }
    1002           4 :         add_lease = e->op_type & LEASE_OPLOCK;
    1003           4 :         result = add_lease_to_json(&sub_json, lease_type, e->lease_key, add_lease);
    1004           4 :         if (result < 0) {
    1005           0 :                 goto failure;
    1006             :         }
    1007             : 
    1008           4 :         timestr = timeval_str_buf(&e->time, true, true, &tv_buf);
    1009           4 :         if (timestr == NULL) {
    1010           0 :                 goto failure;
    1011             :         }
    1012           4 :         result = json_add_string(&sub_json, "opened_at", timestr);
    1013           4 :         if (result < 0) {
    1014           0 :                 goto failure;
    1015             :         }
    1016             : 
    1017           4 :         pid = server_id_str_buf(e->pid, &tmp);
    1018           4 :         key = talloc_asprintf(tmp_ctx, "%s/%"PRIu64, pid, e->share_file_id);
    1019           4 :         result = json_add_object(&opens_json, key, &sub_json);
    1020           4 :         if (result < 0) {
    1021           0 :                 goto failure;
    1022             :         }
    1023           4 :         result = json_update_object(parent_json, "opens", &opens_json);
    1024           4 :         if (result < 0) {
    1025           0 :                 goto failure;
    1026             :         }
    1027             : 
    1028           4 :         TALLOC_FREE(tmp_ctx);
    1029           4 :         return 0;
    1030           0 : failure:
    1031           0 :         json_free(&opens_json);
    1032           0 :         json_free(&sub_json);
    1033           0 :         TALLOC_FREE(tmp_ctx);
    1034           0 :         return -1;
    1035             : }
    1036             : 
    1037           4 : static int add_fileid_to_json(struct json_object *parent_json,
    1038             :                               struct file_id fid)
    1039             : {
    1040             :         struct json_object fid_json;
    1041             :         int result;
    1042             : 
    1043           4 :         fid_json = json_new_object();
    1044           4 :         if (json_is_invalid(&fid_json)) {
    1045           0 :                 goto failure;
    1046             :         }
    1047             : 
    1048           4 :         result = json_add_int(&fid_json, "devid", fid.devid);
    1049           4 :         if (result < 0) {
    1050           0 :                 goto failure;
    1051             :         }
    1052           4 :         result = json_add_int(&fid_json, "inode", fid.inode);
    1053           4 :         if (result < 0) {
    1054           0 :                 goto failure;
    1055             :         }
    1056           4 :         result = json_add_int(&fid_json, "extid", fid.extid);
    1057           4 :         if (result < 0) {
    1058           0 :                 goto failure;
    1059             :         }
    1060             : 
    1061           4 :         result = json_add_object(parent_json, "fileid", &fid_json);
    1062           4 :         if (result < 0) {
    1063           0 :                 goto failure;
    1064             :         }
    1065             : 
    1066           4 :         return 0;
    1067           0 : failure:
    1068           0 :         json_free(&fid_json);
    1069           0 :         return -1;
    1070             : }
    1071             : 
    1072           4 : int print_share_mode_json(struct traverse_state *state,
    1073             :                           const struct share_mode_data *d,
    1074             :                           const struct share_mode_entry *e,
    1075             :                           struct file_id fid,
    1076             :                           const char *uid_str,
    1077             :                           const char *op_str,
    1078             :                           uint32_t lease_type,
    1079             :                           const char *filename)
    1080             : {
    1081           4 :         struct json_object locks_json = {
    1082             :                 .valid = false,
    1083             :         };
    1084           4 :         struct json_object file_json = {
    1085             :                 .valid = false,
    1086             :         };
    1087           4 :         char *key = NULL;
    1088           4 :         int result = 0;
    1089             : 
    1090           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1091           4 :         if (tmp_ctx == NULL) {
    1092           0 :                 return -1;
    1093             :         }
    1094             : 
    1095           4 :         if (d->servicepath[strlen(d->servicepath)-1] == '/') {
    1096           0 :                 key = talloc_asprintf(tmp_ctx, "%s%s", d->servicepath, filename);
    1097             :         } else {
    1098           4 :                 key = talloc_asprintf(tmp_ctx, "%s/%s", d->servicepath, filename);
    1099             :         }
    1100             : 
    1101           4 :         locks_json = json_get_object(&state->root_json, "open_files");
    1102           4 :         if (json_is_invalid(&locks_json)) {
    1103           0 :                 goto failure;
    1104             :         }
    1105           4 :         file_json = json_get_object(&locks_json, key);
    1106           4 :         if (json_is_invalid(&file_json)) {
    1107           0 :                 goto failure;
    1108             :         }
    1109             : 
    1110           4 :         result = json_add_string(&file_json, "service_path", d->servicepath);
    1111           4 :         if (result < 0) {
    1112           0 :                 goto failure;
    1113             :         }
    1114           4 :         result = json_add_string(&file_json, "filename", filename);
    1115           4 :         if (result < 0) {
    1116           0 :                 goto failure;
    1117             :         }
    1118           4 :         result = add_fileid_to_json(&file_json, fid);
    1119           4 :         if (result < 0) {
    1120           0 :                 goto failure;
    1121             :         }
    1122           4 :         result = json_add_int(&file_json, "num_pending_deletes", d->num_delete_tokens);
    1123           4 :         if (result < 0) {
    1124           0 :                 goto failure;
    1125             :         }
    1126             : 
    1127           4 :         result = add_open_to_json(&file_json,
    1128             :                                   e,
    1129           4 :                                   state->resolve_uids,
    1130             :                                   op_str,
    1131             :                                   lease_type,
    1132             :                                   uid_str);
    1133           4 :         if (result < 0) {
    1134           0 :                 goto failure;
    1135             :         }
    1136             : 
    1137           4 :         result = json_update_object(&locks_json, key, &file_json);
    1138           4 :         if (result < 0) {
    1139           0 :                 goto failure;
    1140             :         }
    1141           4 :         result = json_update_object(&state->root_json, "open_files", &locks_json);
    1142           4 :         if (result < 0) {
    1143           0 :                 goto failure;
    1144             :         }
    1145             : 
    1146           4 :         TALLOC_FREE(tmp_ctx);
    1147           4 :         return 0;
    1148           0 : failure:
    1149           0 :         json_free(&file_json);
    1150           0 :         json_free(&locks_json);
    1151           0 :         TALLOC_FREE(tmp_ctx);
    1152           0 :         return -1;
    1153             : }
    1154             : 
    1155           0 : static int add_lock_to_json(struct json_object *parent_json,
    1156             :                             struct server_id server_id,
    1157             :                             const char *type,
    1158             :                             enum brl_flavour flavour,
    1159             :                             intmax_t start,
    1160             :                             intmax_t size)
    1161             : {
    1162           0 :         struct json_object sub_json = {
    1163             :                 .valid = false,
    1164             :         };
    1165           0 :         struct json_object locks_json = {
    1166             :                 .valid = false,
    1167             :         };
    1168             :         const char *flavour_str;
    1169           0 :         int result = 0;
    1170             : 
    1171           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1172           0 :         if (tmp_ctx == NULL) {
    1173           0 :                 return -1;
    1174             :         }
    1175             : 
    1176           0 :         locks_json = json_get_array(parent_json, "locks");
    1177           0 :         if (json_is_invalid(&locks_json)) {
    1178           0 :                 goto failure;
    1179             :         }
    1180           0 :         sub_json = json_new_object();
    1181           0 :         if (json_is_invalid(&sub_json)) {
    1182           0 :                 goto failure;
    1183             :         }
    1184             : 
    1185           0 :         result = add_server_id_to_json(&sub_json, server_id);
    1186           0 :         if (result < 0) {
    1187           0 :                 goto failure;
    1188             :         }
    1189           0 :         result = json_add_string(&sub_json, "type", type);
    1190           0 :         if (result < 0) {
    1191           0 :                 goto failure;
    1192             :         }
    1193           0 :         flavour_str = talloc_asprintf(tmp_ctx, "%s%s",
    1194             :                                       (flavour == WINDOWS_LOCK)?"Windows":"",
    1195             :                                       (flavour == POSIX_LOCK)?"Posix":"");
    1196           0 :         result = json_add_string(&sub_json, "flavour", flavour_str);
    1197           0 :         if (result < 0) {
    1198           0 :                 goto failure;
    1199             :         }
    1200           0 :         result = json_add_int(&sub_json, "start", start);
    1201           0 :         if (result < 0) {
    1202           0 :                 goto failure;
    1203             :         }
    1204           0 :         result = json_add_int(&sub_json, "size", size);
    1205           0 :         if (result < 0) {
    1206           0 :                 goto failure;
    1207             :         }
    1208             : 
    1209           0 :         result = json_add_object(&locks_json, NULL, &sub_json);
    1210           0 :         if (result < 0) {
    1211           0 :                 goto failure;
    1212             :         }
    1213           0 :         result = json_update_object(parent_json, "locks", &locks_json);
    1214           0 :         if (result < 0) {
    1215           0 :                 goto failure;
    1216             :         }
    1217             : 
    1218           0 :         TALLOC_FREE(tmp_ctx);
    1219           0 :         return 0;
    1220           0 : failure:
    1221           0 :         json_free(&locks_json);
    1222           0 :         json_free(&sub_json);
    1223           0 :         TALLOC_FREE(tmp_ctx);
    1224           0 :         return -1;
    1225             : }
    1226             : 
    1227           0 : int print_brl_json(struct traverse_state *state,
    1228             :                    const struct server_id server_id,
    1229             :                    struct file_id fid,
    1230             :                    const char *type,
    1231             :                    enum brl_flavour flavour,
    1232             :                    intmax_t start,
    1233             :                    intmax_t size,
    1234             :                    const char *sharepath,
    1235             :                    const char *filename)
    1236             : {
    1237           0 :         struct json_object file_json = {
    1238             :                 .valid = false,
    1239             :         };
    1240           0 :         struct json_object brl_json = {
    1241             :                 .valid = false,
    1242             :         };
    1243           0 :         int result = 0;
    1244             :         char *key;
    1245             : 
    1246           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1247           0 :         if (tmp_ctx == NULL) {
    1248           0 :                 return -1;
    1249             :         }
    1250             : 
    1251           0 :         if (sharepath[strlen(sharepath)-1] == '/') {
    1252           0 :                 key = talloc_asprintf(tmp_ctx, "%s%s", sharepath, filename);
    1253             :         } else {
    1254           0 :                 key = talloc_asprintf(tmp_ctx, "%s/%s", sharepath, filename);
    1255             :         }
    1256           0 :         if (key == NULL) {
    1257           0 :                 goto failure;
    1258             :         }
    1259             : 
    1260           0 :         brl_json = json_get_object(&state->root_json, "byte_range_locks");
    1261           0 :         if (json_is_invalid(&brl_json)) {
    1262           0 :                 goto failure;
    1263             :         }
    1264           0 :         file_json = json_get_object(&brl_json, key);
    1265           0 :         if (json_is_invalid(&file_json)) {
    1266           0 :                 goto failure;
    1267             :         }
    1268             : 
    1269           0 :         result = add_fileid_to_json(&file_json, fid);
    1270           0 :         if (result < 0) {
    1271           0 :                 goto failure;
    1272             :         }
    1273           0 :         result = json_add_string(&file_json, "file_name", filename);
    1274           0 :         if (result < 0) {
    1275           0 :                 goto failure;
    1276             :         }
    1277           0 :         result = json_add_string(&file_json, "share_path", sharepath);
    1278           0 :         if (result < 0) {
    1279           0 :                 goto failure;
    1280             :         }
    1281           0 :         result = add_server_id_to_json(&file_json, server_id);
    1282           0 :         if (result < 0) {
    1283           0 :                 goto failure;
    1284             :         }
    1285           0 :         result = add_lock_to_json(&file_json, server_id, type, flavour, start, size);
    1286           0 :         if (result < 0) {
    1287           0 :                 goto failure;
    1288             :         }
    1289             : 
    1290           0 :         result = json_add_object(&brl_json, key, &file_json);
    1291           0 :         if (result < 0) {
    1292           0 :                 goto failure;
    1293             :         }
    1294           0 :         result = json_update_object(&state->root_json, "byte_range_locks", &brl_json);
    1295           0 :         if (result < 0) {
    1296           0 :                 goto failure;
    1297             :          }
    1298             : 
    1299           0 :         TALLOC_FREE(tmp_ctx);
    1300           0 :         return 0;
    1301           0 : failure:
    1302           0 :         json_free(&file_json);
    1303           0 :         json_free(&brl_json);
    1304           0 :         TALLOC_FREE(tmp_ctx);
    1305           0 :         return -1;
    1306             : }
    1307             : 
    1308           0 : bool print_notify_rec_json(struct traverse_state *state,
    1309             :                            const struct notify_instance *instance,
    1310             :                            const struct server_id server_id,
    1311             :                            const char *path)
    1312             : {
    1313             :         struct json_object sub_json;
    1314             :         struct json_object notify_json;
    1315           0 :         char *filter = NULL;
    1316           0 :         char *subdir_filter = NULL;
    1317             :         struct timeval_buf tv_buf;
    1318             :         struct timeval val;
    1319           0 :         char *time = NULL;
    1320           0 :         char *pid = NULL;
    1321             :         struct server_id_buf tmp;
    1322           0 :         int result = 0;
    1323             : 
    1324           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1325           0 :         if (tmp_ctx == NULL) {
    1326           0 :                 return -1;
    1327             :         }
    1328             : 
    1329           0 :         sub_json = json_new_object();
    1330           0 :         if (json_is_invalid(&sub_json)) {
    1331           0 :                 return false;
    1332             :         }
    1333           0 :         notify_json = json_get_object(&state->root_json, "notifies");
    1334           0 :         if (json_is_invalid(&notify_json)) {
    1335           0 :                 goto failure;
    1336             :         }
    1337             : 
    1338           0 :         result = add_server_id_to_json(&sub_json, server_id);
    1339           0 :         if (result < 0) {
    1340           0 :                 goto failure;
    1341             :         }
    1342           0 :         result = json_add_string(&sub_json, "path", path);
    1343           0 :         if (result < 0) {
    1344           0 :                 goto failure;
    1345             :         }
    1346           0 :         filter = talloc_asprintf(tmp_ctx, "%u", instance->filter);
    1347           0 :         if (filter == NULL) {
    1348           0 :                 goto failure;
    1349             :         }
    1350           0 :         result = json_add_string(&sub_json, "filter", filter);
    1351           0 :         if (result < 0) {
    1352           0 :                 goto failure;
    1353             :         }
    1354           0 :         subdir_filter = talloc_asprintf(tmp_ctx, "%u", instance->subdir_filter);
    1355           0 :         if (subdir_filter == NULL) {
    1356           0 :                 goto failure;
    1357             :         }
    1358           0 :         result = json_add_string(&sub_json, "subdir_filter", subdir_filter);
    1359           0 :         if (result < 0) {
    1360           0 :                 goto failure;
    1361             :         }
    1362           0 :         val = convert_timespec_to_timeval(instance->creation_time);
    1363           0 :         time = timeval_str_buf(&val, true, true, &tv_buf);
    1364           0 :         result = json_add_string(&sub_json, "creation_time", time);
    1365           0 :         if (result < 0) {
    1366           0 :                 goto failure;
    1367             :         }
    1368             : 
    1369           0 :         pid = server_id_str_buf(server_id, &tmp);
    1370           0 :         result = json_add_object(&notify_json, pid, &sub_json);
    1371           0 :         if (result < 0) {
    1372           0 :                 goto failure;
    1373             :         }
    1374             : 
    1375           0 :         result = json_update_object(&state->root_json, "notifies", &notify_json);
    1376           0 :         if (result < 0) {
    1377           0 :                 goto failure;
    1378             :         }
    1379             : 
    1380           0 :         TALLOC_FREE(tmp_ctx);
    1381           0 :         return true;
    1382           0 : failure:
    1383           0 :         json_free(&sub_json);
    1384           0 :         TALLOC_FREE(tmp_ctx);
    1385           0 :         return false;
    1386             : }

Generated by: LCOV version 1.14