-/*
+/*
Unix SMB/CIFS implementation.
status reporting
Copyright (C) Andrew Tridgell 1994-1998
#include "cmdline_contexts.h"
#include "locking/leases_db.h"
#include "lib/util/string_wrappers.h"
+#include "lib/param/param.h"
#ifdef HAVE_JANSSON
#include <jansson.h>
static unsigned int Ucrit_checkUid(uid_t uid)
{
- if ( !Ucrit_IsActive )
+ if ( !Ucrit_IsActive )
return 1;
- if ( uid == Ucrit_uid )
+ if ( uid == Ucrit_uid )
return 1;
return 0;
{
int i;
- if ( !Ucrit_IsActive )
+ if ( !Ucrit_IsActive )
return 1;
for (i=0;i<Ucrit_MaxPid;i++) {
static int prepare_share_mode(struct traverse_state *state)
{
- /* only print header line if there are open files */
- state->first = true;
-
+ if (!state->json_output) {
+ /* only print header line if there are open files */
+ state->first = true;
+ } else {
+ add_section_to_json(state, "open_files");
+ }
return 0;
}
+static uint32_t map_share_mode_to_deny_mode(
+ uint32_t share_access, uint32_t private_options)
+{
+ switch (share_access & ~FILE_SHARE_DELETE) {
+ case FILE_SHARE_NONE:
+ return DENY_ALL;
+ case FILE_SHARE_READ:
+ return DENY_WRITE;
+ case FILE_SHARE_WRITE:
+ return DENY_READ;
+ case FILE_SHARE_READ|FILE_SHARE_WRITE:
+ return DENY_NONE;
+ }
+ if (private_options & NTCREATEX_FLAG_DENY_DOS) {
+ return DENY_DOS;
+ } else if (private_options & NTCREATEX_FLAG_DENY_FCB) {
+ return DENY_FCB;
+ }
+
+ return (uint32_t)-1;
+}
+
static int print_share_mode(struct file_id fid,
const struct share_mode_data *d,
const struct share_mode_entry *e,
const char *filename = NULL;
const char *timestr = NULL;
const char *user_str = NULL;
+ uint32_t lstate;
struct traverse_state *state = (struct traverse_state *)private_data;
TALLOC_CTX *tmp_ctx = talloc_stackframe();
oplock = "LEVEL_II";
} else if (e->op_type == LEASE_OPLOCK) {
NTSTATUS status;
- uint32_t lstate;
status = leases_db_get(
&e->client_guid,
}
timestr = time_to_asc((time_t)e->time.tv_sec);
- print_share_mode_stdout(state,
- pid,
- user_str,
- denymode,
- (unsigned int)e->access_mask,
- rw,
- oplock,
- d->servicepath,
- filename,
- timestr);
+
+ if (!state->json_output) {
+ print_share_mode_stdout(state,
+ pid,
+ user_str,
+ denymode,
+ (unsigned int)e->access_mask,
+ rw,
+ oplock,
+ d->servicepath,
+ filename,
+ timestr);
+ } else {
+ print_share_mode_json(state,
+ d,
+ e,
+ fid,
+ user_str,
+ oplock,
+ lstate,
+ filename);
+ }
}
TALLOC_FREE(tmp_ctx);
return 0;
static int prepare_brl(struct traverse_state *state)
{
- /* only print header line if there are locked files */
- state->first = true;
-
+ if (!state->json_output) {
+ /* only print header line if there are locked files */
+ state->first = true;
+ } else {
+ add_section_to_json(state, "byte_range_locks");
+ }
return 0;
}
static void print_brl(struct file_id id,
- struct server_id pid,
+ struct server_id pid,
enum brl_type lock_type,
enum brl_flavour lock_flav,
br_off start,
share_mode = fetch_share_mode_unlocked(NULL, id);
if (share_mode) {
fname = share_mode_filename(NULL, share_mode);
+ sharepath = share_mode_servicepath(share_mode);
} else {
fname = talloc_strdup(NULL, "");
if (fname == NULL) {
}
}
- print_brl_stdout(state,
- server_id_str_buf(pid, &tmp),
- file_id_str_buf(id, &ftmp),
- desc,
- (intmax_t)start,
- (intmax_t)size,
- sharepath,
- fname);
+ if (!state->json_output) {
+ print_brl_stdout(state,
+ server_id_str_buf(pid, &tmp),
+ file_id_str_buf(id, &ftmp),
+ desc,
+ (intmax_t)start,
+ (intmax_t)size,
+ sharepath,
+ fname);
+ } else {
+ print_brl_json(state,
+ pid,
+ id,
+ desc,
+ lock_flav,
+ (intmax_t)start,
+ (intmax_t)size,
+ sharepath,
+ fname);
+
+ }
TALLOC_FREE(fname);
TALLOC_FREE(share_mode);
char *server_id,
const char *machine,
const char *timestr,
- const char *encryption,
- const char *signing)
+ const char *encryption_cipher,
+ enum crypto_degree encryption_degree,
+ const char *signing_cipher,
+ enum crypto_degree signing_degree)
{
+ fstring encryption;
+ fstring signing;
+
+ if (encryption_degree == CRYPTO_DEGREE_FULL) {
+ fstr_sprintf(encryption, "%s", encryption_cipher);
+ } else if (encryption_degree == CRYPTO_DEGREE_ANONYMOUS) {
+ fstr_sprintf(encryption, "anonymous(%s)", encryption_cipher);
+ } else if (encryption_degree == CRYPTO_DEGREE_PARTIAL) {
+ fstr_sprintf(encryption, "partial(%s)", encryption_cipher);
+ } else {
+ fstr_sprintf(encryption, "-");
+ }
+ if (signing_degree == CRYPTO_DEGREE_FULL) {
+ fstr_sprintf(signing, "%s", signing_cipher);
+ } else if (signing_degree == CRYPTO_DEGREE_ANONYMOUS) {
+ fstr_sprintf(signing, "anonymous(%s)", signing_cipher);
+ } else if (signing_degree == CRYPTO_DEGREE_PARTIAL) {
+ fstr_sprintf(signing, "partial(%s)", signing_cipher);
+ } else {
+ fstr_sprintf(signing, "-");
+ }
+
d_printf("%-12s %-7s %-13s %-32s %-12s %-12s\n",
servicename, server_id, machine, timestr, encryption, signing);
char *timestr = NULL;
int result = 0;
const char *encryption = "-";
+ enum crypto_degree encryption_degree = CRYPTO_DEGREE_NONE;
const char *signing = "-";
+ enum crypto_degree signing_degree = CRYPTO_DEGREE_NONE;
struct traverse_state *state = (struct traverse_state *)private_data;
TALLOC_CTX *tmp_ctx = talloc_stackframe();
return -1;
}
- if (smbXsrv_is_encrypted(crec->encryption_flags)) {
+ if (smbXsrv_is_encrypted(crec->encryption_flags) ||
+ smbXsrv_is_partially_encrypted(crec->encryption_flags))
+ {
switch (crec->cipher) {
case SMB_ENCRYPTION_GSSAPI:
encryption = "GSSAPI";
case SMB2_ENCRYPTION_AES128_GCM:
encryption = "AES-128-GCM";
break;
+ case SMB2_ENCRYPTION_AES256_CCM:
+ encryption = "AES-256-CCM";
+ break;
+ case SMB2_ENCRYPTION_AES256_GCM:
+ encryption = "AES-256-GCM";
+ break;
default:
encryption = "???";
- result = -1;
break;
}
+ if (smbXsrv_is_encrypted(crec->encryption_flags)) {
+ encryption_degree = CRYPTO_DEGREE_FULL;
+ } else if (smbXsrv_is_partially_encrypted(crec->encryption_flags)) {
+ encryption_degree = CRYPTO_DEGREE_PARTIAL;
+ }
+ if (encryption_degree != CRYPTO_DEGREE_NONE &&
+ !crec->authenticated)
+ {
+ encryption_degree = CRYPTO_DEGREE_ANONYMOUS;
+ }
}
- if (smbXsrv_is_signed(crec->signing_flags)) {
+ if (smbXsrv_is_signed(crec->signing_flags) ||
+ smbXsrv_is_partially_signed(crec->signing_flags))
+ {
switch (crec->signing) {
case SMB2_SIGNING_MD5_SMB1:
signing = "HMAC-MD5";
break;
default:
signing = "???";
- result = -1;
break;
}
+ if (smbXsrv_is_signed(crec->signing_flags)) {
+ signing_degree = CRYPTO_DEGREE_FULL;
+ } else if (smbXsrv_is_partially_signed(crec->signing_flags)) {
+ signing_degree = CRYPTO_DEGREE_PARTIAL;
+ }
+ if (signing_degree != CRYPTO_DEGREE_NONE &&
+ !crec->authenticated)
+ {
+ signing_degree = CRYPTO_DEGREE_ANONYMOUS;
+ }
}
if (!state->json_output) {
crec->machine,
timestr,
encryption,
- signing);
+ encryption_degree,
+ signing,
+ signing_degree);
} else {
result = traverse_connections_json(state,
- crec);
+ crec,
+ encryption,
+ encryption_degree,
+ signing,
+ signing_degree);
}
TALLOC_FREE(timestr);
if (encryption_degree == CRYPTO_DEGREE_FULL) {
fstr_sprintf(encryption, "%s", encryption_cipher);
+ } else if (encryption_degree == CRYPTO_DEGREE_ANONYMOUS) {
+ fstr_sprintf(encryption, "anonymous(%s)", encryption_cipher);
} else if (encryption_degree == CRYPTO_DEGREE_PARTIAL) {
fstr_sprintf(encryption, "partial(%s)", encryption_cipher);
} else {
}
if (signing_degree == CRYPTO_DEGREE_FULL) {
fstr_sprintf(signing, "%s", signing_cipher);
+ } else if (signing_degree == CRYPTO_DEGREE_ANONYMOUS) {
+ fstr_sprintf(signing, "anonymous(%s)", signing_cipher);
} else if (signing_degree == CRYPTO_DEGREE_PARTIAL) {
fstr_sprintf(signing, "partial(%s)", signing_cipher);
} else {
static int prepare_sessionid(struct traverse_state *state)
{
- /* always print header line */
- d_printf("\nSamba version %s\n",samba_version_string());
- d_printf("%-7s %-12s %-12s %-41s %-17s %-20s %-21s\n", "PID", "Username", "Group", "Machine", "Protocol Version", "Encryption", "Signing");
- d_printf("----------------------------------------------------------------------------------------------------------------------------------------\n");
-
+ if (!state->json_output) {
+ /* always print header line */
+ d_printf("\nSamba version %s\n",samba_version_string());
+ d_printf("%-7s %-12s %-12s %-41s %-17s %-20s %-21s\n", "PID", "Username", "Group", "Machine", "Protocol Version", "Encryption", "Signing");
+ d_printf("----------------------------------------------------------------------------------------------------------------------------------------\n");
+ } else {
+ add_section_to_json(state, "sessions");
+ }
return 0;
}
void *private_data)
{
fstring uid_gid_str;
+ fstring uid_str;
+ fstring gid_str;
struct server_id_buf tmp;
char *machine_hostname = NULL;
int result = 0;
Ucrit_addPid(session->pid);
if (numeric_only) {
+ fstr_sprintf(gid_str, "%u", (unsigned int)session->gid);
+ fstr_sprintf(uid_str, "%u", (unsigned int)session->uid);
fstr_sprintf(uid_gid_str, "%-12u %-12u",
(unsigned int)session->uid,
(unsigned int)session->gid);
* The session is not fully authenticated yet.
*/
fstrcpy(uid_gid_str, "(auth in progress)");
+ fstrcpy(gid_str, "(auth in progress)");
+ fstrcpy(uid_str, "(auth in progress)");
} else {
/*
* In theory it should not happen that one of
return -1;
}
}
+ fstr_sprintf(gid_str, "%s", gid_name);
+ fstr_sprintf(uid_str, "%s", uid_name);
fstr_sprintf(uid_gid_str, "%-12s %-12s",
uid_name, gid_name);
}
} else if (smbXsrv_is_partially_encrypted(session->encryption_flags)) {
encryption_degree = CRYPTO_DEGREE_PARTIAL;
}
+ if (encryption_degree != CRYPTO_DEGREE_NONE &&
+ !session->authenticated)
+ {
+ encryption_degree = CRYPTO_DEGREE_ANONYMOUS;
+ }
}
if (smbXsrv_is_signed(session->signing_flags) ||
} else if (smbXsrv_is_partially_signed(session->signing_flags)) {
signing_degree = CRYPTO_DEGREE_PARTIAL;
}
+ if (signing_degree != CRYPTO_DEGREE_NONE &&
+ !session->authenticated)
+ {
+ signing_degree = CRYPTO_DEGREE_ANONYMOUS;
+ }
}
- traverse_sessionid_stdout(state,
- server_id_str_buf(session->pid, &tmp),
- uid_gid_str,
- machine_hostname,
- session_dialect_str(session->connection_dialect),
- encryption,
- encryption_degree,
- signing,
- signing_degree);
+ if (!state->json_output) {
+ traverse_sessionid_stdout(state,
+ server_id_str_buf(session->pid, &tmp),
+ uid_gid_str,
+ machine_hostname,
+ session_dialect_str(session->connection_dialect),
+ encryption,
+ encryption_degree,
+ signing,
+ signing_degree);
+ } else {
+ result = traverse_sessionid_json(state,
+ session,
+ uid_str,
+ gid_str,
+ encryption,
+ encryption_degree,
+ signing,
+ signing_degree,
+ session_dialect_str(session->connection_dialect));
+ }
TALLOC_FREE(machine_hostname);
TALLOC_FREE(tmp_ctx);
static int prepare_notify(struct traverse_state *state)
{
- /* don't print header line */
-
+ if (!state->json_output) {
+ /* don't print header line */
+ } else {
+ add_section_to_json(state, "notifies");
+ }
return 0;
}
struct traverse_state *state = (struct traverse_state *)private_data;
bool result;
- result = print_notify_rec_stdout(state,
- path,
- server_id_str_buf(server, &idbuf),
- (unsigned)instance->filter,
- (unsigned)instance->subdir_filter);
+ if (!state->json_output) {
+ result = print_notify_rec_stdout(state,
+ path,
+ server_id_str_buf(server, &idbuf),
+ (unsigned)instance->filter,
+ (unsigned)instance->subdir_filter);
+
+ } else {
+ result = print_notify_rec_json(state,
+ instance,
+ server,
+ path);
+ }
return result;
}
.val = 'n',
.descrip = "Numeric uid/gid"
},
+ {
+ .longName = "json",
+ .shortName = 'j',
+ .argInfo = POPT_ARG_NONE,
+ .arg = NULL,
+ .val = 'j',
+ .descrip = "JSON output"
+ },
{
.longName = "fast",
.shortName = 'f',
struct messaging_context *msg_ctx = NULL;
char *db_path;
bool ok;
+ struct loadparm_context *lp_ctx = NULL;
state.first = true;
state.json_output = false;
TALLOC_FREE(frame);
exit(1);
}
- lp_set_cmdline("log level", "0");
+ lp_ctx = samba_cmdline_get_lp_ctx();
+ lpcfg_set_cmdline(lp_ctx, "log level", "0");
pc = samba_popt_get_context(getprogname(),
argc,
case 'n':
numeric_only = true;
break;
+ case 'j':
+ state.json_output = true;
+ break;
case 'f':
do_checks = false;
break;
#ifdef HAVE_JANSSON
state.root_json = json_new_object();
- add_general_information_to_json(&state);
+ if (!json_is_invalid(&state.root_json)) {
+ add_general_information_to_json(&state);
+ }
+#else /* HAVE_JANSSON */
+ if (state.json_output) {
+ fprintf(stderr, "JSON support not available, please install lib Jansson\n");
+ goto done;
+ }
#endif /* HAVE_JANSSON */
if (getuid() != geteuid()) {
if ( username )
Ucrit_addUid( nametouid(username) );
- if (verbose) {
+ if (verbose && !state.json_output) {
d_printf("using configfile = %s\n", get_dyn_CONFIGFILE());
}
switch (profile_only) {
case 'P':
/* Dump profile data */
- ok = status_profile_dump(verbose);
+ ok = status_profile_dump(verbose, &state);
ret = ok ? 0 : 1;
goto done;
case 'R':
/* Continuously display rate-converted data */
- ok = status_profile_rates(verbose);
- ret = ok ? 0 : 1;
+ if (!state.json_output) {
+ ok = status_profile_rates(verbose);
+ ret = ok ? 0 : 1;
+ } else {
+ fprintf(stderr, "Call rates not available in a json output.\n");
+ ret = 1;
+ }
goto done;
default:
break;
prepare_connections(&state);
connections_forall_read(traverse_connections, &state);
- d_printf("\n");
+ if (!state.json_output) {
+ d_printf("\n");
+ }
if ( shares_only ) {
goto done;
fprintf(stderr, "This is normal if an SMB client has never "
"connected to your server.\n");
TALLOC_FREE(db_path);
- exit(0);
+ ret = 0;
+ goto done;
} else {
TALLOC_FREE(db);
TALLOC_FREE(db_path);
prepare_share_mode(&state);
result = share_entry_forall(print_share_mode, &state);
- if (result == 0) {
+ if (result == 0 && !state.json_output) {
fprintf(stderr, "No locked files\n");
- } else if (result < 0) {
+ } else if (result < 0 && !state.json_output) {
fprintf(stderr, "locked file list truncated\n");
}
- d_printf("\n");
+ if (!state.json_output) {
+ d_printf("\n");
+ }
if (show_brl) {
prepare_brl(&state);
done:
cmdline_messaging_context_free();
poptFreeContext(pc);
+#ifdef HAVE_JANSSON
+ if (state.json_output) {
+ d_printf("%s\n", json_to_string(frame, &state.root_json));
+ }
+ json_free(&state.root_json);
+#endif /* HAVE_JANSSON */
TALLOC_FREE(frame);
return ret;
}