Skip to content

Commit

Permalink
Add krb5_keytab for specifying a Kerberos client keytab
Browse files Browse the repository at this point in the history
Current MIT Kerberos versions support automatically obtaining client
tickets from a keytab without the need for external kinit/k5start.
  • Loading branch information
grawity committed Dec 26, 2024
1 parent 09ed954 commit 31c1464
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
10 changes: 10 additions & 0 deletions man/nslcd.conf.5.xml
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,16 @@
</listitem>
</varlistentry>

<varlistentry id="krb5_keytab"> <!-- since 0.10 -->
<term><option>krb5_keytab</option> <replaceable>NAME</replaceable></term>
<listitem>
<para>
Set the name for the GSS-API Kerberos client keytab, if supported by
the system Kerberos library.
</para>
</listitem>
</varlistentry>

</variablelist>
</refsect2>

Expand Down
33 changes: 33 additions & 0 deletions nslcd/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,35 @@ static void handle_krb5_ccname(const char *filename, int lnr,
#endif /* HAVE_GSS_KRB5_CCACHE_NAME */
}

static void handle_krb5_keytab(const char *filename, int lnr,
const char *keyword, char *line)
{
char token[80];
/* get token */
check_argumentcount(filename, lnr, keyword,
(get_token(&line, token, sizeof(token)) != NULL));
get_eol(filename, lnr, keyword, &line);
/* set default Kerberos client keytab for SASL-GSSAPI */
ktname = token;
/* check that cache exists and is readable if it is a file */
if (strncasecmp(ktname, "FILE:", sizeof("FILE:") - 1) == 0)
{
ktfile = strchr(ktname, ':') + 1;
check_readable(filename, lnr, keyword, ktfile);
}
/* set the environment variable (we have a memory leak if this option
is set multiple times) */
ktenvlen = strlen(ktname) + sizeof("KRB5_CLIENT_KEYTAB=");
ktenv = (char *)malloc(ktenvlen);
if (ktenv == NULL)
{
log_log(LOG_CRIT, "malloc() failed to allocate memory");
exit(EXIT_FAILURE);
}
mysnprintf(ktenv, ktenvlen, "KRB5_CLIENT_KEYTAB=%s", ktname);
putenv(ktenv);
}

static enum ldap_map_selector parse_map(const char *value)
{
if ((strcasecmp(value, "alias") == 0) || (strcasecmp(value, "aliases") == 0))
Expand Down Expand Up @@ -1504,6 +1533,10 @@ static void cfg_read(const char *filename, struct ldap_config *cfg)
{
handle_krb5_ccname(filename, lnr, keyword, line);
}
else if (strcasecmp(keyword, "krb5_keytab") == 0)
{
handle_krb5_keytab(filename, lnr, keyword, line);
}
/* search/mapping options */
else if (strcasecmp(keyword, "base") == 0)
{
Expand Down
9 changes: 6 additions & 3 deletions pynslcd/cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
sasl_authzid = None # FIXME: add support
sasl_secprops = None # FIXME: add support
sasl_canonicalize = None # FIXME: add support
krb5_ccname = None # FIXME: add support
krb5_keytab = None # FIXME: add support

# LDAP bases to search
bases = []
Expand Down Expand Up @@ -201,9 +203,10 @@ def read(filename): # noqa: C901 (many simple branches)
# parse options with a single value that can contain spaces
m = re.match(
r'(?P<keyword>binddn|rootpwmoddn|sasl_realm|sasl_authcid|'
r'sasl_authzid|sasl_secprops|krb5_ccname|tls_cacertdir|'
r'tls_cacertfile|tls_randfile|tls_ciphers|tls_cert|tls_key|'
r'pam_password_prohibit_message)\s+(?P<value>\S.*)',
r'sasl_authzid|sasl_secprops|krb5_ccname|krb5_keytab|'
r'tls_cacertdir|tls_cacertfile|tls_randfile|tls_ciphers|'
r'tls_cert|tls_key|pam_password_prohibit_message)'
r'\s+(?P<value>\S.*)',
line, re.IGNORECASE)
if m:
globals()[m.group('keyword').lower()] = m.group('value')
Expand Down

0 comments on commit 31c1464

Please sign in to comment.