2 Unix SMB/CIFS implementation.
3 net ads setspn routines
4 Copyright (C) Noel Power 2018
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 bool ads_setspn_list(ADS_STRUCT *ads, const char *machine_name)
27 TALLOC_CTX *frame = NULL;
28 char **spn_array = NULL;
33 frame = talloc_stackframe();
34 status = ads_get_service_principal_names(frame,
39 if (!ADS_ERR_OK(status)) {
43 d_printf("Registered SPNs for %s\n", machine_name);
44 for (i = 0; i < num_spns; i++) {
45 d_printf("\t%s\n", spn_array[i]);
54 /* returns true if spn exists in spn_array (match is NOT case-sensitive) */
55 static bool find_spn_in_spnlist(TALLOC_CTX *ctx,
63 lc_spn = strlower_talloc(ctx, spn);
65 DBG_ERR("Out of memory, lowercasing %s.\n",
70 for (i = 0; i < num_spns; i++) {
71 char *lc_spn_attr = strlower_talloc(ctx, spn_array[i]);
72 if (lc_spn_attr == NULL) {
73 DBG_ERR("Out of memory, lowercasing %s.\n",
78 if (strequal(lc_spn, lc_spn_attr)) {
86 bool ads_setspn_add(ADS_STRUCT *ads, const char *machine_name, const char * spn)
89 TALLOC_CTX *frame = NULL;
91 struct spn_struct *spn_struct = NULL;
92 const char *spns[2] = {NULL, NULL};
93 char **existing_spns = NULL;
97 frame = talloc_stackframe();
99 spn_struct = parse_spn(frame, spn);
100 if (spn_struct == NULL) {
104 status = ads_get_service_principal_names(frame,
110 if (!ADS_ERR_OK(status)) {
114 found = find_spn_in_spnlist(frame, spn, existing_spns, num_spns);
116 d_printf("Duplicate SPN found, aborting operation.\n");
120 d_printf("Registering SPN %s for object %s\n", spn, machine_name);
121 status = ads_add_service_principal_names(ads, machine_name, spns);
122 if (!ADS_ERR_OK(status)) {
126 d_printf("Updated object\n");
132 bool ads_setspn_delete(ADS_STRUCT *ads,
133 const char *machine_name,
137 TALLOC_CTX *frame = NULL;
138 char **spn_array = NULL;
139 const char **new_spn_array = NULL;
145 LDAPMessage *res = NULL;
147 frame = talloc_stackframe();
149 lc_spn = strlower_talloc(frame, spn);
150 if (lc_spn == NULL) {
151 DBG_ERR("Out of memory, lowercasing %s.\n", spn);
155 status = ads_find_machine_acct(ads,
158 if (!ADS_ERR_OK(status)) {
162 status = ads_get_service_principal_names(frame,
167 if (!ADS_ERR_OK(status)) {
171 new_spn_array = talloc_zero_array(frame, const char*, num_spns + 1);
172 if (!new_spn_array) {
173 DBG_ERR("Out of memory, failed to allocate array.\n");
178 * create new spn list to write to object (excluding the spn to
181 for (i = 0, j = 0; i < num_spns; i++) {
183 * windows setspn.exe deletes matching spn in a case
186 char *lc_spn_attr = strlower_talloc(frame, spn_array[i]);
187 if (lc_spn_attr == NULL) {
188 DBG_ERR("Out of memory, lowercasing %s.\n",
193 if (!strequal(lc_spn, lc_spn_attr)) {
194 new_spn_array[j++] = spn_array[i];
198 /* found and removed spn */
201 mods = ads_init_mods(frame);
205 d_printf("Unregistering SPN %s for %s\n", spn, machine_name);
206 status = ads_mod_strlist(frame, &mods, "servicePrincipalName", new_spn_array);
207 if (!ADS_ERR_OK(status)) {
211 dn = ads_get_dn(ads, frame, res);
216 status = ads_gen_mod(ads, dn, mods);
217 if (!ADS_ERR_OK(status)) {
221 d_printf("Updated object\n");
229 #endif /* HAVE_ADS */