[PATCH 2/2] s3: net: implement json output for ads lookup

Philipp Gesang philipp.gesang at intra2net.com
Fri Jul 6 14:48:53 UTC 2018


Add JSON printer (option '-j') for the 'net ads lookup' command.
This outputs the same information as the plain version, with
integral ({LMNT,LM20} Token, NT Version) and boolean values
(Flags) not stringified.

Signed-off-by: Philipp Gesang <philipp.gesang at intra2net.com>
---
 source3/utils/net_ads.c | 143 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 127 insertions(+), 16 deletions(-)

diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 44e5d8bf396..f6d8fa936e8 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -41,6 +41,12 @@
 #include "lib/param/loadparm.h"
 #include "utils/net_dns.h"
 
+#ifdef HAVE_JANSSON
+#include <jansson.h>
+#include "audit_logging.h" /* various JSON helpers */
+#include "auth/common_auth.h"
+#endif /* [HAVE_JANSSON] */
+
 #ifdef HAVE_ADS
 
 /* when we do not have sufficient input parameters to contact a remote domain
@@ -55,6 +61,118 @@ static const char *assume_own_realm(struct net_context *c)
 	return NULL;
 }
 
+#ifdef HAVE_JANSSON
+
+static int output_json(const struct json_object *jsobj)
+{
+	char *json;
+
+	json = json_dumps(jsobj->root, 0);
+	if (!json)
+	{
+	  d_fprintf(stderr, _("error encoding to JSON\n"));
+	  return -1;
+  }
+
+	d_printf("%s\n", json);
+
+	return 0;
+}
+
+static int net_ads_cldap_netlogon_json(ADS_STRUCT *ads,
+				       const char *addr,
+				       const struct NETLOGON_SAM_LOGON_RESPONSE_EX *reply)
+{
+	struct json_object jsobj;
+	struct json_object flagsobj;
+	char response_type [32] = { '\0' };
+	int ret;
+
+	jsobj = json_new_object ();
+	if (jsobj.error) {
+		d_fprintf(stderr, _("error setting up JSON value\n"));
+
+		return -1;
+	}
+
+	flagsobj = json_new_object ();
+	if (flagsobj.error) {
+		d_fprintf(stderr, _("error setting up JSON value\n"));
+		json_free(&jsobj);
+
+		return -1;
+	}
+
+	switch (reply->command) {
+		case LOGON_SAM_LOGON_USER_UNKNOWN_EX:
+			strncpy(response_type, "LOGON_SAM_LOGON_USER_UNKNOWN_EX",
+	      sizeof(response_type));
+			break;
+		case LOGON_SAM_LOGON_RESPONSE_EX:
+			strncpy(response_type, "LOGON_SAM_LOGON_RESPONSE_EX",
+	      sizeof(response_type));
+			break;
+		default:
+			snprintf(response_type, sizeof(response_type), "0x%x",
+	       reply->command);
+			break;
+	}
+
+	json_add_string(&jsobj, "Information for Domain Controller", addr);
+	json_add_string(&jsobj, "Response Type", response_type);
+	json_add_string(&jsobj, "GUID", GUID_string(talloc_tos(),&reply->domain_uuid));
+
+	json_add_bool(&flagsobj, "Is a PDC",                                   reply->server_type & NBT_SERVER_PDC);
+	json_add_bool(&flagsobj, "Is a GC of the forest",                      reply->server_type & NBT_SERVER_GC);
+	json_add_bool(&flagsobj, "Is an LDAP server",                          reply->server_type & NBT_SERVER_LDAP);
+	json_add_bool(&flagsobj, "Supports DS",                                reply->server_type & NBT_SERVER_DS);
+	json_add_bool(&flagsobj, "Is running a KDC",                           reply->server_type & NBT_SERVER_KDC);
+	json_add_bool(&flagsobj, "Is running time services",                   reply->server_type & NBT_SERVER_TIMESERV);
+	json_add_bool(&flagsobj, "Is the closest DC",                          reply->server_type & NBT_SERVER_CLOSEST);
+	json_add_bool(&flagsobj, "Is writable",                                reply->server_type & NBT_SERVER_WRITABLE);
+	json_add_bool(&flagsobj, "Has a hardware clock",                       reply->server_type & NBT_SERVER_GOOD_TIMESERV);
+	json_add_bool(&flagsobj, "Is a non-domain NC serviced by LDAP server", reply->server_type & NBT_SERVER_NDNC);
+	json_add_bool(&flagsobj, "Is NT6 DC that has some secrets",            reply->server_type & NBT_SERVER_SELECT_SECRET_DOMAIN_6);
+	json_add_bool(&flagsobj, "Is NT6 DC that has all secrets",             reply->server_type & NBT_SERVER_FULL_SECRET_DOMAIN_6);
+	json_add_bool(&flagsobj, "Runs Active Directory Web Services",         reply->server_type & NBT_SERVER_ADS_WEB_SERVICE);
+	json_add_bool(&flagsobj, "Runs on Windows 2012 or later",              reply->server_type & NBT_SERVER_DS_8);
+
+	json_add_object(&jsobj, "Flags", &flagsobj);
+
+	json_add_string(&jsobj, "Forest", reply->forest);
+	json_add_string(&jsobj, "Domain", reply->dns_domain);
+	json_add_string(&jsobj, "Domain Controller", reply->pdc_dns_name);
+
+	json_add_string(&jsobj, "Pre-Win2k Domain", reply->domain_name);
+	json_add_string(&jsobj, "Pre-Win2k Hostname", reply->pdc_name);
+
+	if (*reply->user_name) json_add_string(&jsobj, "User name", reply->user_name);
+
+	json_add_string(&jsobj, "Server Site Name", reply->server_site);
+	json_add_string(&jsobj, "Client Site Name", reply->client_site);
+
+	json_add_int(&jsobj, "NT Version", reply->nt_version);
+	json_add_int(&jsobj, "LMNT Token", reply->lmnt_token);
+	json_add_int(&jsobj, "LM20 Token", reply->lm20_token);
+
+	ret = output_json(&jsobj);
+	json_free(&jsobj);
+
+	return ret;
+}
+
+#else /* [HAVE_JANSSON] */
+
+static int net_ads_cldap_netlogon_json(ADS_STRUCT *, const char *,
+				       const struct NETLOGON_SAM_LOGON_RESPONSE_EX *)
+{
+	d_fprintf(stderr, _("JSON support not available\n"));
+
+	return -1;
+}
+
+#endif /* [HAVE_JANSSON] */
+
 /*
   do a cldap netlogon query
 */
