1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-26 21:57:41 +03:00

s3:libads: Allow 'net ads keytab add' handle Windows SPN(s) part 1

This patch addresses how the windows SPN is converted into a kerberos
priniciple to be written to the keytab file. A followup patch will
deal with writing Window SPN(s) to the AD.

Before this change 'net ads keytab add' handled three scenarios

a) 'net ads keytab add param' is passed a fully qualified kerberos principal
   (identified by the presence of '@' in param) In this scenario the keytab
   file alone is updated with the principal contained in 'param'.
b) 'net ads keytab add param'; is passed a machine name (identified by
   the paramater ending with '$'). In this case the machine name
   is converted to a kerberos principal with according to the recipe
   'param@realm' where realm is determined by lp_realm().
c) 'net ads keytab add param' is passed a service (e.g. nfs, http etc.)
   In this scenario the param containing the service is first converted to
   into 2 kerberos principals (long and short forms) according to the
   following recipe
      i) long form:  'param/fully_qualified_dns@realm'
     ii) short form: 'param/netbios_name@realm'
     where 'fully_qualified_dns is retrieved from 'dNSHostName' attribute of
     'this' machines computer account on the AD.
     The principals are written to the keytab file
   Secondly 2 windows SPNs are generated from 'param' as follows
      i) long form 'param/full_qualified_dns'
     ii) short form 'param/netbios_name'
   These SPNs are written to the AD computer account object

After this change a) & b) & c) will retain legacy behaviour except
in the case of c) where if the 'param' passed to c) is a Windows SPN
(e.g. conforming to format 'serviceclass/host:port'
  i) 'param' will get converted to a kerberos principal (just a single one)
     with the following recipe: 'serviceclass/host@realm' which will
     be written to the keytab file. The SPN written to the AD is created
     as before and the legacy behaviour is preserved.

Signed-off-by: Noel Power <noel.power@suse.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
Noel Power 2018-01-29 18:30:33 +00:00 committed by Andreas Schneider
parent 21889ca21c
commit efabfb1c17

View File

@ -159,6 +159,59 @@ static bool ads_set_machine_account_spns(TALLOC_CTX *ctx,
return true;
}
/*
* Create kerberos principal(s) from SPN or service name.
*/
static bool service_or_spn_to_kerberos_princ(TALLOC_CTX *ctx,
const char *service_or_spn,
const char *my_fqdn,
char **p_princ_s,
char **p_short_princ_s)
{
char *princ_s = NULL;
char *short_princ_s = NULL;
const char *service = service_or_spn;
const char *host = my_fqdn;
struct spn_struct* spn_struct = NULL;
char *tmp = NULL;
bool ok = true;
/* SPN should have '/' */
tmp = strchr_m(service_or_spn, '/');
if (tmp != NULL) {
spn_struct = parse_spn(ctx, service_or_spn);
if (spn_struct == NULL) {
ok = false;
goto out;
}
}
if (spn_struct != NULL) {
service = spn_struct->serviceclass;
host = spn_struct->host;
}
princ_s = talloc_asprintf(ctx, "%s/%s@%s",
service,
host, lp_realm());
if (princ_s == NULL) {
ok = false;
goto out;
}
if (spn_struct == NULL) {
short_princ_s = talloc_asprintf(ctx, "%s/%s@%s",
service, lp_netbios_name(),
lp_realm());
if (short_princ_s == NULL) {
ok = false;
goto out;
}
}
*p_princ_s = princ_s;
*p_short_princ_s = short_princ_s;
out:
return ok;
}
/**********************************************************************
Adds a single service principal, i.e. 'host' to the system keytab
***********************************************************************/
@ -264,16 +317,11 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc)
* can obtain credentials for it and double-check the salt value
* used to generate the service's keys. */
princ_s = talloc_asprintf(tmpctx, "%s/%s@%s",
srvPrinc, my_fqdn, lp_realm());
if (!princ_s) {
ret = -1;
goto out;
}
short_princ_s = talloc_asprintf(tmpctx, "%s/%s@%s",
srvPrinc, lp_netbios_name(),
lp_realm());
if (short_princ_s == NULL) {
if (!service_or_spn_to_kerberos_princ(tmpctx,
srvPrinc,
my_fqdn,
&princ_s,
&short_princ_s)) {
ret = -1;
goto out;
}