[RFC PATCH v3 4/5] s3: net: implement json output for ads info

Gary Lockyer gary at catalyst.net.nz
Thu Jul 12 19:24:44 UTC 2018


See comments in line, but looks good.

Gary

On 12/07/18 19:04, Philipp Gesang via samba-technical wrote:
> Add the switch '-j' 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.
> 
> Signed-off-by: Philipp Gesang <philipp.gesang at intra2net.com>
> ---
>  source3/utils/net.c         |   1 +
>  source3/utils/net.h         |   1 +
>  source3/utils/net_ads.c     | 114 ++++++++++++++++++++++++++++++++++++++++++++
>  source3/utils/wscript_build |   2 +
>  4 files changed, 118 insertions(+)
> 
> diff --git a/source3/utils/net.c b/source3/utils/net.c
> index 44daa6088ca..57b853a684a 100644
> --- a/source3/utils/net.c
> +++ b/source3/utils/net.c
> @@ -973,6 +973,7 @@ static struct functable net_func[] = {
>  		{"precheck", 0, POPT_ARG_STRING, &c->opt_precheck},
>  		/* Options for 'net ads join' */
>  		{"no-dns-updates", 0, POPT_ARG_NONE, &c->opt_no_dns_updates},
> +		{"json", 'j', 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 d6dfeb6208f..af748c0275f 100644
> --- a/source3/utils/net.h
> +++ b/source3/utils/net.h
> @@ -85,6 +85,7 @@ struct net_context {
>  	int opt_wipe;
>  	const char *opt_precheck;
>  	int opt_no_dns_updates;
> +	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 ffa67d8f525..c2350ca027f 100644
> --- a/source3/utils/net_ads.c
> +++ b/source3/utils/net_ads.c
> @@ -173,6 +173,116 @@ static int net_ads_lookup(struct net_context *c, int argc, const char **argv)
>  }
>  
>  
> +#ifdef HAVE_JANSSON
> +#include <jansson.h>
> +#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();
> +
> +	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) {
> +		goto failure;
> +	}
> +
> +	ret = json_add_string (&jsobj, "LDAP server name", ads->config.ldap_server_name);
> +	if (ret) {
> +		goto failure;
> +	}
> +
> +	ret = json_add_string (&jsobj, "Realm", ads->config.realm);
> +	if (ret) {
> +		goto failure;
> +	}
> +
> +	ret = json_add_string (&jsobj, "Bind Path", ads->config.bind_path);
> +	if (ret) {
> +		goto failure;
> +	}
> +
> +	ret = json_add_int (&jsobj, "LDAP port", ads->ldap.port);
> +	if (ret) {
> +		goto failure;
> +	}
> +
> +	ret = json_add_int (&jsobj, "Server time", ads->config.current_time);
> +	if (ret) {
> +		goto failure;
> +	}
> +
> +	ret = json_add_string (&jsobj, "KDC server", ads->auth.kdc_server);
> +	if (ret) {
> +		goto failure;
> +	}
> +
> +	ret = json_add_int (&jsobj, "Server time offset", ads->auth.time_offset);
> +	if (ret) {
> +		goto failure;
> +	}
> +
> +	ret = json_add_int (&jsobj, "Last machine account password change", pass_time);
> +	if (ret) {
> +		goto failure;
> +	}
> +
> +	if (json_is_invalid(&jsobj)) {
> +		ret = -1;
> +		goto failure;
> +	}
> +
> +	if (jsobj.root == NULL) {
> +		ret = -1;
> +		goto failure;
> +	}
> +

This should use json_to_string, one of the poorly articulated goals of
the json_* functions is to abstract the underlying JSON library.

> +	json = json_dumps(jsobj.root, 0);
> +	if (json) {
> +		d_printf("%s\n", json);
> +		free (json);
> +	} else {
> +		ret = -1;
> +		d_fprintf(stderr, _("error encoding to JSON\n"));
> +	}
> +
> +failure:
> +	json_free(&jsobj);
> +	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 +318,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 8b4d890d485..09b3306d0a4 100644
> --- a/source3/utils/wscript_build
> +++ b/source3/utils/wscript_build
> @@ -248,6 +248,8 @@ bld.SAMBA3_BINARY('net',
>                   printing_migrate
>                   trusts_util
>                   IDMAP_AUTORID_TDB
> +                 jansson
> +                 common_auth
>                   ''')
>  
>  bld.SAMBA3_BINARY('mvxattr',
> 



-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20180713/b45be28d/signature.sig>


More information about the samba-technical mailing list