smbstatus: add machine readable time to connections
[Samba.git] / source3 / utils / status_json.c
blob3f76cea3c7f006faf8ec388d939a3ac66499b51e
1 /*
2 * Samba Unix/Linux SMB client library
3 * Json output
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/>.
20 #include "includes.h"
21 #include "smbprofile.h"
22 #include "lib/util/time_basic.h"
23 #include "conn_tdb.h"
24 #include "status_json.h"
25 #include "../libcli/security/security.h"
26 #include "status.h"
27 #include "lib/util/server_id.h"
29 #include <jansson.h>
30 #include "audit_logging.h" /* various JSON helpers */
31 #include "auth/common_auth.h"
33 int add_general_information_to_json(struct traverse_state *state)
35 int result;
37 result = json_add_timestamp(&state->root_json);
38 if (result < 0) {
39 return -1;
42 result = json_add_string(&state->root_json, "version", samba_version_string());
43 if (result < 0) {
44 return -1;
47 result = json_add_string(&state->root_json, "smb_conf", get_dyn_CONFIGFILE());
48 if (result < 0) {
49 return -1;
52 return 0;
55 static int add_server_id_to_json(struct json_object *parent_json,
56 const struct server_id server_id)
58 struct json_object sub_json;
59 char *pid_str = NULL;
60 char *task_id_str = NULL;
61 char *vnn_str = NULL;
62 char *unique_id_str = NULL;
63 int result;
65 TALLOC_CTX *tmp_ctx = talloc_stackframe();
66 if (tmp_ctx == NULL) {
67 return -1;
70 sub_json = json_new_object();
71 if (json_is_invalid(&sub_json)) {
72 goto failure;
75 pid_str = talloc_asprintf(tmp_ctx, "%lu", server_id.pid);
76 result = json_add_string(&sub_json, "pid", pid_str);
77 if (result < 0) {
78 goto failure;
80 task_id_str = talloc_asprintf(tmp_ctx, "%u", server_id.task_id);
81 result = json_add_string(&sub_json, "task_id", task_id_str);
82 if (result < 0) {
83 goto failure;
85 vnn_str = talloc_asprintf(tmp_ctx, "%u", server_id.vnn);
86 result = json_add_string(&sub_json, "vnn", vnn_str);
87 if (result < 0) {
88 goto failure;
90 unique_id_str = talloc_asprintf(tmp_ctx, "%lu", server_id.unique_id);
91 result = json_add_string(&sub_json, "unique_id", unique_id_str);
92 if (result < 0) {
93 goto failure;
96 result = json_add_object(parent_json, "server_id", &sub_json);
97 if (result < 0) {
98 goto failure;
101 json_free(&sub_json);
102 TALLOC_FREE(tmp_ctx);
103 return 0;
104 failure:
105 json_free(&sub_json);
106 TALLOC_FREE(tmp_ctx);
107 return -1;
110 int add_section_to_json(struct traverse_state *state,
111 const char *key)
113 struct json_object empty_json;
114 int result;
116 empty_json = json_new_object();
117 if (json_is_invalid(&empty_json)) {
118 return -1;
121 result = json_add_object(&state->root_json, key, &empty_json);
122 if (result < 0) {
123 return -1;
126 return result;
129 int traverse_connections_json(struct traverse_state *state,
130 const struct connections_data *crec)
132 struct json_object sub_json;
133 struct json_object connections_json;
134 struct timeval tv;
135 struct timeval_buf tv_buf;
136 char *time = NULL;
137 int result = 0;
138 char *sess_id_str = NULL;
139 char *tcon_id_str = NULL;
141 TALLOC_CTX *tmp_ctx = talloc_stackframe();
142 if (tmp_ctx == NULL) {
143 return -1;
146 sub_json = json_new_object();
147 if (json_is_invalid(&sub_json)) {
148 goto failure;
150 connections_json = json_get_object(&state->root_json, "tcons");
151 if (json_is_invalid(&connections_json)) {
152 goto failure;
155 result = json_add_string(&sub_json, "service", crec->servicename);
156 if (result < 0) {
157 goto failure;
159 result = add_server_id_to_json(&sub_json, crec->pid);
160 if (result < 0) {
161 goto failure;
163 tcon_id_str = talloc_asprintf(tmp_ctx, "%u", crec->cnum);
164 if (tcon_id_str == NULL) {
165 goto failure;
167 result = json_add_string(&sub_json, "tcon_id", tcon_id_str);
168 if (result < 0) {
169 goto failure;
171 sess_id_str = talloc_asprintf(tmp_ctx, "%u", crec->sess_id);
172 if (sess_id_str == NULL) {
173 goto failure;
175 result = json_add_string(&sub_json, "session_id", sess_id_str);
176 if (result < 0) {
177 goto failure;
179 result = json_add_string(&sub_json, "machine", crec->machine);
180 if (result < 0) {
181 goto failure;
183 nttime_to_timeval(&tv, crec->start);
184 time = timeval_str_buf(&tv, true, true, &tv_buf);
185 if (time == NULL) {
186 goto failure;
188 result = json_add_string(&sub_json, "connected_at", time);
189 if (result < 0) {
190 goto failure;
193 result = json_add_object(&connections_json, tcon_id_str, &sub_json);
194 if (result < 0) {
195 goto failure;
198 result = json_update_object(&state->root_json, "tcons", &connections_json);
199 if (result < 0) {
200 goto failure;
203 TALLOC_FREE(tmp_ctx);
204 return 0;
205 failure:
206 json_free(&sub_json);
207 TALLOC_FREE(tmp_ctx);
208 return -1;