Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 248401 Details for
Bug 315311
Add Kerberos support to CIFS mounts
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
patch -- get SPNEGO blob for session setup via downcall
cifs-spnego-upcall.patch (text/plain), 19.59 KB, created by
Jeff Layton
on 2007-11-05 16:18:15 UTC
(
hide
)
Description:
patch -- get SPNEGO blob for session setup via downcall
Filename:
MIME Type:
Creator:
Jeff Layton
Created:
2007-11-05 16:18:15 UTC
Size:
19.59 KB
patch
obsolete
>diff --git a/fs/Kconfig b/fs/Kconfig >index cc28a69..e431c38 100644 >--- a/fs/Kconfig >+++ b/fs/Kconfig >@@ -2007,7 +2007,7 @@ config CIFS_EXPERIMENTAL > config CIFS_UPCALL > bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)" > depends on CIFS_EXPERIMENTAL >- depends on CONNECTOR >+ depends on KEYS > help > Enables an upcall mechanism for CIFS which will be used to contact > userspace helper utilities to provide SPNEGO packaged Kerberos >diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile >index ff6ba8d..45e42fb 100644 >--- a/fs/cifs/Makefile >+++ b/fs/cifs/Makefile >@@ -3,4 +3,9 @@ > # > obj-$(CONFIG_CIFS) += cifs.o > >-cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o cifsacl.o >+cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ >+ link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ >+ md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o \ >+ readdir.o ioctl.o sess.o export.o cifsacl.o >+ >+cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o >diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c >index 2a01f3e..bcda2c6 100644 >--- a/fs/cifs/asn1.c >+++ b/fs/cifs/asn1.c >@@ -77,8 +77,12 @@ > > #define SPNEGO_OID_LEN 7 > #define NTLMSSP_OID_LEN 10 >+#define KRB5_OID_LEN 7 >+#define MSKRB5_OID_LEN 7 > static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; > static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; >+static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 }; >+static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 }; > > /* > * ASN.1 context. >@@ -457,6 +461,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, > unsigned long *oid = NULL; > unsigned int cls, con, tag, oidlen, rc; > int use_ntlmssp = FALSE; >+ int use_kerberos = FALSE; > > *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/ > >@@ -545,18 +550,28 @@ decode_negTokenInit(unsigned char *security_blob, int length, > return 0; > } > if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { >- rc = asn1_oid_decode(&ctx, end, &oid, &oidlen); >- if (rc) { >+ if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) { >+ > cFYI(1, > ("OID len = %d oid = 0x%lx 0x%lx " > "0x%lx 0x%lx", > oidlen, *oid, *(oid + 1), > *(oid + 2), *(oid + 3))); >- rc = compare_oid(oid, oidlen, >- NTLMSSP_OID, NTLMSSP_OID_LEN); >- kfree(oid); >- if (rc) >+ >+ if (compare_oid(oid, oidlen, >+ MSKRB5_OID, >+ MSKRB5_OID_LEN)) >+ use_kerberos = TRUE; >+ else if (compare_oid(oid, oidlen, >+ KRB5_OID, >+ KRB5_OID_LEN)) >+ use_kerberos = TRUE; >+ else if (compare_oid(oid, oidlen, >+ NTLMSSP_OID, >+ NTLMSSP_OID_LEN)) > use_ntlmssp = TRUE; >+ >+ kfree(oid); > } > } else { > cFYI(1, ("Should be an oid what is going on?")); >@@ -609,12 +624,10 @@ decode_negTokenInit(unsigned char *security_blob, int length, > ctx.pointer)); /* is this UTF-8 or ASCII? */ > } > >- /* if (use_kerberos) >- *secType = Kerberos >- else */ >- if (use_ntlmssp) { >+ if (use_kerberos) >+ *secType = Kerberos; >+ else if (use_ntlmssp) > *secType = NTLMSSP; >- } > > return 1; > } >diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c >new file mode 100644 >index 0000000..e142faf >--- /dev/null >+++ b/fs/cifs/cifs_spnego.c >@@ -0,0 +1,124 @@ >+/* >+ * fs/cifs/cifs_spnego.c -- SPNEGO upcall management for CIFS >+ * >+ * Copyright (c) 2007 Red Hat, Inc. >+ * Author(s): Jeff Layton (jlayton@redhat.com) >+ * >+ * This library is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU Lesser General Public License as published >+ * by the Free Software Foundation; either version 2.1 of the License, or >+ * (at your option) any later version. >+ * >+ * This library is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See >+ * the GNU Lesser General Public License for more details. >+ * >+ * You should have received a copy of the GNU Lesser General Public License >+ * along with this library; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+ */ >+ >+#include <linux/list.h> >+#include <linux/string.h> >+#include <keys/user-type.h> >+#include <linux/key-type.h> >+#include "cifsglob.h" >+#include "cifs_spnego.h" >+#include "cifs_debug.h" >+ >+/* create a new cifs key */ >+static int >+cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen) >+{ >+ char *payload; >+ int ret; >+ >+ ret = -ENOMEM; >+ payload = kmalloc(datalen, GFP_KERNEL); >+ if (!payload) >+ goto error; >+ >+ /* attach the data */ >+ memcpy(payload, data, datalen); >+ rcu_assign_pointer(key->payload.data, payload); >+ ret = 0; >+ >+error: >+ return ret; >+} >+ >+static void >+cifs_spnego_key_destroy(struct key *key) >+{ >+ kfree(key->payload.data); >+} >+ >+ >+/* >+ * keytype for CIFS spnego keys >+ */ >+struct key_type cifs_spnego_key_type = { >+ .name = "cifs.spnego", >+ .instantiate = cifs_spnego_key_instantiate, >+ .match = user_match, >+ .destroy = cifs_spnego_key_destroy, >+ .describe = user_describe, >+}; >+ >+/* get a key struct with a SPNEGO security blob, suitable for session setup */ >+struct key * >+cifs_get_spnego_key(struct cifsSesInfo *sesInfo, const char *hostname) >+{ >+ struct TCP_Server_Info *server = sesInfo->server; >+ char *description, *dp; >+ size_t desc_len; >+ struct key *spnego_key; >+ >+ >+ /* version + ;ip{4|6}= + address + ;host=hostname + ;sec= + NULL */ >+ desc_len = 2 + 5 + 32 + 1 + 5 + strlen(hostname) + >+ strlen(";sec=krb5") + 1; >+ spnego_key = ERR_PTR(-ENOMEM); >+ description = kzalloc(desc_len, GFP_KERNEL); >+ if (description == NULL) >+ goto out; >+ >+ dp = description; >+ /* start with version and hostname portion of UNC string */ >+ spnego_key = ERR_PTR(-EINVAL); >+ sprintf(dp, "%2.2x;host=%s;", CIFS_SPNEGO_UPCALL_VERSION, >+ hostname); >+ dp = description + strlen(description); >+ >+ /* add the server address */ >+ if (server->addr.sockAddr.sin_family == AF_INET) >+ sprintf(dp, "ip4=" NIPQUAD_FMT, >+ NIPQUAD(server->addr.sockAddr.sin_addr)); >+ else if (server->addr.sockAddr.sin_family == AF_INET6) >+ sprintf(dp, "ip6=" NIP6_SEQFMT, >+ NIP6(server->addr.sockAddr6.sin6_addr)); >+ else >+ goto out; >+ >+ dp = description + strlen(description); >+ >+ /* for now, only sec=krb5 is valid */ >+ if (server->secType == Kerberos) >+ sprintf(dp, ";sec=krb5"); >+ else >+ goto out; >+ >+ cFYI(1, ("key description = %s", description)); >+ spnego_key = request_key(&cifs_spnego_key_type, description, ""); >+ >+ if (cifsFYI && !IS_ERR(spnego_key)) { >+ struct cifs_spnego_msg *msg = spnego_key->payload.data; >+ cifs_dump_mem("SPNEGO reply blob:", msg->data, >+ msg->secblob_len + msg->sesskey_len); >+ } >+ >+out: >+ kfree(description); >+ return spnego_key; >+} >diff --git a/fs/cifs/cifs_spnego.h b/fs/cifs/cifs_spnego.h >new file mode 100644 >index 0000000..f443f3b >--- /dev/null >+++ b/fs/cifs/cifs_spnego.h >@@ -0,0 +1,46 @@ >+/* >+ * fs/cifs/cifs_spnego.h -- SPNEGO upcall management for CIFS >+ * >+ * Copyright (c) 2007 Red Hat, Inc. >+ * Author(s): Jeff Layton (jlayton@redhat.com) >+ * Steve French (sfrench@us.ibm.com) >+ * >+ * This library is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU Lesser General Public License as published >+ * by the Free Software Foundation; either version 2.1 of the License, or >+ * (at your option) any later version. >+ * >+ * This library is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See >+ * the GNU Lesser General Public License for more details. >+ * >+ * You should have received a copy of the GNU Lesser General Public License >+ * along with this library; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >+ */ >+ >+#ifndef _CIFS_SPNEGO_H >+#define _CIFS_SPNEGO_H >+ >+#define CIFS_SPNEGO_UPCALL_VERSION 1 >+ >+/* >+ * The version field should always be set to CIFS_SPNEGO_UPCALL_VERSION. >+ * The flags field is for future use. The request-key callout should set >+ * sesskey_len and secblob_len, and then concatenate the SessKey+SecBlob >+ * and stuff it in the data field. >+ */ >+struct cifs_spnego_msg { >+ uint32_t version; >+ uint32_t flags; >+ uint32_t sesskey_len; >+ uint32_t secblob_len; >+ uint8_t data[1]; >+}; >+ >+#ifdef __KERNEL__ >+extern struct key_type cifs_spnego_key_type; >+#endif /* KERNEL */ >+ >+#endif /* _CIFS_SPNEGO_H */ >diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c >index 632070b..788f0ad 100644 >--- a/fs/cifs/cifsencrypt.c >+++ b/fs/cifs/cifsencrypt.c >@@ -99,11 +99,12 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec, > MD5Init(&context); > MD5Update(&context, (char *)&key->data, key->len); > for (i = 0; i < n_vec; i++) { >+ if (iov[i].iov_len == 0) >+ continue; > if (iov[i].iov_base == NULL) { > cERROR(1, ("null iovec entry")); > return -EIO; >- } else if (iov[i].iov_len == 0) >- break; /* bail out if we are sent nothing to sign */ >+ } > /* The first entry includes a length field (which does not get > signed that occupies the first 4 bytes before the header */ > if (i == 0) { >diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c >index a6fbea5..416dc9f 100644 >--- a/fs/cifs/cifsfs.c >+++ b/fs/cifs/cifsfs.c >@@ -43,6 +43,8 @@ > #include "cifs_debug.h" > #include "cifs_fs_sb.h" > #include <linux/mm.h> >+#include <linux/key-type.h> >+#include "cifs_spnego.h" > #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ > > #ifdef CONFIG_CIFS_QUOTA >@@ -1005,12 +1007,16 @@ init_cifs(void) > rc = register_filesystem(&cifs_fs_type); > if (rc) > goto out_destroy_request_bufs; >- >+#ifdef CONFIG_CIFS_UPCALL >+ rc = register_key_type(&cifs_spnego_key_type); >+ if (rc) >+ goto out_unregister_filesystem; >+#endif > oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd"); > if (IS_ERR(oplockThread)) { > rc = PTR_ERR(oplockThread); > cERROR(1, ("error %d create oplock thread", rc)); >- goto out_unregister_filesystem; >+ goto out_unregister_key_type; > } > > dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd"); >@@ -1024,7 +1030,11 @@ init_cifs(void) > > out_stop_oplock_thread: > kthread_stop(oplockThread); >+ out_unregister_key_type: >+#ifdef CONFIG_CIFS_UPCALL >+ unregister_key_type(&cifs_spnego_key_type); > out_unregister_filesystem: >+#endif > unregister_filesystem(&cifs_fs_type); > out_destroy_request_bufs: > cifs_destroy_request_bufs(); >@@ -1046,6 +1056,9 @@ exit_cifs(void) > #ifdef CONFIG_PROC_FS > cifs_proc_clean(); > #endif >+#ifdef CONFIG_CIFS_UPCALL >+ unregister_key_type(&cifs_spnego_key_type); >+#endif > unregister_filesystem(&cifs_fs_type); > cifs_destroy_inodecache(); > cifs_destroy_mids(); >diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h >index 87f51f2..a628446 100644 >--- a/fs/cifs/cifsglob.h >+++ b/fs/cifs/cifsglob.h >@@ -110,6 +110,7 @@ struct mac_key { > unsigned int len; > union { > char ntlm[CIFS_SESS_KEY_SIZE + 16]; >+ char krb5[CIFS_SESS_KEY_SIZE + 16]; /* BB: length correct? */ > struct { > char key[16]; > struct ntlmv2_resp resp; >diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h >index 1ffe255..65dce89 100644 >--- a/fs/cifs/cifsproto.h >+++ b/fs/cifs/cifsproto.h >@@ -76,9 +76,11 @@ extern void header_assemble(struct smb_hdr *, char /* command */ , > extern int small_smb_init_no_tc(const int smb_cmd, const int wct, > struct cifsSesInfo *ses, > void **request_buf); >+extern struct key *cifs_get_spnego_key(struct cifsSesInfo *sesInfo, >+ const char *hostname); > extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, >- const int stage, >- const struct nls_table *nls_cp); >+ const int stage, const struct nls_table *nls_cp, >+ const char *hostname); > extern __u16 GetNextMid(struct TCP_Server_Info *server); > extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, > struct cifsTconInfo *); >@@ -105,7 +107,7 @@ void cifs_proc_init(void); > void cifs_proc_clean(void); > > extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, >- struct nls_table *nls_info); >+ struct nls_table *nls_info, const char *unc); > extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses); > > extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, >diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c >index 0bb3e43..d7d3433 100644 >--- a/fs/cifs/cifssmb.c >+++ b/fs/cifs/cifssmb.c >@@ -157,7 +157,8 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, > down(&tcon->ses->sesSem); > if (tcon->ses->status == CifsNeedReconnect) > rc = cifs_setup_session(0, tcon->ses, >- nls_codepage); >+ nls_codepage, >+ tcon->treeName); > if (!rc && (tcon->tidStatus == CifsNeedReconnect)) { > mark_open_files_invalid(tcon); > rc = CIFSTCon(0, tcon->ses, tcon->treeName, >@@ -302,7 +303,8 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, > down(&tcon->ses->sesSem); > if (tcon->ses->status == CifsNeedReconnect) > rc = cifs_setup_session(0, tcon->ses, >- nls_codepage); >+ nls_codepage, >+ tcon->treeName); > if (!rc && (tcon->tidStatus == CifsNeedReconnect)) { > mark_open_files_invalid(tcon); > rc = CIFSTCon(0, tcon->ses, tcon->treeName, >@@ -647,8 +649,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) > count - 16, > &server->secType); > if (rc == 1) { >- /* BB Need to fill struct for sessetup here */ >- rc = -EOPNOTSUPP; >+ rc = 0; > } else { > rc = -EINVAL; > } >diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c >index 380ee99..75d7f8f 100644 >--- a/fs/cifs/connect.c >+++ b/fs/cifs/connect.c >@@ -1996,7 +1996,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, > down(&pSesInfo->sesSem); > /* BB FIXME need to pass vol->secFlgs BB */ > rc = cifs_setup_session(xid, pSesInfo, >- cifs_sb->local_nls); >+ cifs_sb->local_nls, >+ volume_info.UNC); > up(&pSesInfo->sesSem); > if (!rc) > atomic_inc(&srvTcp->socketUseCount); >@@ -3508,13 +3509,49 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) > return rc; /* BB check if we should always return zero here */ > } > >+/* extract the host portion of the UNC string */ >+static char * >+extract_hostname_from_unc(const char *unc) >+{ >+ const char *src; >+ char *dst, *delim; >+ unsigned int len; >+ >+ /* skip double chars at beginning of string */ >+ /* BB: check validity of these bytes? */ >+ src = unc + 2; >+ >+ /* delimiter between hostname and sharename is always '\\' now */ >+ delim = strchr(src, '\\'); >+ if (!delim) >+ return ERR_PTR(-EINVAL); >+ >+ len = delim - src; >+ dst = kmalloc((len + 1), GFP_KERNEL); >+ if (dst == NULL) >+ return ERR_PTR(-ENOMEM); >+ >+ memcpy(dst, src, len); >+ dst[len] = '\0'; >+ >+ return dst; >+} >+ > int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, >- struct nls_table *nls_info) >+ struct nls_table *nls_info, const char *unc) > { > int rc = 0; > char ntlm_session_key[CIFS_SESS_KEY_SIZE]; > int ntlmv2_flag = FALSE; > int first_time = 0; >+ char *hostname; >+ >+ hostname = extract_hostname_from_unc(unc); >+ if (IS_ERR(hostname)) { >+ rc = PTR_ERR(hostname); >+ hostname = NULL; >+ goto ss_err_exit; >+ } > > /* what if server changes its buffer size after dropping the session? */ > if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ { >@@ -3547,8 +3584,8 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, > pSesInfo->server->capabilities, > pSesInfo->server->timeAdj)); > if (experimEnabled < 2) >- rc = CIFS_SessSetup(xid, pSesInfo, >- first_time, nls_info); >+ rc = CIFS_SessSetup(xid, pSesInfo, first_time, >+ nls_info, hostname); > else if (extended_security > && (pSesInfo->capabilities > & CAP_EXTENDED_SECURITY) >@@ -3627,6 +3664,8 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, > } > } > ss_err_exit: >+ kfree(hostname); >+ > return rc; > } > >diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c >index 899dc60..7cb64bb 100644 >--- a/fs/cifs/sess.c >+++ b/fs/cifs/sess.c >@@ -29,6 +29,7 @@ > #include "ntlmssp.h" > #include "nterr.h" > #include <linux/utsname.h> >+#include "cifs_spnego.h" > > extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, > unsigned char *p24); >@@ -330,7 +331,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft, > > int > CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, >- const struct nls_table *nls_cp) >+ const struct nls_table *nls_cp, const char *hostname) > { > int rc = 0; > int wct; >@@ -341,10 +342,11 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, > __u32 capabilities; > int count; > int resp_buf_type = 0; >- struct kvec iov[2]; >+ struct kvec iov[3]; > enum securityEnum type; > __u16 action; > int bytes_remaining; >+ struct key *spnego_key = NULL; > > if (ses == NULL) > return -EINVAL; >@@ -395,6 +397,9 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, > > ses->flags &= ~CIFS_SES_LANMAN; > >+ iov[1].iov_base = NULL; >+ iov[1].iov_len = 0; >+ > if (type == LANMAN) { > #ifdef CONFIG_CIFS_WEAK_PW_HASH > char lnm_session_key[CIFS_SESS_KEY_SIZE]; >@@ -499,21 +504,58 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, > unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); > } else > ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); >- } else /* NTLMSSP or SPNEGO */ { >+ } else if (type == Kerberos) { >+#ifdef CONFIG_CIFS_UPCALL >+ struct cifs_spnego_msg *msg; >+ spnego_key = cifs_get_spnego_key(ses, hostname); >+ if (IS_ERR(spnego_key)) { >+ rc = PTR_ERR(spnego_key); >+ spnego_key = NULL; >+ goto ssetup_exit; >+ } >+ msg = spnego_key->payload.data; >+ ses->server->mac_signing_key.len = msg->sesskey_len; >+ memcpy(ses->server->mac_signing_key.data.krb5, msg->data, >+ msg->sesskey_len); > pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; > capabilities |= CAP_EXTENDED_SECURITY; > pSMB->req.Capabilities = cpu_to_le32(capabilities); >- /* BB set password lengths */ >+ iov[1].iov_base = msg->data + msg->sesskey_len; >+ iov[1].iov_len = msg->secblob_len; >+ pSMB->req.SecurityBlobLength = cpu_to_le16(iov[1].iov_len); >+ >+ if (ses->capabilities & CAP_UNICODE) { >+ /* unicode strings must be word aligned */ >+ if (iov[0].iov_len % 2) { >+ *bcc_ptr = 0; >+ bcc_ptr++; >+ } >+ unicode_oslm_strings(&bcc_ptr, nls_cp); >+ unicode_domain_string(&bcc_ptr, ses, nls_cp); >+ } else >+ /* BB: is this right? */ >+ ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); >+#else /* ! CONFIG_CIFS_UPCALL */ >+ cERROR(1, ("Kerberos negotiated, but kernel not configured " >+ "for upcall support")); >+ rc = -ENOSYS; >+ goto ssetup_exit; >+#endif /* CONFIG_CIFS_UPCALL */ >+ } else { >+ cERROR(1, ("secType %d not supported!", type)); >+ rc = -ENOSYS; >+ goto ssetup_exit; > } > >- count = (long) bcc_ptr - (long) str_area; >+ iov[2].iov_base = str_area; >+ iov[2].iov_len = (long) bcc_ptr - (long) str_area; >+ >+ count = iov[1].iov_len + iov[2].iov_len; > smb_buf->smb_buf_length += count; > > BCC_LE(smb_buf) = cpu_to_le16(count); > >- iov[1].iov_base = str_area; >- iov[1].iov_len = count; >- rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, >+ rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type, > 0 /* not long op */, 1 /* log NT STATUS if any */ ); > /* SMB request buf freed in SendReceive2 */ > >@@ -560,6 +602,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, > ses, nls_cp); > > ssetup_exit: >+ if (spnego_key) >+ key_put(spnego_key); > kfree(str_area); > if (resp_buf_type == CIFS_SMALL_BUFFER) { > cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 315311
:
215841
|
217871
|
218261
|
218271
|
228611
|
232741
|
236521
|
237721
| 248401