Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: (21 commits)
  [CIFS] fix oops on second mount to same server when null auth is used
  [CIFS] Fix stale mode after readdir when cifsacl specified
  [CIFS] add mode to acl conversion helper function
  [CIFS] Fix incorrect mode when ACL had deny access control entries
  [CIFS] Add uid to key description so krb can handle user mounts
  [CIFS] Fix walking out end of cifs dacl
  [CIFS] Add upcall files for cifs to use spnego/kerberos
  [CIFS] add OIDs for KRB5 and MSKRB5 to ASN1 parsing routines
  [CIFS] Register and unregister cifs_spnego_key_type on module init/exit
  [CIFS] implement upcalls for SPNEGO blob via keyctl API
  [CIFS] allow cifs_calc_signature2 to deal with a zero length iovec
  [CIFS] If no Access Control Entries, set mode perm bits to zero
  [CIFS] when mount helper missing fix slash wrong direction in share
  [CIFS] Don't request too much permission when reading an ACL
  [CIFS] enable get mode from ACL when cifsacl mount option specified
  [CIFS] ACL support part 8
  [CIFS] acl support part 7
  [CIFS] acl support part 6
  [CIFS] acl support part 6
  [CIFS] remove unused funtion compile warning when experimental off
  ...
  • Loading branch information
Linus Torvalds committed Nov 12, 2007
2 parents 92d140e + 9b8f5f5 commit 4601597
Show file tree
Hide file tree
Showing 24 changed files with 727 additions and 171 deletions.
2 changes: 1 addition & 1 deletion fs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 10 additions & 1 deletion fs/cifs/CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Version 1.52
------------
Fix oops on second mount to server when null auth is used.

Version 1.51
------------
Fix memory leak in statfs when mounted to very old servers (e.g.
Expand All @@ -12,7 +16,12 @@ leak that causes cifsd not to stop and rmmod to fail to cleanup
cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on
bigendian architectures. Fix possible memory corruption when
EAGAIN returned on kern_recvmsg. Return better error if server
requires packet signing but client has disabled it.
requires packet signing but client has disabled it. When mounted
with cifsacl mount option - mode bits are approximated based
on the contents of the ACL of the file or directory. When cifs
mount helper is missing convert make sure that UNC name
has backslash (not forward slash) between ip address of server
and the share name.

Version 1.50
------------
Expand Down
7 changes: 6 additions & 1 deletion fs/cifs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
35 changes: 24 additions & 11 deletions fs/cifs/asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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*/

Expand Down Expand Up @@ -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?"));
Expand Down Expand Up @@ -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;
}
128 changes: 128 additions & 0 deletions fs/cifs/cifs_spnego.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* 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= + ;uid= + NULL */
desc_len = 4 + 5 + 32 + 1 + 5 + strlen(hostname) +
strlen(";sec=krb5") + 7 + sizeof(uid_t)*2 + 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, "0x%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;

dp = description + strlen(description);
sprintf(dp, ";uid=0x%x", sesInfo->linux_uid);

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;
}
46 changes: 46 additions & 0 deletions fs/cifs/cifs_spnego.h
Original file line number Diff line number Diff line change
@@ -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 */
Loading

0 comments on commit 4601597

Please sign in to comment.