浏览代码

[CIFS] distinguish between Kerberos and MSKerberos in upcall

Properly handle MSKRB5 by passing sec=mskrb5 to the upcall so that the
spengo blob can be generated appropriately. Also, make
decode_negTokenInit prefer whichever mechanism is first in the list.

Needed for some NetApp servers, and possibly some older
versions of Windows which treat the two KRB5 mechanisms differently.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Steve French 16 年之前
父节点
当前提交
c16fefa563
共有 4 个文件被更改,包括 14 次插入6 次删除
  1. 8 3
      fs/cifs/asn1.c
  2. 3 1
      fs/cifs/cifs_spnego.c
  3. 2 1
      fs/cifs/cifsglob.h
  4. 1 1
      fs/cifs/sess.c

+ 8 - 3
fs/cifs/asn1.c

@@ -476,6 +476,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
 	unsigned int cls, con, tag, oidlen, rc;
 	unsigned int cls, con, tag, oidlen, rc;
 	bool use_ntlmssp = false;
 	bool use_ntlmssp = false;
 	bool use_kerberos = false;
 	bool use_kerberos = false;
+	bool use_mskerberos = false;
 
 
 	*secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/
 	*secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/
 
 
@@ -574,10 +575,12 @@ decode_negTokenInit(unsigned char *security_blob, int length,
 					 *(oid + 1), *(oid + 2), *(oid + 3)));
 					 *(oid + 1), *(oid + 2), *(oid + 3)));
 
 
 				if (compare_oid(oid, oidlen, MSKRB5_OID,
 				if (compare_oid(oid, oidlen, MSKRB5_OID,
-						MSKRB5_OID_LEN))
-					use_kerberos = true;
+						MSKRB5_OID_LEN) &&
+						!use_kerberos)
+					use_mskerberos = true;
 				else if (compare_oid(oid, oidlen, KRB5_OID,
 				else if (compare_oid(oid, oidlen, KRB5_OID,
-						     KRB5_OID_LEN))
+						     KRB5_OID_LEN) &&
+						     !use_mskerberos)
 					use_kerberos = true;
 					use_kerberos = true;
 				else if (compare_oid(oid, oidlen, NTLMSSP_OID,
 				else if (compare_oid(oid, oidlen, NTLMSSP_OID,
 						     NTLMSSP_OID_LEN))
 						     NTLMSSP_OID_LEN))
@@ -630,6 +633,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
 
 
 	if (use_kerberos)
 	if (use_kerberos)
 		*secType = Kerberos;
 		*secType = Kerberos;
+	else if (use_mskerberos)
+		*secType = MSKerberos;
 	else if (use_ntlmssp)
 	else if (use_ntlmssp)
 		*secType = NTLMSSP;
 		*secType = NTLMSSP;
 
 

+ 3 - 1
fs/cifs/cifs_spnego.c

@@ -114,9 +114,11 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
 
 
 	dp = description + strlen(description);
 	dp = description + strlen(description);
 
 
-	/* for now, only sec=krb5 is valid */
+	/* for now, only sec=krb5 and sec=mskrb5 are valid */
 	if (server->secType == Kerberos)
 	if (server->secType == Kerberos)
 		sprintf(dp, ";sec=krb5");
 		sprintf(dp, ";sec=krb5");
+	else if (server->secType == MSKerberos)
+		sprintf(dp, ";sec=mskrb5");
 	else
 	else
 		goto out;
 		goto out;
 
 

+ 2 - 1
fs/cifs/cifsglob.h

@@ -80,7 +80,8 @@ enum securityEnum {
 	NTLMv2,			/* Legacy NTLM auth with NTLMv2 hash */
 	NTLMv2,			/* Legacy NTLM auth with NTLMv2 hash */
 	RawNTLMSSP,		/* NTLMSSP without SPNEGO */
 	RawNTLMSSP,		/* NTLMSSP without SPNEGO */
 	NTLMSSP,		/* NTLMSSP via SPNEGO */
 	NTLMSSP,		/* NTLMSSP via SPNEGO */
-	Kerberos		/* Kerberos via SPNEGO */
+	Kerberos,		/* Kerberos via SPNEGO */
+	MSKerberos,		/* MS Kerberos via SPNEGO */
 };
 };
 
 
 enum protocolEnum {
 enum protocolEnum {

+ 1 - 1
fs/cifs/sess.c

@@ -505,7 +505,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
 			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
 			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
 		} else
 		} else
 			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
 			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
-	} else if (type == Kerberos) {
+	} else if (type == Kerberos || type == MSKerberos) {
 #ifdef CONFIG_CIFS_UPCALL
 #ifdef CONFIG_CIFS_UPCALL
 		struct cifs_spnego_msg *msg;
 		struct cifs_spnego_msg *msg;
 		spnego_key = cifs_get_spnego_key(ses);
 		spnego_key = cifs_get_spnego_key(ses);