LCOV - code coverage report
Current view: top level - source3/utils - status_json.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 376 757 49.7 %
Date: 2024-04-13 12:30:31 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             : 
     489           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     490           4 :         if (tmp_ctx == NULL) {
     491           0 :                 return -1;
     492             :         }
     493             : 
     494           4 :         sub_json = json_new_object();
     495           4 :         if (json_is_invalid(&sub_json)) {
     496           0 :                 goto failure;
     497             :         }
     498             : 
     499           4 :         session_json = json_get_object(&state->root_json, "sessions");
     500           4 :         if (json_is_invalid(&session_json)) {
     501           0 :                 goto failure;
     502             :         }
     503             : 
     504           4 :         id_str = talloc_asprintf(tmp_ctx, "%u", session->id_num);
     505           4 :         result = json_add_string(&sub_json, "session_id", id_str);
     506           4 :         if (result < 0) {
     507           0 :                 goto failure;
     508             :         }
     509           4 :         result = add_server_id_to_json(&sub_json, session->pid);
     510           4 :         if (result < 0) {
     511           0 :                 goto failure;
     512             :         }
     513           4 :         result = json_add_int(&sub_json, "uid", session->uid);
     514           4 :         if (result < 0) {
     515           0 :                 goto failure;
     516             :         }
     517           4 :         result = json_add_int(&sub_json, "gid", session->gid);
     518           4 :         if (result < 0) {
     519           0 :                 goto failure;
     520             :         }
     521           4 :         result = json_add_string(&sub_json, "username", uid_str);
     522           4 :         if (result < 0) {
     523           0 :                 goto failure;
     524             :         }
     525           4 :         result = json_add_string(&sub_json, "groupname", gid_str);
     526           4 :         if (result < 0) {
     527           0 :                 goto failure;
     528             :         }
     529           4 :         result = json_add_string(&sub_json, "remote_machine", session->remote_machine);
     530           4 :         if (result < 0) {
     531           0 :                 goto failure;
     532             :         }
     533           4 :         result = json_add_string(&sub_json, "hostname", session->hostname);
     534           4 :         if (result < 0) {
     535           0 :                 goto failure;
     536             :         }
     537           4 :         result = json_add_string(&sub_json, "session_dialect", connection_dialect);
     538           4 :         if (result < 0) {
     539           0 :                 goto failure;
     540             :         }
     541           4 :         result = json_add_guid(&sub_json,
     542             :                                "client_guid",
     543           4 :                                &session->global->client_guid);
     544           4 :         if (result < 0) {
     545           0 :                 goto failure;
     546             :         }
     547           4 :         result = add_crypto_to_json(&sub_json, "encryption",
     548             :                                     encryption_cipher, encryption_degree);
     549           4 :         if (result < 0) {
     550           0 :                 goto failure;
     551             :         }
     552           4 :         result = add_crypto_to_json(&sub_json, "signing",
     553             :                                     signing_cipher, signing_degree);
     554           4 :         if (result < 0) {
     555           0 :                 goto failure;
     556             :         }
     557             : 
     558           4 :         result = add_channels_to_json(&sub_json, session->global);
     559           4 :         if (result < 0) {
     560           0 :                 goto failure;
     561             :         }
     562             : 
     563           4 :         result = json_add_object(&session_json, id_str, &sub_json);
     564           4 :         if (result < 0) {
     565           0 :                 goto failure;
     566             :         }
     567             : 
     568           4 :         result = json_update_object(&state->root_json, "sessions", &session_json);
     569           4 :         if (result < 0) {
     570           0 :                 goto failure;
     571             :         }
     572             : 
     573           4 :         TALLOC_FREE(tmp_ctx);
     574           4 :         return 0;
     575           0 : failure:
     576           0 :         json_free(&sub_json);
     577           0 :         TALLOC_FREE(tmp_ctx);
     578           0 :         return -1;
     579             : }
     580             : 
     581           4 : static int add_access_mode_to_json(struct json_object *parent_json,
     582             :                                    int access_int)
     583             : {
     584             :         struct json_object access_json;
     585           4 :         char *access_hex = NULL;
     586           4 :         const char *access_str = NULL;
     587             :         int result;
     588             : 
     589           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     590           4 :         if (tmp_ctx == NULL) {
     591           0 :                 return -1;
     592             :         }
     593             : 
     594           4 :         access_json = json_new_object();
     595           4 :         if (json_is_invalid(&access_json)) {
     596           0 :                 goto failure;
     597             :         }
     598             : 
     599           4 :         access_hex = talloc_asprintf(tmp_ctx, "0x%08x", access_int);
     600           4 :         result = json_add_string(&access_json, "hex", access_hex);
     601           4 :         if (result < 0) {
     602           0 :                   goto failure;
     603             :         }
     604           4 :         result = map_mask_to_json(&access_json, access_int, access_mask);
     605           4 :         if (result < 0) {
     606           0 :                 goto failure;
     607             :         }
     608             : 
     609           8 :         access_str = talloc_asprintf(tmp_ctx, "%s%s",
     610           4 :                                      (access_int & FILE_READ_DATA)?"R":"",
     611           4 :                                      (access_int & (FILE_WRITE_DATA|FILE_APPEND_DATA))?"W":"");
     612           4 :         result = json_add_string(&access_json, "text", access_str);
     613           4 :         if (result < 0) {
     614           0 :                   goto failure;
     615             :         }
     616             : 
     617           4 :         result = json_add_object(parent_json, "access_mask", &access_json);
     618           4 :         if (result < 0) {
     619           0 :                 goto failure;
     620             :         }
     621             : 
     622           4 :         TALLOC_FREE(tmp_ctx);
     623           4 :         return 0;
     624           0 : failure:
     625           0 :         json_free(&access_json);
     626           0 :         TALLOC_FREE(tmp_ctx);
     627           0 :         return -1;
     628             : }
     629             : 
     630           4 : static int add_caching_to_json(struct json_object *parent_json,
     631             :                               int op_type,
     632             :                               int lease_type)
     633             : {
     634             :         struct json_object caching_json;
     635           4 :         char *hex = NULL;
     636           4 :         char *caching_text = NULL;
     637           4 :         int caching_type = 0;
     638             :         int result;
     639             : 
     640           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     641           4 :         if (tmp_ctx == NULL) {
     642           0 :                 return -1;
     643             :         }
     644             : 
     645           4 :         caching_json = json_new_object();
     646           4 :         if (json_is_invalid(&caching_json)) {
     647           0 :                 goto failure;
     648             :         }
     649             : 
     650           4 :         if (op_type & LEASE_OPLOCK) {
     651           0 :                 caching_type = lease_type;
     652             :         } else {
     653           4 :                 if (op_type & LEVEL_II_OPLOCK) {
     654           0 :                         caching_type = SMB2_LEASE_READ;
     655           4 :                 } else if (op_type & EXCLUSIVE_OPLOCK) {
     656           0 :                         caching_type = SMB2_LEASE_READ + SMB2_LEASE_WRITE;
     657           4 :                 } else if (op_type & BATCH_OPLOCK) {
     658           0 :                         caching_type = SMB2_LEASE_READ + SMB2_LEASE_WRITE + SMB2_LEASE_HANDLE;
     659             :                 }
     660             :         }
     661           4 :         result = map_mask_to_json(&caching_json, caching_type, lease_mask);
     662           4 :         if (result < 0) {
     663           0 :                 goto failure;
     664             :         }
     665             : 
     666           4 :         hex = talloc_asprintf(tmp_ctx, "0x%08x", caching_type);
     667           4 :         if (hex == NULL) {
     668           0 :                 goto failure;
     669             :         }
     670           4 :         result = json_add_string(&caching_json, "hex", hex);
     671           4 :         if (result < 0) {
     672           0 :                 goto failure;
     673             :         }
     674             : 
     675          12 :         caching_text = talloc_asprintf(tmp_ctx, "%s%s%s",
     676           4 :                                        (caching_type & SMB2_LEASE_READ)?"R":"",
     677           4 :                                        (caching_type & SMB2_LEASE_WRITE)?"W":"",
     678           4 :                                        (caching_type & SMB2_LEASE_HANDLE)?"H":"");
     679           4 :         if (caching_text == NULL) {
     680           0 :                 return -1;
     681             :         }
     682             : 
     683           4 :         result = json_add_string(&caching_json, "text", caching_text);
     684           4 :         if (result < 0) {
     685           0 :                 goto failure;
     686             :         }
     687             : 
     688           4 :         result = json_add_object(parent_json, "caching", &caching_json);
     689           4 :         if (result < 0) {
     690           0 :                 goto failure;
     691             :         }
     692             : 
     693           4 :         TALLOC_FREE(tmp_ctx);
     694           4 :         return 0;
     695           0 : failure:
     696           0 :         json_free(&caching_json);
     697           0 :         TALLOC_FREE(tmp_ctx);
     698           0 :         return -1;
     699             : }
     700             : 
     701           4 : static int add_oplock_to_json(struct json_object *parent_json,
     702             :                               uint16_t op_type,
     703             :                               const char *op_str)
     704             : {
     705             :         struct json_object oplock_json;
     706             :         int result;
     707             : 
     708           4 :         oplock_json = json_new_object();
     709           4 :         if (json_is_invalid(&oplock_json)) {
     710           0 :                 goto failure;
     711             :         }
     712             : 
     713           4 :         if (op_type != 0) {
     714           0 :                 result = map_mask_to_json(&oplock_json, op_type, oplock_mask);
     715           0 :                 if (result < 0) {
     716           0 :                         goto failure;
     717             :                 }
     718           0 :                 result = json_add_string(&oplock_json, "text", op_str);
     719           0 :                 if (result < 0) {
     720           0 :                         goto failure;
     721             :                 }
     722             :         }
     723             : 
     724           4 :         result = json_add_object(parent_json, "oplock", &oplock_json);
     725           4 :         if (result < 0) {
     726           0 :                 goto failure;
     727             :         }
     728             : 
     729           4 :         return 0;
     730           0 : failure:
     731           0 :         json_free(&oplock_json);
     732           0 :         return -1;
     733             : }
     734             : 
     735           0 : static int lease_key_to_str(struct smb2_lease_key lease_key,
     736             :                             char *lease_str)
     737             : {
     738           0 :         uint8_t _buf[16] = {0};
     739           0 :         DATA_BLOB blob = data_blob_const(_buf, sizeof(_buf));
     740             :         struct GUID guid;
     741             :         NTSTATUS status;
     742           0 :         char *tmp = NULL;
     743             : 
     744           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     745           0 :         if (tmp_ctx == NULL) {
     746           0 :                 return -1;
     747             :         }
     748             : 
     749           0 :         PUSH_LE_U64(_buf, 0, lease_key.data[0]);
     750           0 :         PUSH_LE_U64(_buf, 8, lease_key.data[1]);
     751             : 
     752           0 :         status = GUID_from_ndr_blob(&blob, &guid);
     753           0 :         if (!NT_STATUS_IS_OK(status)) {
     754           0 :                 goto failure;
     755             :         }
     756           0 :         tmp = GUID_string(tmp_ctx, &guid);
     757           0 :         if (tmp == NULL) {
     758           0 :                 goto failure;
     759             :         }
     760           0 :         fstrcpy(lease_str, tmp);
     761             : 
     762           0 :         TALLOC_FREE(tmp_ctx);
     763           0 :         return 0;
     764           0 : failure:
     765           0 :         TALLOC_FREE(tmp_ctx);
     766           0 :         return -1;
     767             : }
     768             : 
     769           4 : static int add_lease_to_json(struct json_object *parent_json,
     770             :                              int lease_type,
     771             :                              struct smb2_lease_key lease_key,
     772             :                              bool add_lease)
     773             : {
     774             :         struct json_object lease_json;
     775           4 :         char *lease_hex = NULL;
     776           4 :         char *lease_text = NULL;
     777             :         fstring lease_key_str;
     778             :         int result;
     779             : 
     780           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     781           4 :         if (tmp_ctx == NULL) {
     782           0 :                 return -1;
     783             :         }
     784             : 
     785           4 :         lease_json = json_new_object();
     786           4 :         if (json_is_invalid(&lease_json)) {
     787           0 :                 goto failure;
     788             :         }
     789             : 
     790             : 
     791           4 :         if (add_lease) {
     792           0 :                 result = lease_key_to_str(lease_key, lease_key_str);
     793           0 :                 if (result < 0) {
     794           0 :                         goto failure;
     795             :                 }
     796           0 :                 result = json_add_string(&lease_json, "lease_key", lease_key_str);
     797           0 :                 if (result < 0) {
     798           0 :                         goto failure;
     799             :                 }
     800           0 :                 lease_hex = talloc_asprintf(tmp_ctx, "0x%08x", lease_type);
     801           0 :                 result = json_add_string(&lease_json, "hex", lease_hex);
     802           0 :                 if (result < 0) {
     803           0 :                         goto failure;
     804             :                 }
     805           0 :                 if (lease_type > (SMB2_LEASE_WRITE + SMB2_LEASE_HANDLE + SMB2_LEASE_READ)) {
     806           0 :                         result = json_add_bool(&lease_json, "UNKNOWN", true);
     807           0 :                         if (result < 0) {
     808           0 :                                 goto failure;
     809             :                         }
     810             :                 } else {
     811           0 :                         result = map_mask_to_json(&lease_json, lease_type, lease_mask);
     812           0 :                         if (result < 0) {
     813           0 :                                 goto failure;
     814             :                         }
     815             :                 }
     816           0 :                 lease_text = talloc_asprintf(tmp_ctx, "%s%s%s",
     817           0 :                                              (lease_type & SMB2_LEASE_READ)?"R":"",
     818           0 :                                              (lease_type & SMB2_LEASE_WRITE)?"W":"",
     819           0 :                                              (lease_type & SMB2_LEASE_HANDLE)?"H":"");
     820             : 
     821           0 :                 result = json_add_string(&lease_json, "text", lease_text);
     822           0 :                 if (result < 0) {
     823           0 :                         goto failure;
     824             :                 }
     825             :         }
     826             : 
     827           4 :         result = json_add_object(parent_json, "lease", &lease_json);
     828           4 :         if (result < 0) {
     829           0 :                 goto failure;
     830             :         }
     831             : 
     832           4 :         TALLOC_FREE(tmp_ctx);
     833           4 :         return 0;
     834           0 : failure:
     835           0 :         json_free(&lease_json);
     836           0 :         TALLOC_FREE(tmp_ctx);
     837           0 :         return -1;
     838             : }
     839             : 
     840           4 : static int add_sharemode_to_json(struct json_object *parent_json,
     841             :                                  int sharemode)
     842             : {
     843             :         struct json_object sharemode_json;
     844           4 :         char *hex = NULL;
     845           4 :         char *text = NULL;
     846             :         int result;
     847             : 
     848           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     849           4 :         if (tmp_ctx == NULL) {
     850           0 :                 return -1;
     851             :         }
     852             : 
     853           4 :         sharemode_json = json_new_object();
     854           4 :         if (json_is_invalid(&sharemode_json)) {
     855           0 :                 goto failure;
     856             :         }
     857             : 
     858           4 :         hex = talloc_asprintf(tmp_ctx, "0x%08x", sharemode);
     859           4 :         if (hex == NULL) {
     860           0 :                 goto failure;
     861             :         }
     862           4 :         result = json_add_string(&sharemode_json, "hex", hex);
     863           4 :         if (result < 0) {
     864           0 :                 goto failure;
     865             :         }
     866           4 :         result = map_mask_to_json(&sharemode_json, sharemode, sharemode_mask);
     867           4 :         if (result < 0) {
     868           0 :                 goto failure;
     869             :         }
     870             : 
     871          12 :         text = talloc_asprintf(tmp_ctx, "%s%s%s",
     872           4 :                                (sharemode & FILE_SHARE_READ)?"R":"",
     873           4 :                                (sharemode & FILE_SHARE_WRITE)?"W":"",
     874           4 :                                (sharemode & FILE_SHARE_DELETE)?"D":"");
     875           4 :         if (text == NULL) {
     876           0 :                 goto failure;
     877             :         }
     878           4 :         result = json_add_string(&sharemode_json, "text", text);
     879           4 :         if (result < 0) {
     880           0 :                 goto failure;
     881             :         }
     882             : 
     883           4 :         result = json_add_object(parent_json, "sharemode", &sharemode_json);
     884           4 :         if (result < 0) {
     885           0 :                 goto failure;
     886             :         }
     887             : 
     888           4 :         TALLOC_FREE(tmp_ctx);
     889           4 :         return 0;
     890           0 : failure:
     891           0 :         json_free(&sharemode_json);
     892           0 :         TALLOC_FREE(tmp_ctx);
     893           0 :         return -1;
     894             : }
     895             : 
     896           4 : static int add_open_to_json(struct json_object *parent_json,
     897             :                             const struct share_mode_entry *e,
     898             :                             bool resolve_uids,
     899             :                             const char *op_str,
     900             :                             uint32_t lease_type,
     901             :                             const char *uid_str)
     902             : {
     903           4 :         struct json_object sub_json = {
     904             :                 .valid = false,
     905             :         };
     906           4 :         struct json_object opens_json = {
     907             :                 .valid = false,
     908             :         };
     909             :         struct timeval_buf tv_buf;
     910           4 :         int result = 0;
     911             :         char *timestr;
     912           4 :         bool add_lease = false;
     913           4 :         char *key = NULL;
     914           4 :         char *share_file_id = NULL;
     915           4 :         char *pid = NULL;
     916             :         struct server_id_buf tmp;
     917             : 
     918           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     919           4 :         if (tmp_ctx == NULL) {
     920           0 :                 return -1;
     921             :         }
     922             : 
     923           4 :         opens_json = json_get_object(parent_json, "opens");
     924           4 :         if (json_is_invalid(&opens_json)) {
     925           0 :                 goto failure;
     926             :         }
     927           4 :         sub_json = json_new_object();
     928           4 :         if (json_is_invalid(&sub_json)) {
     929           0 :                 goto failure;
     930             :         }
     931             : 
     932             : 
     933           4 :         result = add_server_id_to_json(&sub_json, e->pid);
     934           4 :         if (result < 0) {
     935           0 :                 goto failure;
     936             :         }
     937           4 :         if (resolve_uids) {
     938           0 :                 result = json_add_string(&sub_json, "username", uid_str);
     939           0 :                 if (result < 0) {
     940           0 :                         goto failure;
     941             :                 }
     942             :         }
     943           4 :         result = json_add_int(&sub_json, "uid", e->uid);
     944           4 :         if (result < 0) {
     945           0 :                 goto failure;
     946             :         }
     947           4 :         share_file_id = talloc_asprintf(tmp_ctx, "%"PRIu64, e->share_file_id);
     948           4 :         result = json_add_string(&sub_json, "share_file_id", share_file_id);
     949           4 :         if (result < 0) {
     950           0 :                 goto failure;
     951             :         }
     952           4 :         result = add_sharemode_to_json(&sub_json, e->share_access);
     953           4 :         if (result < 0) {
     954           0 :                 goto failure;
     955             :         }
     956           4 :         result = add_access_mode_to_json(&sub_json, e->access_mask);
     957           4 :         if (result < 0) {
     958           0 :                 goto failure;
     959             :         }
     960           4 :         result = add_caching_to_json(&sub_json, e->op_type, lease_type);
     961           4 :         if (result < 0) {
     962           0 :                 goto failure;
     963             :         }
     964           4 :         result = add_oplock_to_json(&sub_json, e->op_type, op_str);
     965           4 :         if (result < 0) {
     966           0 :                 goto failure;
     967             :         }
     968           4 :         add_lease = e->op_type & LEASE_OPLOCK;
     969           4 :         result = add_lease_to_json(&sub_json, lease_type, e->lease_key, add_lease);
     970           4 :         if (result < 0) {
     971           0 :                 goto failure;
     972             :         }
     973             : 
     974           4 :         timestr = timeval_str_buf(&e->time, true, true, &tv_buf);
     975           4 :         if (timestr == NULL) {
     976           0 :                 goto failure;
     977             :         }
     978           4 :         result = json_add_string(&sub_json, "opened_at", timestr);
     979           4 :         if (result < 0) {
     980           0 :                 goto failure;
     981             :         }
     982             : 
     983           4 :         pid = server_id_str_buf(e->pid, &tmp);
     984           4 :         key = talloc_asprintf(tmp_ctx, "%s/%"PRIu64, pid, e->share_file_id);
     985           4 :         result = json_add_object(&opens_json, key, &sub_json);
     986           4 :         if (result < 0) {
     987           0 :                 goto failure;
     988             :         }
     989           4 :         result = json_update_object(parent_json, "opens", &opens_json);
     990           4 :         if (result < 0) {
     991           0 :                 goto failure;
     992             :         }
     993             : 
     994           4 :         TALLOC_FREE(tmp_ctx);
     995           4 :         return 0;
     996           0 : failure:
     997           0 :         json_free(&opens_json);
     998           0 :         json_free(&sub_json);
     999           0 :         TALLOC_FREE(tmp_ctx);
    1000           0 :         return -1;
    1001             : }
    1002             : 
    1003           4 : static int add_fileid_to_json(struct json_object *parent_json,
    1004             :                               struct file_id fid)
    1005             : {
    1006             :         struct json_object fid_json;
    1007             :         int result;
    1008             : 
    1009           4 :         fid_json = json_new_object();
    1010           4 :         if (json_is_invalid(&fid_json)) {
    1011           0 :                 goto failure;
    1012             :         }
    1013             : 
    1014           4 :         result = json_add_int(&fid_json, "devid", fid.devid);
    1015           4 :         if (result < 0) {
    1016           0 :                 goto failure;
    1017             :         }
    1018           4 :         result = json_add_int(&fid_json, "inode", fid.inode);
    1019           4 :         if (result < 0) {
    1020           0 :                 goto failure;
    1021             :         }
    1022           4 :         result = json_add_int(&fid_json, "extid", fid.extid);
    1023           4 :         if (result < 0) {
    1024           0 :                 goto failure;
    1025             :         }
    1026             : 
    1027           4 :         result = json_add_object(parent_json, "fileid", &fid_json);
    1028           4 :         if (result < 0) {
    1029           0 :                 goto failure;
    1030             :         }
    1031             : 
    1032           4 :         return 0;
    1033           0 : failure:
    1034           0 :         json_free(&fid_json);
    1035           0 :         return -1;
    1036             : }
    1037             : 
    1038           4 : int print_share_mode_json(struct traverse_state *state,
    1039             :                           const struct share_mode_data *d,
    1040             :                           const struct share_mode_entry *e,
    1041             :                           struct file_id fid,
    1042             :                           const char *uid_str,
    1043             :                           const char *op_str,
    1044             :                           uint32_t lease_type,
    1045             :                           const char *filename)
    1046             : {
    1047           4 :         struct json_object locks_json = {
    1048             :                 .valid = false,
    1049             :         };
    1050           4 :         struct json_object file_json = {
    1051             :                 .valid = false,
    1052             :         };
    1053           4 :         char *key = NULL;
    1054           4 :         int result = 0;
    1055             : 
    1056           4 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1057           4 :         if (tmp_ctx == NULL) {
    1058           0 :                 return -1;
    1059             :         }
    1060             : 
    1061           4 :         if (d->servicepath[strlen(d->servicepath)-1] == '/') {
    1062           0 :                 key = talloc_asprintf(tmp_ctx, "%s%s", d->servicepath, filename);
    1063             :         } else {
    1064           4 :                 key = talloc_asprintf(tmp_ctx, "%s/%s", d->servicepath, filename);
    1065             :         }
    1066             : 
    1067           4 :         locks_json = json_get_object(&state->root_json, "open_files");
    1068           4 :         if (json_is_invalid(&locks_json)) {
    1069           0 :                 goto failure;
    1070             :         }
    1071           4 :         file_json = json_get_object(&locks_json, key);
    1072           4 :         if (json_is_invalid(&file_json)) {
    1073           0 :                 goto failure;
    1074             :         }
    1075             : 
    1076           4 :         result = json_add_string(&file_json, "service_path", d->servicepath);
    1077           4 :         if (result < 0) {
    1078           0 :                 goto failure;
    1079             :         }
    1080           4 :         result = json_add_string(&file_json, "filename", filename);
    1081           4 :         if (result < 0) {
    1082           0 :                 goto failure;
    1083             :         }
    1084           4 :         result = add_fileid_to_json(&file_json, fid);
    1085           4 :         if (result < 0) {
    1086           0 :                 goto failure;
    1087             :         }
    1088           4 :         result = json_add_int(&file_json, "num_pending_deletes", d->num_delete_tokens);
    1089           4 :         if (result < 0) {
    1090           0 :                 goto failure;
    1091             :         }
    1092             : 
    1093           4 :         result = add_open_to_json(&file_json,
    1094             :                                   e,
    1095           4 :                                   state->resolve_uids,
    1096             :                                   op_str,
    1097             :                                   lease_type,
    1098             :                                   uid_str);
    1099           4 :         if (result < 0) {
    1100           0 :                 goto failure;
    1101             :         }
    1102             : 
    1103           4 :         result = json_update_object(&locks_json, key, &file_json);
    1104           4 :         if (result < 0) {
    1105           0 :                 goto failure;
    1106             :         }
    1107           4 :         result = json_update_object(&state->root_json, "open_files", &locks_json);
    1108           4 :         if (result < 0) {
    1109           0 :                 goto failure;
    1110             :         }
    1111             : 
    1112           4 :         TALLOC_FREE(tmp_ctx);
    1113           4 :         return 0;
    1114           0 : failure:
    1115           0 :         json_free(&file_json);
    1116           0 :         json_free(&locks_json);
    1117           0 :         TALLOC_FREE(tmp_ctx);
    1118           0 :         return -1;
    1119             : }
    1120             : 
    1121           0 : static int add_lock_to_json(struct json_object *parent_json,
    1122             :                             struct server_id server_id,
    1123             :                             const char *type,
    1124             :                             enum brl_flavour flavour,
    1125             :                             intmax_t start,
    1126             :                             intmax_t size)
    1127             : {
    1128           0 :         struct json_object sub_json = {
    1129             :                 .valid = false,
    1130             :         };
    1131           0 :         struct json_object locks_json = {
    1132             :                 .valid = false,
    1133             :         };
    1134             :         const char *flavour_str;
    1135           0 :         int result = 0;
    1136             : 
    1137           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1138           0 :         if (tmp_ctx == NULL) {
    1139           0 :                 return -1;
    1140             :         }
    1141             : 
    1142           0 :         locks_json = json_get_array(parent_json, "locks");
    1143           0 :         if (json_is_invalid(&locks_json)) {
    1144           0 :                 goto failure;
    1145             :         }
    1146           0 :         sub_json = json_new_object();
    1147           0 :         if (json_is_invalid(&sub_json)) {
    1148           0 :                 goto failure;
    1149             :         }
    1150             : 
    1151           0 :         result = add_server_id_to_json(&sub_json, server_id);
    1152           0 :         if (result < 0) {
    1153           0 :                 goto failure;
    1154             :         }
    1155           0 :         result = json_add_string(&sub_json, "type", type);
    1156           0 :         if (result < 0) {
    1157           0 :                 goto failure;
    1158             :         }
    1159           0 :         flavour_str = talloc_asprintf(tmp_ctx, "%s%s",
    1160             :                                       (flavour == WINDOWS_LOCK)?"Windows":"",
    1161             :                                       (flavour == POSIX_LOCK)?"Posix":"");
    1162           0 :         result = json_add_string(&sub_json, "flavour", flavour_str);
    1163           0 :         if (result < 0) {
    1164           0 :                 goto failure;
    1165             :         }
    1166           0 :         result = json_add_int(&sub_json, "start", start);
    1167           0 :         if (result < 0) {
    1168           0 :                 goto failure;
    1169             :         }
    1170           0 :         result = json_add_int(&sub_json, "size", size);
    1171           0 :         if (result < 0) {
    1172           0 :                 goto failure;
    1173             :         }
    1174             : 
    1175           0 :         result = json_add_object(&locks_json, NULL, &sub_json);
    1176           0 :         if (result < 0) {
    1177           0 :                 goto failure;
    1178             :         }
    1179           0 :         result = json_update_object(parent_json, "locks", &locks_json);
    1180           0 :         if (result < 0) {
    1181           0 :                 goto failure;
    1182             :         }
    1183             : 
    1184           0 :         TALLOC_FREE(tmp_ctx);
    1185           0 :         return 0;
    1186           0 : failure:
    1187           0 :         json_free(&locks_json);
    1188           0 :         json_free(&sub_json);
    1189           0 :         TALLOC_FREE(tmp_ctx);
    1190           0 :         return -1;
    1191             : }
    1192             : 
    1193           0 : int print_brl_json(struct traverse_state *state,
    1194             :                    const struct server_id server_id,
    1195             :                    struct file_id fid,
    1196             :                    const char *type,
    1197             :                    enum brl_flavour flavour,
    1198             :                    intmax_t start,
    1199             :                    intmax_t size,
    1200             :                    const char *sharepath,
    1201             :                    const char *filename)
    1202             : {
    1203           0 :         struct json_object file_json = {
    1204             :                 .valid = false,
    1205             :         };
    1206           0 :         struct json_object brl_json = {
    1207             :                 .valid = false,
    1208             :         };
    1209           0 :         int result = 0;
    1210             :         char *key;
    1211             : 
    1212           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1213           0 :         if (tmp_ctx == NULL) {
    1214           0 :                 return -1;
    1215             :         }
    1216             : 
    1217           0 :         if (sharepath[strlen(sharepath)-1] == '/') {
    1218           0 :                 key = talloc_asprintf(tmp_ctx, "%s%s", sharepath, filename);
    1219             :         } else {
    1220           0 :                 key = talloc_asprintf(tmp_ctx, "%s/%s", sharepath, filename);
    1221             :         }
    1222           0 :         if (key == NULL) {
    1223           0 :                 goto failure;
    1224             :         }
    1225             : 
    1226           0 :         brl_json = json_get_object(&state->root_json, "byte_range_locks");
    1227           0 :         if (json_is_invalid(&brl_json)) {
    1228           0 :                 goto failure;
    1229             :         }
    1230           0 :         file_json = json_get_object(&brl_json, key);
    1231           0 :         if (json_is_invalid(&file_json)) {
    1232           0 :                 goto failure;
    1233             :         }
    1234             : 
    1235           0 :         result = add_fileid_to_json(&file_json, fid);
    1236           0 :         if (result < 0) {
    1237           0 :                 goto failure;
    1238             :         }
    1239           0 :         result = json_add_string(&file_json, "file_name", filename);
    1240           0 :         if (result < 0) {
    1241           0 :                 goto failure;
    1242             :         }
    1243           0 :         result = json_add_string(&file_json, "share_path", sharepath);
    1244           0 :         if (result < 0) {
    1245           0 :                 goto failure;
    1246             :         }
    1247           0 :         result = add_server_id_to_json(&file_json, server_id);
    1248           0 :         if (result < 0) {
    1249           0 :                 goto failure;
    1250             :         }
    1251           0 :         result = add_lock_to_json(&file_json, server_id, type, flavour, start, size);
    1252           0 :         if (result < 0) {
    1253           0 :                 goto failure;
    1254             :         }
    1255             : 
    1256           0 :         result = json_add_object(&brl_json, key, &file_json);
    1257           0 :         if (result < 0) {
    1258           0 :                 goto failure;
    1259             :         }
    1260           0 :         result = json_update_object(&state->root_json, "byte_range_locks", &brl_json);
    1261           0 :         if (result < 0) {
    1262           0 :                 goto failure;
    1263             :          }
    1264             : 
    1265           0 :         TALLOC_FREE(tmp_ctx);
    1266           0 :         return 0;
    1267           0 : failure:
    1268           0 :         json_free(&file_json);
    1269           0 :         json_free(&brl_json);
    1270           0 :         TALLOC_FREE(tmp_ctx);
    1271           0 :         return -1;
    1272             : }
    1273             : 
    1274           0 : bool print_notify_rec_json(struct traverse_state *state,
    1275             :                            const struct notify_instance *instance,
    1276             :                            const struct server_id server_id,
    1277             :                            const char *path)
    1278             : {
    1279             :         struct json_object sub_json;
    1280             :         struct json_object notify_json;
    1281           0 :         char *filter = NULL;
    1282           0 :         char *subdir_filter = NULL;
    1283             :         struct timeval_buf tv_buf;
    1284             :         struct timeval val;
    1285           0 :         char *time = NULL;
    1286           0 :         char *pid = NULL;
    1287             :         struct server_id_buf tmp;
    1288           0 :         int result = 0;
    1289             : 
    1290           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1291           0 :         if (tmp_ctx == NULL) {
    1292           0 :                 return -1;
    1293             :         }
    1294             : 
    1295           0 :         sub_json = json_new_object();
    1296           0 :         if (json_is_invalid(&sub_json)) {
    1297           0 :                 return false;
    1298             :         }
    1299           0 :         notify_json = json_get_object(&state->root_json, "notifies");
    1300           0 :         if (json_is_invalid(&notify_json)) {
    1301           0 :                 goto failure;
    1302             :         }
    1303             : 
    1304           0 :         result = add_server_id_to_json(&sub_json, server_id);
    1305           0 :         if (result < 0) {
    1306           0 :                 goto failure;
    1307             :         }
    1308           0 :         result = json_add_string(&sub_json, "path", path);
    1309           0 :         if (result < 0) {
    1310           0 :                 goto failure;
    1311             :         }
    1312           0 :         filter = talloc_asprintf(tmp_ctx, "%u", instance->filter);
    1313           0 :         if (filter == NULL) {
    1314           0 :                 goto failure;
    1315             :         }
    1316           0 :         result = json_add_string(&sub_json, "filter", filter);
    1317           0 :         if (result < 0) {
    1318           0 :                 goto failure;
    1319             :         }
    1320           0 :         subdir_filter = talloc_asprintf(tmp_ctx, "%u", instance->subdir_filter);
    1321           0 :         if (subdir_filter == NULL) {
    1322           0 :                 goto failure;
    1323             :         }
    1324           0 :         result = json_add_string(&sub_json, "subdir_filter", subdir_filter);
    1325           0 :         if (result < 0) {
    1326           0 :                 goto failure;
    1327             :         }
    1328           0 :         val = convert_timespec_to_timeval(instance->creation_time);
    1329           0 :         time = timeval_str_buf(&val, true, true, &tv_buf);
    1330           0 :         result = json_add_string(&sub_json, "creation_time", time);
    1331           0 :         if (result < 0) {
    1332           0 :                 goto failure;
    1333             :         }
    1334             : 
    1335           0 :         pid = server_id_str_buf(server_id, &tmp);
    1336           0 :         result = json_add_object(&notify_json, pid, &sub_json);
    1337           0 :         if (result < 0) {
    1338           0 :                 goto failure;
    1339             :         }
    1340             : 
    1341           0 :         result = json_update_object(&state->root_json, "notifies", &notify_json);
    1342           0 :         if (result < 0) {
    1343           0 :                 goto failure;
    1344             :         }
    1345             : 
    1346           0 :         TALLOC_FREE(tmp_ctx);
    1347           0 :         return true;
    1348           0 : failure:
    1349           0 :         json_free(&sub_json);
    1350           0 :         TALLOC_FREE(tmp_ctx);
    1351           0 :         return false;
    1352             : }

Generated by: LCOV version 1.14