smbstatus: add encryption and signing to connections
[Samba.git] / source3 / utils / status_json.c
blob0eadd1a1867a929251d2722b4f24ecf791989c60
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 static int add_crypto_to_json(struct json_object *parent_json,
130 const char *key,
131 const char *cipher,
132 enum crypto_degree degree)
134 struct json_object sub_json;
135 const char *degree_str;
136 int result;
138 if (degree == CRYPTO_DEGREE_NONE) {
139 degree_str = "none";
140 } else if (degree == CRYPTO_DEGREE_PARTIAL) {
141 degree_str = "partial";
142 } else {
143 degree_str = "full";
146 sub_json = json_new_object();
147 if (json_is_invalid(&sub_json)) {
148 goto failure;
151 result = json_add_string(&sub_json, "cipher", cipher);
152 if (result < 0) {
153 goto failure;
155 result = json_add_string(&sub_json, "degree", degree_str);
156 if (result < 0) {
157 goto failure;
159 result = json_add_object(parent_json, key, &sub_json);
160 if (result < 0) {
161 goto failure;
164 return 0;
165 failure:
166 json_free(&sub_json);
167 return -1;
170 int traverse_connections_json(struct traverse_state *state,
171 const struct connections_data *crec,
172 const char *encryption_cipher,
173 enum crypto_degree encryption_degree,
174 const char *signing_cipher,
175 enum crypto_degree signing_degree)
177 struct json_object sub_json;
178 struct json_object connections_json;
179 struct timeval tv;
180 struct timeval_buf tv_buf;
181 char *time = NULL;
182 int result = 0;
183 char *sess_id_str = NULL;
184 char *tcon_id_str = NULL;
186 TALLOC_CTX *tmp_ctx = talloc_stackframe();
187 if (tmp_ctx == NULL) {
188 return -1;
191 sub_json = json_new_object();
192 if (json_is_invalid(&sub_json)) {
193 goto failure;
195 connections_json = json_get_object(&state->root_json, "tcons");
196 if (json_is_invalid(&connections_json)) {
197 goto failure;
200 result = json_add_string(&sub_json, "service", crec->servicename);
201 if (result < 0) {
202 goto failure;
204 result = add_server_id_to_json(&sub_json, crec->pid);
205 if (result < 0) {
206 goto failure;
208 tcon_id_str = talloc_asprintf(tmp_ctx, "%u", crec->cnum);
209 if (tcon_id_str == NULL) {
210 goto failure;
212 result = json_add_string(&sub_json, "tcon_id", tcon_id_str);
213 if (result < 0) {
214 goto failure;
216 sess_id_str = talloc_asprintf(tmp_ctx, "%u", crec->sess_id);
217 if (sess_id_str == NULL) {
218 goto failure;
220 result = json_add_string(&sub_json, "session_id", sess_id_str);
221 if (result < 0) {
222 goto failure;
224 result = json_add_string(&sub_json, "machine", crec->machine);
225 if (result < 0) {
226 goto failure;
228 nttime_to_timeval(&tv, crec->start);
229 time = timeval_str_buf(&tv, true, true, &tv_buf);
230 if (time == NULL) {
231 goto failure;
233 result = json_add_string(&sub_json, "connected_at", time);
234 if (result < 0) {
235 goto failure;
237 result = add_crypto_to_json(&sub_json, "encryption",
238 encryption_cipher, encryption_degree);
239 if (result < 0) {
240 goto failure;
242 result = add_crypto_to_json(&sub_json, "signing",
243 signing_cipher, signing_degree);
244 if (result < 0) {
245 goto failure;
248 result = json_add_object(&connections_json, tcon_id_str, &sub_json);
249 if (result < 0) {
250 goto failure;
253 result = json_update_object(&state->root_json, "tcons", &connections_json);
254 if (result < 0) {
255 goto failure;
258 TALLOC_FREE(tmp_ctx);
259 return 0;
260 failure:
261 json_free(&sub_json);
262 TALLOC_FREE(tmp_ctx);
263 return -1;