From 2e00ad44aa6822817f7e988cdfa7c87fc3aa5257 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 2 Jul 2018 16:21:59 +0200 Subject: [PATCH] s3: net: implement json output for ads info Add the switch '--json' to 'net' to format the output as JSON. The rationale is to supply the information in a machine-readable fashion to complement the text version of the output which is neither particularly well defined nor locale-safe. The output differs from that of plain 'info' in that times are not formatted as timestamps. Currently affects only the 'net ads info' subcommand. Reviewed-by: Gary Lockyer Signed-off-by: Philipp Gesang Reviewed-by: Andrew Bartlett --- source3/utils/net.c | 1 + source3/utils/net.h | 1 + source3/utils/net_ads.c | 121 ++++++++++++++++++++++++++++++++++++++++++++ source3/utils/wscript_build | 2 + 4 files changed, 125 insertions(+) diff --git a/source3/utils/net.c b/source3/utils/net.c index b3bd4b67118..7f07644b611 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -973,6 +973,7 @@ static struct functable net_func[] = { /* Options for 'net ads join or leave' */ {"no-dns-updates", 0, POPT_ARG_NONE, &c->opt_no_dns_updates}, {"keep-account", 0, POPT_ARG_NONE, &c->opt_keep_account}, + {"json", 0, POPT_ARG_NONE, &c->opt_json}, POPT_COMMON_SAMBA { 0, 0, 0, 0} }; diff --git a/source3/utils/net.h b/source3/utils/net.h index 5e70fd3aafa..0d01ad45010 100644 --- a/source3/utils/net.h +++ b/source3/utils/net.h @@ -86,6 +86,7 @@ struct net_context { const char *opt_precheck; int opt_no_dns_updates; int opt_keep_account; + int opt_json; int opt_have_ip; struct sockaddr_storage opt_dest_ip; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index afe47dad839..416a7b8d927 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -173,6 +173,123 @@ static int net_ads_lookup(struct net_context *c, int argc, const char **argv) } +#ifdef HAVE_JANSSON +#include +#include "audit_logging.h" /* various JSON helpers */ +#include "auth/common_auth.h" + +/* + * note: JSON output deliberately bypasses gettext so as to provide the same + * output irrespective of the locale. + */ + +static int net_ads_info_json(ADS_STRUCT *ads) +{ + int ret = 0; + char addr[INET6_ADDRSTRLEN]; + time_t pass_time; + struct json_object jsobj = json_new_object(); + TALLOC_CTX *ctx = NULL; + char *json = NULL; + + if (json_is_invalid(&jsobj)) { + d_fprintf(stderr, _("error setting up JSON value\n")); + + goto failure; + } + + pass_time = secrets_fetch_pass_last_set_time(ads->server.workgroup); + + print_sockaddr(addr, sizeof(addr), &ads->ldap.ss); + + ret = json_add_string (&jsobj, "LDAP server", addr); + if (ret != 0) { + goto failure; + } + + ret = json_add_string (&jsobj, "LDAP server name", + ads->config.ldap_server_name); + if (ret != 0) { + goto failure; + } + + ret = json_add_string (&jsobj, "Realm", ads->config.realm); + if (ret != 0) { + goto failure; + } + + ret = json_add_string (&jsobj, "Bind Path", ads->config.bind_path); + if (ret != 0) { + goto failure; + } + + ret = json_add_int (&jsobj, "LDAP port", ads->ldap.port); + if (ret != 0) { + goto failure; + } + + ret = json_add_int (&jsobj, "Server time", ads->config.current_time); + if (ret != 0) { + goto failure; + } + + ret = json_add_string (&jsobj, "KDC server", ads->auth.kdc_server); + if (ret != 0) { + goto failure; + } + + ret = json_add_int (&jsobj, "Server time offset", + ads->auth.time_offset); + if (ret != 0) { + goto failure; + } + + ret = json_add_int (&jsobj, "Last machine account password change", + pass_time); + if (ret != 0) { + goto failure; + } + + if (json_is_invalid(&jsobj)) { + ret = -1; + goto failure; + } + + ctx = talloc_new(NULL); + if (ctx == NULL) { + ret = -1; + d_fprintf(stderr, _("Out of memory\n")); + + goto failure; + } + + json = json_to_string(ctx, &jsobj); + if (json) { + d_printf("%s\n", json); + } else { + ret = -1; + d_fprintf(stderr, _("error encoding to JSON\n")); + } + + TALLOC_FREE(ctx); +failure: + ads_destroy(&ads); + + return ret; +} + +#else /* [HAVE_JANSSON] */ + +static int net_ads_info_json(ADS_STRUCT *) +{ + d_fprintf(stderr, _("JSON support not available\n")); + + return -1; +} + +#endif /* [HAVE_JANSSON] */ + + static int net_ads_info(struct net_context *c, int argc, const char **argv) { @@ -208,6 +325,10 @@ static int net_ads_info(struct net_context *c, int argc, const char **argv) d_fprintf( stderr, _("Failed to get server's current time!\n")); } + if (c->opt_json) { + return net_ads_info_json(ads); + } + pass_time = secrets_fetch_pass_last_set_time(ads->server.workgroup); print_sockaddr(addr, sizeof(addr), &ads->ldap.ss); diff --git a/source3/utils/wscript_build b/source3/utils/wscript_build index 6793c6d5c8a..c6d1c29b310 100644 --- a/source3/utils/wscript_build +++ b/source3/utils/wscript_build @@ -263,6 +263,8 @@ bld.SAMBA3_BINARY('net', printing_migrate trusts_util IDMAP_AUTORID_TDB + jansson + common_auth ''') bld.SAMBA3_BINARY('mvxattr', -- 2.11.4.GIT