diff options
author | Philipp Gesang <philipp.gesang@intra2net.com> | 2018-07-03 12:09:17 +0200 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2018-09-22 06:05:06 +0200 |
commit | 5534b9248fa375799ad4bc6f45a69dcf14e6419e (patch) | |
tree | a39a3428099dc4946ba9d982005674161503f806 /source3/utils/net_ads.c | |
parent | 2e00ad44aa6822817f7e988cdfa7c87fc3aa5257 (diff) | |
download | samba-5534b9248fa375799ad4bc6f45a69dcf14e6419e.tar.gz |
s3: net: implement json output for ads lookup
Add JSON printer (option '--json') 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.
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
Signed-off-by: Philipp Gesang <philipp.gesang@intra2net.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source3/utils/net_ads.c')
-rw-r--r-- | source3/utils/net_ads.c | 301 |
1 files changed, 269 insertions, 32 deletions
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 416a7b8d927..054d8ddc648 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,263 @@ static const char *assume_own_realm(struct net_context *c) return NULL; } +#ifdef HAVE_JANSSON + +/* + * note: JSON output deliberately bypasses gettext so as to provide the same + * output irrespective of the locale. + */ + +static int output_json(const struct json_object *jsobj) +{ + TALLOC_CTX *ctx = NULL; + char *json = NULL; + + if (json_is_invalid(jsobj)) { + return -1; + } + + ctx = talloc_new(NULL); + if (ctx == NULL) { + d_fprintf(stderr, _("Out of memory\n")); + return -1; + } + + json = json_to_string(ctx, jsobj); + if (!json) { + d_fprintf(stderr, _("error encoding to JSON\n")); + return -1; + } + + d_printf("%s\n", json); + TALLOC_FREE(ctx); + + 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 = json_new_object(); + struct json_object flagsobj = json_new_object(); + char response_type [32] = { '\0' }; + int ret = 0; + + if (json_is_invalid(&jsobj) || json_is_invalid(&flagsobj)) { + d_fprintf(stderr, _("error setting up JSON value\n")); + + goto failure; + } + + 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; + } + + ret = json_add_string(&jsobj, "Information for Domain Controller", + addr); + if (ret != 0) { + goto failure; + } + + ret = json_add_string(&jsobj, "Response Type", response_type); + if (ret != 0) { + goto failure; + } + + ret = json_add_guid(&jsobj, "GUID", &reply->domain_uuid); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool(&flagsobj, "Is a PDC", + reply->server_type & NBT_SERVER_PDC); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool(&flagsobj, "Is a GC of the forest", + reply->server_type & NBT_SERVER_GC); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool(&flagsobj, "Is an LDAP server", + reply->server_type & NBT_SERVER_LDAP); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool(&flagsobj, "Supports DS", + reply->server_type & NBT_SERVER_DS); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool(&flagsobj, "Is running a KDC", + reply->server_type & NBT_SERVER_KDC); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool(&flagsobj, "Is running time services", + reply->server_type & NBT_SERVER_TIMESERV); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool(&flagsobj, "Is the closest DC", + reply->server_type & NBT_SERVER_CLOSEST); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool(&flagsobj, "Is writable", + reply->server_type & NBT_SERVER_WRITABLE); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool(&flagsobj, "Has a hardware clock", + reply->server_type & NBT_SERVER_GOOD_TIMESERV); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool(&flagsobj, + "Is a non-domain NC serviced by LDAP server", + reply->server_type & NBT_SERVER_NDNC); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool + (&flagsobj, "Is NT6 DC that has some secrets", + reply->server_type & NBT_SERVER_SELECT_SECRET_DOMAIN_6); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool + (&flagsobj, "Is NT6 DC that has all secrets", + reply->server_type & NBT_SERVER_FULL_SECRET_DOMAIN_6); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool(&flagsobj, "Runs Active Directory Web Services", + reply->server_type & NBT_SERVER_ADS_WEB_SERVICE); + if (ret != 0) { + goto failure; + } + + ret = json_add_bool(&flagsobj, "Runs on Windows 2012 or later", + reply->server_type & NBT_SERVER_DS_8); + if (ret != 0) { + goto failure; + } + + ret = json_add_string(&jsobj, "Forest", reply->forest); + if (ret != 0) { + goto failure; + } + + ret = json_add_string(&jsobj, "Domain", reply->dns_domain); + if (ret != 0) { + goto failure; + } + + ret = json_add_string(&jsobj, "Domain Controller", reply->pdc_dns_name); + if (ret != 0) { + goto failure; + } + + + ret = json_add_string(&jsobj, "Pre-Win2k Domain", reply->domain_name); + if (ret != 0) { + goto failure; + } + + ret = json_add_string(&jsobj, "Pre-Win2k Hostname", reply->pdc_name); + if (ret != 0) { + goto failure; + } + + if (*reply->user_name) { + ret = json_add_string(&jsobj, "User name", reply->user_name); + if (ret != 0) { + goto failure; + } + } + + ret = json_add_string(&jsobj, "Server Site Name", reply->server_site); + if (ret != 0) { + goto failure; + } + + ret = json_add_string(&jsobj, "Client Site Name", reply->client_site); + if (ret != 0) { + goto failure; + } + + ret = json_add_int(&jsobj, "NT Version", reply->nt_version); + if (ret != 0) { + goto failure; + } + + ret = json_add_int(&jsobj, "LMNT Token", reply->lmnt_token); + if (ret != 0) { + goto failure; + } + + ret = json_add_int(&jsobj, "LM20 Token", reply->lm20_token); + if (ret != 0) { + goto failure; + } + + ret = json_add_object(&jsobj, "Flags", &flagsobj); + if (ret != 0) { + goto failure; + } + + ret = output_json(&jsobj); + json_free(&jsobj); /* frees flagsobj recursively */ + + return ret; + +failure: + json_free(&flagsobj); + 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 +333,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,14 +441,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 - * output irrespective of the locale. - */ static int net_ads_info_json(ADS_STRUCT *ads) { @@ -189,8 +448,6 @@ static int net_ads_info_json(ADS_STRUCT *ads) 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")); @@ -250,29 +507,9 @@ static int net_ads_info_json(ADS_STRUCT *ads) 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); + ret = output_json(&jsobj); failure: + json_free(&jsobj); ads_destroy(&ads); return ret; |