From 992fed22dcbc3a21662e735fd299acb8e50556e9 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 18 Aug 2008 17:58:34 +0400 Subject: [PATCH] Adds support to cifs.upcall for spnego MS_KRB5 wrapping Signed-off-by: Igor Mammedov --- source/client/cifs.upcall.c | 48 ++++++++++++++++++++++++++++++++++-------- 1 files changed, 39 insertions(+), 9 deletions(-) diff --git a/source/client/cifs.upcall.c b/source/client/cifs.upcall.c index aa5eb57..6cf8bc3 100644 --- a/source/client/cifs.upcall.c +++ b/source/client/cifs.upcall.c @@ -29,7 +29,7 @@ create dns_resolver * * /usr/local/sbin/cifs.upcall %k #include "cifs_spnego.h" -const char *CIFSSPNEGO_VERSION = "1.1"; +const char *CIFSSPNEGO_VERSION = "1.2"; static const char *prog = "cifs.upcall"; typedef enum _secType { KRB5, @@ -73,7 +73,7 @@ int handle_krb5_mech(const char *oid, const char *principal, tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ - *secblob = gen_negTokenInit(OID_KERBEROS5, tkt_wrapped); + *secblob = gen_negTokenInit(oid, tkt_wrapped); data_blob_free(&tkt_wrapped); data_blob_free(&tkt); @@ -86,20 +86,20 @@ int handle_krb5_mech(const char *oid, const char *principal, #define DKD_HAVE_IPV4 8 #define DKD_HAVE_IPV6 16 #define DKD_HAVE_UID 32 -#define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC) +#define DKD_HAVE_MIC 64 +#define DKD_MUSTHAVE_SET (DKD_HAVE_VERSION|DKD_HAVE_SEC) int decode_key_description(const char *desc, int *ver, secType_t * sec, - char **hostname, uid_t * uid) + char **hostname, char **mic, uid_t * uid) { + const char *tkn = desc; int retval = 0; char *pos; - const char *tkn = desc; + int len; do { pos = index(tkn, ';'); if (strncmp(tkn, "host=", 5) == 0) { - int len; - if (pos == NULL) { len = strlen(tkn); } else { @@ -110,6 +110,17 @@ int decode_key_description(const char *desc, int *ver, secType_t * sec, *hostname = SMB_XMALLOC_ARRAY(char, len); strlcpy(*hostname, tkn + 5, len); retval |= DKD_HAVE_HOSTNAME; + } else if (strncmp(tkn, "mic=", 4) == 0) { + if (pos == NULL) { + len = strlen(tkn); + } else { + len = pos - tkn; + } + len -= 3; + SAFE_FREE(*mic); + *mic = SMB_XMALLOC_ARRAY(char, len); + strlcpy(*mic, tkn + 4, len); + retval |= DKD_HAVE_MIC; } else if (strncmp(tkn, "ipv4=", 5) == 0) { /* BB: do we need it if we have hostname already? */ } else if (strncmp(tkn, "ipv6=", 5) == 0) { @@ -118,6 +129,9 @@ int decode_key_description(const char *desc, int *ver, secType_t * sec, if (strncmp(tkn + 4, "krb5", 4) == 0) { retval |= DKD_HAVE_SEC; *sec = KRB5; + } else if (strncmp(tkn + 4, "mskrb5", 6) == 0) { + retval |= DKD_HAVE_SEC; + *sec = MS_KRB5; } } else if (strncmp(tkn, "uid=", 4) == 0) { errno = 0; @@ -219,7 +233,7 @@ int main(const int argc, char *const argv[]) uid_t uid; int kernel_upcall_version; int c, use_cifs_service_prefix = 0; - char *buf, *hostname = NULL; + char *buf, *hostname = NULL, *mic = NULL; openlog(prog, 0, LOG_DAEMON); @@ -270,7 +284,7 @@ int main(const int argc, char *const argv[]) } rc = decode_key_description(buf, &kernel_upcall_version, §ype, - &hostname, &uid); + &hostname, &mic, &uid); if ((rc & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) { syslog(LOG_WARNING, "unable to get from description necessary params"); @@ -280,6 +294,16 @@ int main(const int argc, char *const argv[]) } SAFE_FREE(buf); + if (sectype == MS_KRB5 && !(rc & DKD_HAVE_MIC)) { + syslog(LOG_ERR, "mskrb5 requires missing mic option"); + goto out; + } + + if (sectype == KRB5 && !(rc & DKD_HAVE_HOSTNAME)) { + syslog(LOG_ERR, "krb5 requires missing host option"); + goto out; + } + if (kernel_upcall_version != CIFS_SPNEGO_UPCALL_VERSION) { syslog(LOG_WARNING, "incompatible kernel upcall version: 0x%x", @@ -301,6 +325,11 @@ int main(const int argc, char *const argv[]) // do mech specific authorization switch (sectype) { + case MS_KRB5:{ + rc = handle_krb5_mech(OID_KERBEROS5_OLD, mic, + &secblob, &sess_key); + break; + } case KRB5:{ char *princ; size_t len; @@ -373,6 +402,7 @@ out: data_blob_free(&secblob); data_blob_free(&sess_key); SAFE_FREE(hostname); + SAFE_FREE(mic); SAFE_FREE(keydata); return rc; } -- 1.5.3.7