2 * Samba Unix/Linux SMB client library
4 * Copyright (C) Jule Anger 2022
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.
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.
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/>.
21 #include "smbprofile.h"
22 #include "lib/util/time_basic.h"
25 #include "librpc/gen_ndr/open_files.h"
26 #include "status_json.h"
27 #include "../libcli/security/security.h"
29 #include "lib/util/server_id.h"
30 #include "lib/util/string_wrappers.h"
33 #include "audit_logging.h" /* various JSON helpers */
34 #include "auth/common_auth.h"
36 int add_general_information_to_json(struct traverse_state
*state
)
40 result
= json_add_timestamp(&state
->root_json
);
45 result
= json_add_string(&state
->root_json
, "version", samba_version_string());
50 result
= json_add_string(&state
->root_json
, "smb_conf", get_dyn_CONFIGFILE());
58 static int add_server_id_to_json(struct json_object
*parent_json
,
59 const struct server_id server_id
)
61 struct json_object sub_json
;
63 char *task_id_str
= NULL
;
65 char *unique_id_str
= NULL
;
68 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
69 if (tmp_ctx
== NULL
) {
73 sub_json
= json_new_object();
74 if (json_is_invalid(&sub_json
)) {
78 pid_str
= talloc_asprintf(
79 tmp_ctx
, "%lu", (unsigned long)server_id
.pid
);
80 result
= json_add_string(&sub_json
, "pid", pid_str
);
84 task_id_str
= talloc_asprintf(tmp_ctx
, "%u", server_id
.task_id
);
85 result
= json_add_string(&sub_json
, "task_id", task_id_str
);
89 vnn_str
= talloc_asprintf(tmp_ctx
, "%u", server_id
.vnn
);
90 result
= json_add_string(&sub_json
, "vnn", vnn_str
);
94 unique_id_str
= talloc_asprintf(
95 tmp_ctx
, "%"PRIu64
, server_id
.unique_id
);
96 result
= json_add_string(&sub_json
, "unique_id", unique_id_str
);
101 result
= json_add_object(parent_json
, "server_id", &sub_json
);
106 TALLOC_FREE(tmp_ctx
);
109 json_free(&sub_json
);
110 TALLOC_FREE(tmp_ctx
);
116 const char *string_desc
;
120 * Convert a mask of some sort (access, oplock, leases),
121 * to key/value pairs in a JSON object.
123 static int map_mask_to_json(struct json_object
*root_json
,
125 const struct mask2txt
*table
)
127 const struct mask2txt
*a
= NULL
;
130 for (a
= table
; a
->string_desc
!= 0; a
++) {
131 result
= json_add_bool(root_json
, a
->string_desc
,
132 (tomap
& a
->mask
) ? true : false);
140 /* Assert we know about all requested "tomap" values */
141 SMB_ASSERT(tomap
== 0);
146 static const struct mask2txt access_mask
[] = {
147 {FILE_READ_DATA
, "READ_DATA"},
148 {FILE_WRITE_DATA
, "WRITE_DATA"},
149 {FILE_APPEND_DATA
, "APPEND_DATA"},
150 {FILE_READ_EA
, "READ_EA"},
151 {FILE_WRITE_EA
, "WRITE_EA"},
152 {FILE_EXECUTE
, "EXECUTE"},
153 {FILE_READ_ATTRIBUTES
, "READ_ATTRIBUTES"},
154 {FILE_WRITE_ATTRIBUTES
, "WRITE_ATTRIBUTES"},
155 {FILE_DELETE_CHILD
, "DELETE_CHILD"},
156 {SEC_STD_DELETE
, "DELETE"},
157 {SEC_STD_READ_CONTROL
, "READ_CONTROL"},
158 {SEC_STD_WRITE_DAC
, "WRITE_DAC"},
159 {SEC_STD_SYNCHRONIZE
, "SYNCHRONIZE"},
160 {SEC_FLAG_SYSTEM_SECURITY
, "ACCESS_SYSTEM_SECURITY"},
164 static const struct mask2txt oplock_mask
[] = {
165 {EXCLUSIVE_OPLOCK
, "EXCLUSIVE"},
166 {BATCH_OPLOCK
, "BATCH"},
167 {LEVEL_II_OPLOCK
, "LEVEL_II"},
168 {LEASE_OPLOCK
, "LEASE"},
172 static const struct mask2txt sharemode_mask
[] = {
173 {FILE_SHARE_READ
, "READ"},
174 {FILE_SHARE_WRITE
, "WRITE"},
175 {FILE_SHARE_DELETE
, "DELETE"},
179 static const struct mask2txt lease_mask
[] = {
180 {SMB2_LEASE_READ
, "READ"},
181 {SMB2_LEASE_WRITE
, "WRITE"},
182 {SMB2_LEASE_HANDLE
, "HANDLE"},
186 int add_profile_item_to_json(struct traverse_state
*state
,
188 const char *subsection
,
192 struct json_object section_json
= {
195 struct json_object subsection_json
= {
200 section_json
= json_get_object(&state
->root_json
, section
);
201 if (json_is_invalid(§ion_json
)) {
204 subsection_json
= json_get_object(§ion_json
, subsection
);
205 if (json_is_invalid(&subsection_json
)) {
209 result
= json_add_int(&subsection_json
, key
, value
);
214 result
= json_update_object(§ion_json
, subsection
, &subsection_json
);
218 result
= json_update_object(&state
->root_json
, section
, §ion_json
);
225 json_free(§ion_json
);
226 json_free(&subsection_json
);
230 int add_section_to_json(struct traverse_state
*state
,
233 struct json_object empty_json
;
236 empty_json
= json_new_object();
237 if (json_is_invalid(&empty_json
)) {
241 result
= json_add_object(&state
->root_json
, key
, &empty_json
);
249 static int add_crypto_to_json(struct json_object
*parent_json
,
252 enum crypto_degree degree
)
254 struct json_object sub_json
;
255 const char *degree_str
;
258 if (degree
== CRYPTO_DEGREE_NONE
) {
260 } else if (degree
== CRYPTO_DEGREE_PARTIAL
) {
261 degree_str
= "partial";
266 sub_json
= json_new_object();
267 if (json_is_invalid(&sub_json
)) {
271 result
= json_add_string(&sub_json
, "cipher", cipher
);
275 result
= json_add_string(&sub_json
, "degree", degree_str
);
279 result
= json_add_object(parent_json
, key
, &sub_json
);
286 json_free(&sub_json
);
290 int traverse_connections_json(struct traverse_state
*state
,
291 const struct connections_data
*crec
,
292 const char *encryption_cipher
,
293 enum crypto_degree encryption_degree
,
294 const char *signing_cipher
,
295 enum crypto_degree signing_degree
)
297 struct json_object sub_json
;
298 struct json_object connections_json
;
300 struct timeval_buf tv_buf
;
303 char *sess_id_str
= NULL
;
304 char *tcon_id_str
= NULL
;
306 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
307 if (tmp_ctx
== NULL
) {
311 sub_json
= json_new_object();
312 if (json_is_invalid(&sub_json
)) {
315 connections_json
= json_get_object(&state
->root_json
, "tcons");
316 if (json_is_invalid(&connections_json
)) {
320 result
= json_add_string(&sub_json
, "service", crec
->servicename
);
324 result
= add_server_id_to_json(&sub_json
, crec
->pid
);
328 tcon_id_str
= talloc_asprintf(tmp_ctx
, "%u", crec
->cnum
);
329 if (tcon_id_str
== NULL
) {
332 result
= json_add_string(&sub_json
, "tcon_id", tcon_id_str
);
336 sess_id_str
= talloc_asprintf(tmp_ctx
, "%u", crec
->sess_id
);
337 if (sess_id_str
== NULL
) {
340 result
= json_add_string(&sub_json
, "session_id", sess_id_str
);
344 result
= json_add_string(&sub_json
, "machine", crec
->machine
);
348 nttime_to_timeval(&tv
, crec
->start
);
349 time
= timeval_str_buf(&tv
, true, true, &tv_buf
);
353 result
= json_add_string(&sub_json
, "connected_at", time
);
357 result
= add_crypto_to_json(&sub_json
, "encryption",
358 encryption_cipher
, encryption_degree
);
362 result
= add_crypto_to_json(&sub_json
, "signing",
363 signing_cipher
, signing_degree
);
368 result
= json_add_object(&connections_json
, tcon_id_str
, &sub_json
);
373 result
= json_update_object(&state
->root_json
, "tcons", &connections_json
);
378 TALLOC_FREE(tmp_ctx
);
381 json_free(&sub_json
);
382 TALLOC_FREE(tmp_ctx
);
386 int traverse_sessionid_json(struct traverse_state
*state
,
387 struct sessionid
*session
,
390 const char *encryption_cipher
,
391 enum crypto_degree encryption_degree
,
392 const char *signing_cipher
,
393 enum crypto_degree signing_degree
,
394 const char *connection_dialect
)
396 struct json_object sub_json
;
397 struct json_object session_json
;
401 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
402 if (tmp_ctx
== NULL
) {
406 sub_json
= json_new_object();
407 if (json_is_invalid(&sub_json
)) {
411 session_json
= json_get_object(&state
->root_json
, "sessions");
412 if (json_is_invalid(&session_json
)) {
416 id_str
= talloc_asprintf(tmp_ctx
, "%u", session
->id_num
);
417 result
= json_add_string(&sub_json
, "session_id", id_str
);
421 result
= add_server_id_to_json(&sub_json
, session
->pid
);
425 result
= json_add_int(&sub_json
, "uid", session
->uid
);
429 result
= json_add_int(&sub_json
, "gid", session
->gid
);
433 result
= json_add_string(&sub_json
, "username", uid_str
);
437 result
= json_add_string(&sub_json
, "groupname", gid_str
);
441 result
= json_add_string(&sub_json
, "remote_machine", session
->remote_machine
);
445 result
= json_add_string(&sub_json
, "hostname", session
->hostname
);
449 result
= json_add_string(&sub_json
, "session_dialect", connection_dialect
);
453 result
= add_crypto_to_json(&sub_json
, "encryption",
454 encryption_cipher
, encryption_degree
);
458 result
= add_crypto_to_json(&sub_json
, "signing",
459 signing_cipher
, signing_degree
);
464 result
= json_add_object(&session_json
, id_str
, &sub_json
);
469 result
= json_update_object(&state
->root_json
, "sessions", &session_json
);
474 TALLOC_FREE(tmp_ctx
);
477 json_free(&sub_json
);
478 TALLOC_FREE(tmp_ctx
);
482 static int add_access_mode_to_json(struct json_object
*parent_json
,
485 struct json_object access_json
;
486 char *access_hex
= NULL
;
487 const char *access_str
= NULL
;
490 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
491 if (tmp_ctx
== NULL
) {
495 access_json
= json_new_object();
496 if (json_is_invalid(&access_json
)) {
500 access_hex
= talloc_asprintf(tmp_ctx
, "0x%08x", access_int
);
501 result
= json_add_string(&access_json
, "hex", access_hex
);
505 result
= map_mask_to_json(&access_json
, access_int
, access_mask
);
510 access_str
= talloc_asprintf(tmp_ctx
, "%s%s",
511 (access_int
& FILE_READ_DATA
)?"R":"",
512 (access_int
& (FILE_WRITE_DATA
|FILE_APPEND_DATA
))?"W":"");
513 result
= json_add_string(&access_json
, "text", access_str
);
518 result
= json_add_object(parent_json
, "access_mask", &access_json
);
523 TALLOC_FREE(tmp_ctx
);
526 json_free(&access_json
);
527 TALLOC_FREE(tmp_ctx
);
531 static int add_caching_to_json(struct json_object
*parent_json
,
535 struct json_object caching_json
;
537 char *caching_text
= NULL
;
538 int caching_type
= 0;
541 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
542 if (tmp_ctx
== NULL
) {
546 caching_json
= json_new_object();
547 if (json_is_invalid(&caching_json
)) {
551 if (op_type
& LEASE_OPLOCK
) {
552 caching_type
= lease_type
;
554 if (op_type
& LEVEL_II_OPLOCK
) {
555 caching_type
= SMB2_LEASE_READ
;
556 } else if (op_type
& EXCLUSIVE_OPLOCK
) {
557 caching_type
= SMB2_LEASE_READ
+ SMB2_LEASE_WRITE
;
558 } else if (op_type
& BATCH_OPLOCK
) {
559 caching_type
= SMB2_LEASE_READ
+ SMB2_LEASE_WRITE
+ SMB2_LEASE_HANDLE
;
562 result
= map_mask_to_json(&caching_json
, caching_type
, lease_mask
);
567 hex
= talloc_asprintf(tmp_ctx
, "0x%08x", caching_type
);
571 result
= json_add_string(&caching_json
, "hex", hex
);
576 caching_text
= talloc_asprintf(tmp_ctx
, "%s%s%s",
577 (caching_type
& SMB2_LEASE_READ
)?"R":"",
578 (caching_type
& SMB2_LEASE_WRITE
)?"W":"",
579 (caching_type
& SMB2_LEASE_HANDLE
)?"H":"");
580 if (caching_text
== NULL
) {
584 result
= json_add_string(&caching_json
, "text", caching_text
);
589 result
= json_add_object(parent_json
, "caching", &caching_json
);
594 TALLOC_FREE(tmp_ctx
);
597 json_free(&caching_json
);
598 TALLOC_FREE(tmp_ctx
);
602 static int add_oplock_to_json(struct json_object
*parent_json
,
606 struct json_object oplock_json
;
609 oplock_json
= json_new_object();
610 if (json_is_invalid(&oplock_json
)) {
615 result
= map_mask_to_json(&oplock_json
, op_type
, oplock_mask
);
619 result
= json_add_string(&oplock_json
, "text", op_str
);
625 result
= json_add_object(parent_json
, "oplock", &oplock_json
);
632 json_free(&oplock_json
);
636 static int lease_key_to_str(struct smb2_lease_key lease_key
,
639 uint8_t _buf
[16] = {0};
640 DATA_BLOB blob
= data_blob_const(_buf
, sizeof(_buf
));
645 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
646 if (tmp_ctx
== NULL
) {
650 PUSH_LE_U64(_buf
, 0, lease_key
.data
[0]);
651 PUSH_LE_U64(_buf
, 8, lease_key
.data
[1]);
653 status
= GUID_from_ndr_blob(&blob
, &guid
);
654 if (!NT_STATUS_IS_OK(status
)) {
657 tmp
= GUID_string(tmp_ctx
, &guid
);
661 fstrcpy(lease_str
, tmp
);
663 TALLOC_FREE(tmp_ctx
);
666 TALLOC_FREE(tmp_ctx
);
670 static int add_lease_to_json(struct json_object
*parent_json
,
672 struct smb2_lease_key lease_key
,
675 struct json_object lease_json
;
676 char *lease_hex
= NULL
;
677 char *lease_text
= NULL
;
678 fstring lease_key_str
;
681 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
682 if (tmp_ctx
== NULL
) {
686 lease_json
= json_new_object();
687 if (json_is_invalid(&lease_json
)) {
693 result
= lease_key_to_str(lease_key
, lease_key_str
);
697 result
= json_add_string(&lease_json
, "lease_key", lease_key_str
);
701 lease_hex
= talloc_asprintf(tmp_ctx
, "0x%08x", lease_type
);
702 result
= json_add_string(&lease_json
, "hex", lease_hex
);
706 if (lease_type
> (SMB2_LEASE_WRITE
+ SMB2_LEASE_HANDLE
+ SMB2_LEASE_READ
)) {
707 result
= json_add_bool(&lease_json
, "UNKNOWN", true);
712 result
= map_mask_to_json(&lease_json
, lease_type
, lease_mask
);
717 lease_text
= talloc_asprintf(tmp_ctx
, "%s%s%s",
718 (lease_type
& SMB2_LEASE_READ
)?"R":"",
719 (lease_type
& SMB2_LEASE_WRITE
)?"W":"",
720 (lease_type
& SMB2_LEASE_HANDLE
)?"H":"");
722 result
= json_add_string(&lease_json
, "text", lease_text
);
728 result
= json_add_object(parent_json
, "lease", &lease_json
);
733 TALLOC_FREE(tmp_ctx
);
736 json_free(&lease_json
);
737 TALLOC_FREE(tmp_ctx
);
741 static int add_sharemode_to_json(struct json_object
*parent_json
,
744 struct json_object sharemode_json
;
749 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
750 if (tmp_ctx
== NULL
) {
754 sharemode_json
= json_new_object();
755 if (json_is_invalid(&sharemode_json
)) {
759 hex
= talloc_asprintf(tmp_ctx
, "0x%08x", sharemode
);
763 result
= json_add_string(&sharemode_json
, "hex", hex
);
767 result
= map_mask_to_json(&sharemode_json
, sharemode
, sharemode_mask
);
772 text
= talloc_asprintf(tmp_ctx
, "%s%s%s",
773 (sharemode
& FILE_SHARE_READ
)?"R":"",
774 (sharemode
& FILE_SHARE_WRITE
)?"W":"",
775 (sharemode
& FILE_SHARE_DELETE
)?"D":"");
779 result
= json_add_string(&sharemode_json
, "text", text
);
784 result
= json_add_object(parent_json
, "sharemode", &sharemode_json
);
789 TALLOC_FREE(tmp_ctx
);
792 json_free(&sharemode_json
);
793 TALLOC_FREE(tmp_ctx
);
797 static int add_open_to_json(struct json_object
*parent_json
,
798 const struct share_mode_entry
*e
,
804 struct json_object sub_json
= {
807 struct json_object opens_json
= {
810 struct timeval_buf tv_buf
;
813 bool add_lease
= false;
815 char *share_file_id
= NULL
;
817 struct server_id_buf tmp
;
819 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
820 if (tmp_ctx
== NULL
) {
824 opens_json
= json_get_object(parent_json
, "opens");
825 if (json_is_invalid(&opens_json
)) {
828 sub_json
= json_new_object();
829 if (json_is_invalid(&sub_json
)) {
834 result
= add_server_id_to_json(&sub_json
, e
->pid
);
839 result
= json_add_string(&sub_json
, "username", uid_str
);
844 result
= json_add_int(&sub_json
, "uid", e
->uid
);
848 share_file_id
= talloc_asprintf(tmp_ctx
, "%"PRIu64
, e
->share_file_id
);
849 result
= json_add_string(&sub_json
, "share_file_id", share_file_id
);
853 result
= add_sharemode_to_json(&sub_json
, e
->share_access
);
857 result
= add_access_mode_to_json(&sub_json
, e
->access_mask
);
861 result
= add_caching_to_json(&sub_json
, e
->op_type
, lease_type
);
865 result
= add_oplock_to_json(&sub_json
, e
->op_type
, op_str
);
869 add_lease
= e
->op_type
& LEASE_OPLOCK
;
870 result
= add_lease_to_json(&sub_json
, lease_type
, e
->lease_key
, add_lease
);
875 timestr
= timeval_str_buf(&e
->time
, true, true, &tv_buf
);
876 if (timestr
== NULL
) {
879 result
= json_add_string(&sub_json
, "opened_at", timestr
);
884 pid
= server_id_str_buf(e
->pid
, &tmp
);
885 key
= talloc_asprintf(tmp_ctx
, "%s/%"PRIu64
, pid
, e
->share_file_id
);
886 result
= json_add_object(&opens_json
, key
, &sub_json
);
890 result
= json_update_object(parent_json
, "opens", &opens_json
);
895 TALLOC_FREE(tmp_ctx
);
898 json_free(&opens_json
);
899 json_free(&sub_json
);
900 TALLOC_FREE(tmp_ctx
);
904 static int add_fileid_to_json(struct json_object
*parent_json
,
907 struct json_object fid_json
;
910 fid_json
= json_new_object();
911 if (json_is_invalid(&fid_json
)) {
915 result
= json_add_int(&fid_json
, "devid", fid
.devid
);
919 result
= json_add_int(&fid_json
, "inode", fid
.inode
);
923 result
= json_add_int(&fid_json
, "extid", fid
.extid
);
928 result
= json_add_object(parent_json
, "fileid", &fid_json
);
935 json_free(&fid_json
);
939 int print_share_mode_json(struct traverse_state
*state
,
940 const struct share_mode_data
*d
,
941 const struct share_mode_entry
*e
,
946 const char *filename
)
948 struct json_object locks_json
= {
951 struct json_object file_json
= {
957 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
958 if (tmp_ctx
== NULL
) {
962 if (d
->servicepath
[strlen(d
->servicepath
)-1] == '/') {
963 key
= talloc_asprintf(tmp_ctx
, "%s%s", d
->servicepath
, filename
);
965 key
= talloc_asprintf(tmp_ctx
, "%s/%s", d
->servicepath
, filename
);
968 locks_json
= json_get_object(&state
->root_json
, "open_files");
969 if (json_is_invalid(&locks_json
)) {
972 file_json
= json_get_object(&locks_json
, key
);
973 if (json_is_invalid(&file_json
)) {
977 result
= json_add_string(&file_json
, "service_path", d
->servicepath
);
981 result
= json_add_string(&file_json
, "filename", filename
);
985 result
= add_fileid_to_json(&file_json
, fid
);
989 result
= json_add_int(&file_json
, "num_pending_deletes", d
->num_delete_tokens
);
994 result
= add_open_to_json(&file_json
,
1004 result
= json_update_object(&locks_json
, key
, &file_json
);
1008 result
= json_update_object(&state
->root_json
, "open_files", &locks_json
);
1013 TALLOC_FREE(tmp_ctx
);
1016 json_free(&file_json
);
1017 json_free(&locks_json
);
1018 TALLOC_FREE(tmp_ctx
);
1022 static int add_lock_to_json(struct json_object
*parent_json
,
1023 struct server_id server_id
,
1025 enum brl_flavour flavour
,
1029 struct json_object sub_json
= {
1032 struct json_object locks_json
= {
1035 const char *flavour_str
;
1038 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1039 if (tmp_ctx
== NULL
) {
1043 locks_json
= json_get_array(parent_json
, "locks");
1044 if (json_is_invalid(&locks_json
)) {
1047 sub_json
= json_new_object();
1048 if (json_is_invalid(&sub_json
)) {
1052 result
= add_server_id_to_json(&sub_json
, server_id
);
1056 result
= json_add_string(&sub_json
, "type", type
);
1060 flavour_str
= talloc_asprintf(tmp_ctx
, "%s%s",
1061 (flavour
== WINDOWS_LOCK
)?"Windows":"",
1062 (flavour
== POSIX_LOCK
)?"Posix":"");
1063 result
= json_add_string(&sub_json
, "flavour", flavour_str
);
1067 result
= json_add_int(&sub_json
, "start", start
);
1071 result
= json_add_int(&sub_json
, "size", size
);
1076 result
= json_add_object(&locks_json
, NULL
, &sub_json
);
1080 result
= json_update_object(parent_json
, "locks", &locks_json
);
1085 TALLOC_FREE(tmp_ctx
);
1088 json_free(&locks_json
);
1089 json_free(&sub_json
);
1090 TALLOC_FREE(tmp_ctx
);
1094 int print_brl_json(struct traverse_state
*state
,
1095 const struct server_id server_id
,
1098 enum brl_flavour flavour
,
1101 const char *sharepath
,
1102 const char *filename
)
1104 struct json_object file_json
;
1105 struct json_object brl_json
;
1109 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1110 if (tmp_ctx
== NULL
) {
1114 if (sharepath
[strlen(sharepath
)-1] == '/') {
1115 key
= talloc_asprintf(tmp_ctx
, "%s%s", sharepath
, filename
);
1117 key
= talloc_asprintf(tmp_ctx
, "%s/%s", sharepath
, filename
);
1123 brl_json
= json_get_object(&state
->root_json
, "byte_range_locks");
1124 if (json_is_invalid(&brl_json
)) {
1127 file_json
= json_get_object(&brl_json
, key
);
1128 if (json_is_invalid(&file_json
)) {
1132 result
= add_fileid_to_json(&file_json
, fid
);
1136 result
= json_add_string(&file_json
, "file_name", filename
);
1140 result
= json_add_string(&file_json
, "share_path", sharepath
);
1144 result
= add_server_id_to_json(&file_json
, server_id
);
1148 result
= add_lock_to_json(&file_json
, server_id
, type
, flavour
, start
, size
);
1153 result
= json_add_object(&brl_json
, key
, &file_json
);
1157 result
= json_update_object(&state
->root_json
, "byte_range_locks", &brl_json
);
1162 TALLOC_FREE(tmp_ctx
);
1165 json_free(&file_json
);
1166 json_free(&brl_json
);
1167 TALLOC_FREE(tmp_ctx
);
1171 bool print_notify_rec_json(struct traverse_state
*state
,
1172 const struct notify_instance
*instance
,
1173 const struct server_id server_id
,
1176 struct json_object sub_json
;
1177 struct json_object notify_json
;
1178 char *filter
= NULL
;
1179 char *subdir_filter
= NULL
;
1180 struct timeval_buf tv_buf
;
1184 struct server_id_buf tmp
;
1187 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1188 if (tmp_ctx
== NULL
) {
1192 sub_json
= json_new_object();
1193 if (json_is_invalid(&sub_json
)) {
1196 notify_json
= json_get_object(&state
->root_json
, "notifies");
1197 if (json_is_invalid(¬ify_json
)) {
1201 result
= add_server_id_to_json(&sub_json
, server_id
);
1205 result
= json_add_string(&sub_json
, "path", path
);
1209 filter
= talloc_asprintf(tmp_ctx
, "%u", instance
->filter
);
1210 if (filter
== NULL
) {
1213 result
= json_add_string(&sub_json
, "filter", filter
);
1217 subdir_filter
= talloc_asprintf(tmp_ctx
, "%u", instance
->subdir_filter
);
1218 if (subdir_filter
== NULL
) {
1221 result
= json_add_string(&sub_json
, "subdir_filter", subdir_filter
);
1225 val
= convert_timespec_to_timeval(instance
->creation_time
);
1226 time
= timeval_str_buf(&val
, true, true, &tv_buf
);
1227 result
= json_add_string(&sub_json
, "creation_time", time
);
1232 pid
= server_id_str_buf(server_id
, &tmp
);
1233 result
= json_add_object(¬ify_json
, pid
, &sub_json
);
1238 result
= json_update_object(&state
->root_json
, "notifies", ¬ify_json
);
1243 TALLOC_FREE(tmp_ctx
);
1246 json_free(&sub_json
);
1247 TALLOC_FREE(tmp_ctx
);