From 8a6c3c5ae2cab809d994821ed573315ba0c7562d Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 24 Jan 2018 14:41:06 +0000 Subject: [PATCH] s3:utils: add new 'net ads setspn add' subcommand This patch adds 'add' to the 'net ads setspn' subcommand (see https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/cc731241(v=ws.11) Usage: net ads setspn add Note: is optional, if not specified the computer account associated with value returned by lp_netbios_name() is used instead. Signed-off-by: Noel Power Reviewed-by: Jeremy Allison Reviewed-by: Andreas Schneider --- source3/libads/ads_proto.h | 3 +- source3/libads/net_ads_setspn.c | 78 +++++++++++++++++++++++++++++++++ source3/utils/net_ads.c | 39 +++++++++++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h index d806ce49c16..f7a9f426639 100644 --- a/source3/libads/ads_proto.h +++ b/source3/libads/ads_proto.h @@ -56,7 +56,8 @@ int ads_keytab_list(const char *keytab_name); /* The following definitions come from libads/net_ads_setspn.c */ bool ads_setspn_list(ADS_STRUCT *ads, const char *machine); - +bool ads_setspn_add(ADS_STRUCT *ads, const char *machine_name, + const char * spn); /* The following definitions come from libads/krb5_errs.c */ /* The following definitions come from libads/kerberos_util.c */ diff --git a/source3/libads/net_ads_setspn.c b/source3/libads/net_ads_setspn.c index 7bef330bf51..41d698be7db 100644 --- a/source3/libads/net_ads_setspn.c +++ b/source3/libads/net_ads_setspn.c @@ -51,4 +51,82 @@ done: return ok; } +/* returns true if spn exists in spn_array (match is NOT case-sensitive) */ +static bool find_spn_in_spnlist(TALLOC_CTX *ctx, + const char *spn, + char **spn_array, + size_t num_spns) +{ + char *lc_spn = NULL; + size_t i = 0; + + lc_spn = strlower_talloc(ctx, spn); + if (lc_spn == NULL) { + DBG_ERR("Out of memory, lowercasing %s.\n", + spn); + return false; + } + + for (i = 0; i < num_spns; i++) { + char *lc_spn_attr = strlower_talloc(ctx, spn_array[i]); + if (lc_spn_attr == NULL) { + DBG_ERR("Out of memory, lowercasing %s.\n", + spn_array[i]); + return false; + } + + if (strequal(lc_spn, lc_spn_attr)) { + return true; + } + } + + return false; +} + +bool ads_setspn_add(ADS_STRUCT *ads, const char *machine_name, const char * spn) +{ + bool ret = false; + TALLOC_CTX *frame = NULL; + ADS_STATUS status; + struct spn_struct *spn_struct = NULL; + const char *spns[2] = {NULL, NULL}; + char **existing_spns = NULL; + size_t num_spns = 0; + bool found = false; + + frame = talloc_stackframe(); + spns[0] = spn; + spn_struct = parse_spn(frame, spn); + if (spn_struct == NULL) { + goto done; + } + + status = ads_get_service_principal_names(frame, + ads, + machine_name, + &existing_spns, + &num_spns); + + if (!ADS_ERR_OK(status)) { + goto done; + } + + found = find_spn_in_spnlist(frame, spn, existing_spns, num_spns); + if (found) { + d_printf("Duplicate SPN found, aborting operation.\n"); + goto done; + } + + d_printf("Registering SPN %s for object %s\n", spn, machine_name); + status = ads_add_service_principal_names(ads, machine_name, spns); + if (!ADS_ERR_OK(status)) { + goto done; + } + ret = true; + d_printf("Updated object\n"); +done: + TALLOC_FREE(frame); + return ret; +} + #endif /* HAVE_ADS */ diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 4243cacc2d2..3f59f51a419 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -3036,6 +3036,37 @@ done: return ret; } +static int net_ads_setspn_add(struct net_context *c, int argc, const char **argv) +{ + int ret = 0; + bool ok = false; + ADS_STRUCT *ads = NULL; + if (c->display_usage || argc < 1) { + d_printf("%s\n%s", + _("Usage:"), + _("net ads setspn add SPN\n")); + ret = 0; + goto done; + } + if (!ADS_ERR_OK(ads_startup(c, true, &ads))) { + ret = -1; + goto done; + } + if (argc > 1) { + ok = ads_setspn_add(ads, argv[0], argv[1]); + } else { + ok = ads_setspn_add(ads, lp_netbios_name(), argv[0]); + } + if (!ok) { + ret = -1; + } +done: + if (ads) { + ads_destroy(&ads); + } + return ret; +} + int net_ads_setspn(struct net_context *c, int argc, const char **argv) { struct functable func[] = { @@ -3047,6 +3078,14 @@ int net_ads_setspn(struct net_context *c, int argc, const char **argv) N_("net ads setspn list machine\n" " List Service Principal Names (SPN)") }, + { + "add", + net_ads_setspn_add, + NET_TRANSPORT_ADS, + N_("Add Service Principal Names (SPN)"), + N_("net ads setspn add machine spn\n" + " Add Service Principal Names (SPN)") + }, {NULL, NULL, 0, NULL, NULL} }; -- 2.34.1