@@ -70,6 +188,10 @@ static int net_ads_cldap_netlogon(struct net_context *c, ADS_STRUCT *ads)
 		return -1;
 	}
 
+	if (c->opt_json) {
+		return net_ads_cldap_netlogon_json(ads, addr, &reply);
+	}
+
 	d_printf(_("Information for Domain Controller: %s\n\n"),
 		addr);
 
@@ -174,9 +296,6 @@ 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
@@ -185,10 +304,10 @@ static int net_ads_lookup(struct net_context *c, int argc, const char **argv)
 
 static int net_ads_info_json(ADS_STRUCT *ads)
 {
+	int ret;
 	char addr[INET6_ADDRSTRLEN];
 	time_t pass_time;
 	struct json_object jsobj;
-	char *json;
 
 	jsobj = json_new_object ();
 	if (jsobj.error)
@@ -214,20 +333,12 @@ static int net_ads_info_json(ADS_STRUCT *ads)
 
 	json_add_int (&jsobj, "Last machine account password change", pass_time);
 
-	ads_destroy(&ads);
+	ret = output_json(&jsobj);
+	json_free(&jsobj);
 
-	json = json_dumps(jsobj.root, 0);
-	if (!json)
-	{
-		d_fprintf(stderr, _("error encoding to JSON\n"));
-		return -1;
-	}
-
-	d_printf("%s\n", json);
-
-	free (json);
+	ads_destroy(&ads);
 
-	return 0;
+	return ret;
 }
 
 #else /* [HAVE_JANSSON] */
-- 
2.13.6




More information about the samba-technical mailing list