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 */