diff options
author | Noel Power <noel.power@suse.com> | 2018-01-24 14:51:03 +0000 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2018-03-02 14:07:14 +0100 |
commit | 5fa82263ad6bc82c9a8b34797df35bd800b7f11f (patch) | |
tree | 1995c1bb4eb91f50cf862a2948133ee2d91f44e4 | |
parent | 8a6c3c5ae2cab809d994821ed573315ba0c7562d (diff) | |
download | samba-5fa82263ad6bc82c9a8b34797df35bd800b7f11f.tar.gz |
s3:utils: add new 'net ads setspn delete' subcommand
This patch adds 'delete' 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 delete <computer> <SPN>
Note: <computer> is optional, if not specified the computer account
associated with value returned by lp_netbios_name() is used instead.
Signed-off-by: Noel Power <noel.power@suse.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
-rw-r--r-- | source3/libads/ads_proto.h | 3 | ||||
-rw-r--r-- | source3/libads/net_ads_setspn.c | 97 | ||||
-rw-r--r-- | source3/utils/net_ads.c | 39 |
3 files changed, 139 insertions, 0 deletions
diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h index f7a9f426639..3934c1cfe27 100644 --- a/source3/libads/ads_proto.h +++ b/source3/libads/ads_proto.h @@ -58,6 +58,9 @@ int ads_keytab_list(const char *keytab_name); bool ads_setspn_list(ADS_STRUCT *ads, const char *machine); bool ads_setspn_add(ADS_STRUCT *ads, const char *machine_name, const char * spn); +bool ads_setspn_delete(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 41d698be7db..b1631843263 100644 --- a/source3/libads/net_ads_setspn.c +++ b/source3/libads/net_ads_setspn.c @@ -129,4 +129,101 @@ done: return ret; } +bool ads_setspn_delete(ADS_STRUCT *ads, + const char *machine_name, + const char * spn) +{ + size_t i = 0, j = 0; + TALLOC_CTX *frame = NULL; + char **spn_array = NULL; + const char **new_spn_array = NULL; + char *lc_spn = NULL; + size_t num_spns = 0; + ADS_STATUS status; + ADS_MODLIST mods; + bool ok = false; + LDAPMessage *res = NULL; + + frame = talloc_stackframe(); + + lc_spn = strlower_talloc(frame, spn); + if (lc_spn == NULL) { + DBG_ERR("Out of memory, lowercasing %s.\n", spn); + goto done; + } + + status = ads_find_machine_acct(ads, + &res, + machine_name); + if (!ADS_ERR_OK(status)) { + goto done; + } + + status = ads_get_service_principal_names(frame, + ads, + machine_name, + &spn_array, + &num_spns); + if (!ADS_ERR_OK(status)) { + goto done; + } + + new_spn_array = talloc_zero_array(frame, const char*, num_spns + 1); + if (!new_spn_array) { + DBG_ERR("Out of memory, failed to allocate array.\n"); + goto done; + } + + /* + * create new spn list to write to object (excluding the spn to + * be deleted). + */ + for (i = 0, j = 0; i < num_spns; i++) { + /* + * windows setspn.exe deletes matching spn in a case + * insensitive way. + */ + char *lc_spn_attr = strlower_talloc(frame, spn_array[i]); + if (lc_spn_attr == NULL) { + DBG_ERR("Out of memory, lowercasing %s.\n", + spn_array[i]); + goto done; + } + + if (!strequal(lc_spn, lc_spn_attr)) { + new_spn_array[j++] = spn_array[i]; + } + } + + /* found and removed spn */ + if (j < num_spns) { + char *dn = NULL; + mods = ads_init_mods(frame); + if (mods == NULL) { + goto done; + } + d_printf("Unregistering SPN %s for %s\n", spn, machine_name); + status = ads_mod_strlist(frame, &mods, "servicePrincipalName", new_spn_array); + if (!ADS_ERR_OK(status)) { + goto done; + } + + dn = ads_get_dn(ads, frame, res); + if (dn == NULL ) { + goto done; + } + + status = ads_gen_mod(ads, dn, mods); + if (!ADS_ERR_OK(status)) { + goto done; + } + } + d_printf("Updated object\n"); + + ok = true; +done: + TALLOC_FREE(frame); + return ok; +} + #endif /* HAVE_ADS */ diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 3f59f51a419..a5d1928f30b 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -3067,6 +3067,37 @@ done: return ret; } +static int net_ads_setspn_delete(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 delete <machinename> 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_delete(ads, argv[0], argv[1]); + } else { + ok = ads_setspn_delete(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[] = { @@ -3086,6 +3117,14 @@ int net_ads_setspn(struct net_context *c, int argc, const char **argv) N_("net ads setspn add machine spn\n" " Add Service Principal Names (SPN)") }, + { + "delete", + net_ads_setspn_delete, + NET_TRANSPORT_ADS, + N_("Delete Service Principal Names (SPN)"), + N_("net ads setspn delete machine spn\n" + " Delete Service Principal Names (SPN)") + }, {NULL, NULL, 0, NULL, NULL} }; |