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 232741 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 -- update to use new keyctl binary blob patches
cifs-2.6-spnego.patch (text/plain), 12.90 KB, created by
Jeff Layton
on 2007-10-19 16:25:54 UTC
(
hide
)
Description:
patch -- update to use new keyctl binary blob patches
Filename:
MIME Type:
Creator:
Jeff Layton
Created:
2007-10-19 16:25:54 UTC
Size:
12.90 KB
patch
obsolete
>diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile >index ff6ba8d..0a6d9a5 100644 >--- a/fs/cifs/Makefile >+++ b/fs/cifs/Makefile >@@ -3,4 +3,4 @@ > # > 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-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 cifsauth.o >diff --git a/fs/cifs/cifsauth.c b/fs/cifs/cifsauth.c >new file mode 100644 >index 0000000..e29ebb9 >--- /dev/null >+++ b/fs/cifs/cifsauth.c >@@ -0,0 +1,118 @@ >+/* >+ * fs/cifs/cifsauth.c -- auth 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 "cifsauth.h" >+#include "cifs_debug.h" >+ >+/* >+ * create a new SPNEGO blob key >+ */ >+static int >+cifs_spnego_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_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_instantiate, >+ .match = user_match, >+ .destroy = cifs_spnego_destroy, >+ .describe = user_describe, >+}; >+ >+/* >+ * given a SPNEGO security blob and session info, get a key struct with a new >+ * SPNEGO security blob, suitable for session setup >+ */ >+int >+cifs_get_spnego_key(struct cifsSesInfo *sesInfo, const unsigned char *secblob, >+ size_t len, struct key **spnego_key) >+{ >+ struct TCP_Server_Info *server = sesInfo->server; >+ char *description = NULL; >+ int error; >+ >+ error = -ENOMEM; >+ /* 8 bytes for uid, 32 for addr, 1 for colon, 1 for NULL */ >+ description = kzalloc((8 + 32 + 1 + 1), GFP_KERNEL); >+ if (description == NULL) >+ goto out; >+ >+ error = -EINVAL; >+ if (server->addr.sockAddr.sin_family == AF_INET) >+ sprintf(description, "%8.8x:" NIPQUAD_FMT, sesInfo->linux_uid, >+ NIPQUAD(server->addr.sockAddr.sin_addr)); >+ else if (server->addr.sockAddr.sin_family == AF_INET6) >+ sprintf(description, "%8.8x:" NIP6_SEQFMT, sesInfo->linux_uid, >+ NIP6(server->addr.sockAddr6.sin6_addr)); >+ else >+ goto out; >+ >+ *spnego_key = request_key_with_auxdata(&cifs_spnego_key_type, description, >+ secblob, len, NULL); >+ if (IS_ERR(*spnego_key)) { >+ error = PTR_ERR(*spnego_key); >+ *spnego_key = NULL; >+ goto out; >+ } >+ >+ error = 0; >+ >+ if (cifsFYI) { >+ struct cifs_spnego_msg *msg = (*spnego_key)->payload.data; >+ cifs_dump_mem("SPNEGO reply blob:", msg->data, msg->len); >+ } >+ >+out: >+ if (description) >+ kfree(description); >+ return error; >+} >diff --git a/fs/cifs/cifsauth.h b/fs/cifs/cifsauth.h >new file mode 100644 >index 0000000..75d26c8 >--- /dev/null >+++ b/fs/cifs/cifsauth.h >@@ -0,0 +1,36 @@ >+/* >+ * fs/cifs/cifsauth.h -- auth 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 >+ */ >+ >+#ifndef _CIFSAUTH_H >+#define _CIFSAUTH_H >+ >+struct cifs_spnego_msg { >+ uint32_t len; >+ uint8_t data[1]; >+}; >+ >+extern struct key_type cifs_spnego_key_type; >+ >+extern int cifs_get_spnego_key(struct cifsSesInfo *sesInfo, >+ const unsigned char *secblob, >+ size_t len, struct key **key); >+ >+#endif /* _CIFSAUTH_H */ >diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c >index 91ba328..901f5db 100644 >--- a/fs/cifs/cifsfs.c >+++ b/fs/cifs/cifsfs.c >@@ -42,7 +42,9 @@ > #include "cifsproto.h" > #include "cifs_debug.h" > #include "cifs_fs_sb.h" >+#include "cifsauth.h" > #include <linux/mm.h> >+#include <linux/key-type.h> > #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ > > #ifdef CONFIG_CIFS_QUOTA >@@ -1006,11 +1008,15 @@ init_cifs(void) > if (rc) > goto out_destroy_request_bufs; > >+ rc = register_key_type(&cifs_spnego_key_type); >+ if (rc) >+ goto out_unregister_filesystem; >+ > 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,6 +1030,8 @@ init_cifs(void) > > out_stop_oplock_thread: > kthread_stop(oplockThread); >+ out_unregister_key_type: >+ unregister_key_type(&cifs_spnego_key_type); > out_unregister_filesystem: > unregister_filesystem(&cifs_fs_type); > out_destroy_request_bufs: >@@ -1046,6 +1054,7 @@ exit_cifs(void) > #ifdef CONFIG_PROC_FS > cifs_proc_clean(); > #endif >+ unregister_key_type(&cifs_spnego_key_type); > unregister_filesystem(&cifs_fs_type); > cifs_destroy_inodecache(); > cifs_destroy_mids(); >diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h >index 1a88366..6ff6d43 100644 >--- a/fs/cifs/cifsproto.h >+++ b/fs/cifs/cifsproto.h >@@ -75,7 +75,8 @@ extern int small_smb_init_no_tc(const int smb_cmd, const int wct, > void **request_buf); > extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, > const int stage, >- const struct nls_table *nls_cp); >+ const struct nls_table *nls_cp, >+ struct key *spnego_key); > extern __u16 GetNextMid(struct TCP_Server_Info *server); > extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, > struct cifsTconInfo *); >@@ -101,7 +102,8 @@ void cifs_proc_clean(void); > > extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, > struct nls_table *nls_info); >-extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses); >+extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses, >+ struct key **spnego_key); > > extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, > const char *tree, struct cifsTconInfo *tcon, >diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c >index f0d9a48..ea050b9 100644 >--- a/fs/cifs/cifssmb.c >+++ b/fs/cifs/cifssmb.c >@@ -38,6 +38,7 @@ > #include "cifsproto.h" > #include "cifs_unicode.h" > #include "cifs_debug.h" >+#include "cifsauth.h" > > #ifdef CONFIG_CIFS_POSIX > static struct { >@@ -405,7 +406,8 @@ static int validate_t2(struct smb_t2_rsp *pSMB) > return rc; > } > int >-CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) >+CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses, >+ struct key **spnego_key) > { > NEGOTIATE_REQ *pSMB; > NEGOTIATE_RSP *pSMBr; >@@ -642,16 +644,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) > if (count == 16) { > server->secType = RawNTLMSSP; > } else { >- rc = decode_negTokenInit(pSMBr->u.extended_response. >+ rc = cifs_get_spnego_key(ses, >+ pSMBr->u.extended_response. > SecurityBlob, >- count - 16, >- &server->secType); >- if (rc == 1) { >- /* BB Need to fill struct for sessetup here */ >- rc = -EOPNOTSUPP; >- } else { >- rc = -EINVAL; >- } >+ count - 16, spnego_key); >+ /* FIXME: could also be NTLMSSP */ >+ server->secType = Kerberos; >+ if (rc) >+ goto neg_err_exit; > } > } else > server->capabilities &= ~CAP_EXTENDED_SECURITY; >diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c >index 676bbf2..8ea30fa 100644 >--- a/fs/cifs/connect.c >+++ b/fs/cifs/connect.c >@@ -3515,12 +3515,13 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, > char ntlm_session_key[CIFS_SESS_KEY_SIZE]; > int ntlmv2_flag = FALSE; > int first_time = 0; >+ struct key *spnego_key = NULL; > > /* what if server changes its buffer size after dropping the session? */ > if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ { >- rc = CIFSSMBNegotiate(xid, pSesInfo); >+ rc = CIFSSMBNegotiate(xid, pSesInfo, &spnego_key); > if (rc == -EAGAIN) /* retry only once on 1st time connection */ { >- rc = CIFSSMBNegotiate(xid, pSesInfo); >+ rc = CIFSSMBNegotiate(xid, pSesInfo, &spnego_key); > if (rc == -EAGAIN) > rc = -EHOSTDOWN; > } >@@ -3548,7 +3549,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, > pSesInfo->server->timeAdj)); > if (experimEnabled < 2) > rc = CIFS_SessSetup(xid, pSesInfo, >- first_time, nls_info); >+ first_time, nls_info, spnego_key); > else if (extended_security > && (pSesInfo->capabilities > & CAP_EXTENDED_SECURITY) >@@ -3627,6 +3628,8 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, > } > } > ss_err_exit: >+ if (spnego_key) >+ key_put(spnego_key); > return rc; > } > >diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c >index 899dc60..eedd97b 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 "cifsauth.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, struct key *spnego_key) > { > int rc = 0; > int wct; >@@ -341,7 +342,7 @@ 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; >@@ -395,6 +396,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 +503,36 @@ 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) { >+ struct cifs_spnego_msg *msg = spnego_key->payload.data; > 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; >+ iov[1].iov_len = msg->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); >+ } >+ /* FIXME: What do we do here if unicode isn't enabled? */ > } > >- 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 */ >
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