Commit ded679fe authored by Steve French's avatar Steve French

Merge bk://linux.bkbits.net/linux-2.5

into hostme.bitkeeper.com:/repos/c/cifs/linux-2.5cifs
parents f9c235e6 4c3bd7e4
...@@ -1652,6 +1652,22 @@ config CIFS_STATS ...@@ -1652,6 +1652,22 @@ config CIFS_STATS
Enabling this option will cause statistics for each server share Enabling this option will cause statistics for each server share
mounted by the cifs client to be displayed in /proc/fs/cifs/Stats mounted by the cifs client to be displayed in /proc/fs/cifs/Stats
config CIFS_XATTR
bool "CIFS extended attributes (EXPERIMENTAL)"
depends on CIFS
help
Extended attributes are name:value pairs associated with inodes by
the kernel or by users (see the attr(5) manual page, or visit
<http://acl.bestbits.at/> for details). CIFS maps the name of
extended attributes beginning with the user namespace prefix
to SMB/CIFS EAs. EAs are stored on Windows servers without the
user namespace prefix, but their names are seen by Linux cifs clients
prefaced by the user namespace prefix. The system namespace
(used by some filesystems to store ACLs) is not supported at
this time.
If unsure, say N.
config CIFS_POSIX config CIFS_POSIX
bool "CIFS POSIX Extensions (EXPERIMENTAL)" bool "CIFS POSIX Extensions (EXPERIMENTAL)"
depends on CIFS depends on CIFS
......
Version 1.22
------------
Add config option to enable XATTR (extended attribute) support, mapping
xattr names in the "user." namespace space to SMB/CIFS EAs.
Version 1.21
------------
Add new mount parm to control whether mode check (vfs_permission) is done on
the client. If Unix extensions are enabled and the uids on the client
and server do not match, client permission checks are meaningless on
server uids that do not exist on the client (this does not affect the
normal ACL check which occurs on the server). Fix default uid
on mknod to match create and mkdir. Add optional mount parm to allow
override of the default uid behavior (in which the server sets the uid
and gid of newly created files). Normally for network filesystem mounts
user want the server to set the uid/gid on newly created files (rather than
using uid of the client processes you would in a local filesystem).
Version 1.20 Version 1.20
------------ ------------
Make transaction counts more consistent. Merge /proc/fs/cifs/SimultaneousOps Make transaction counts more consistent. Merge /proc/fs/cifs/SimultaneousOps
......
...@@ -255,7 +255,33 @@ A partial list of the supported mount options follows: ...@@ -255,7 +255,33 @@ A partial list of the supported mount options follows:
mount helper will not prompt the user for a password mount helper will not prompt the user for a password
if guest is specified on the mount options. If no if guest is specified on the mount options. If no
password is specified a null password will be used. password is specified a null password will be used.
perm Client does permission checks (vfs_permission check of uid
and gid of the file against the mode and desired operation),
Note that this is in addition to the normal ACL check on the
target machine done by the server software.
Client permission checking is enabled by default.
noperm Client does not do permission checks. This can expose
files on this mount to access by other users on the local
client system. It is typically only needed when the server
supports the CIFS Unix Extensions but the UIDs/GIDs on the
client and server system do not match closely enough to allow
access by the user doing the mount.
Note that this does not affect the normal ACL check on the
target machine done by the server software (of the server
ACL against the user name provided at mount time).
setuids If the CIFS Unix extensions are negotiated with the server
the client will attempt to set the effective uid and gid of
the local process on newly created files, directories, and
devices (create, mkdir, mknod).
nosetuids The client will not attempt to set the uid and gid on
on newly created files, directories, and devices (create,
mkdir, mknod) which will result in the server setting the
uid and gid to the default (usually the server uid of the
usern who mounted the share). Letting the server (rather than
the client) set the uid and gid is the default. This
parameter has no effect if the CIFS Unix Extensions are not
negotiated.
The mount.cifs mount helper also accepts a few mount options before -o The mount.cifs mount helper also accepts a few mount options before -o
including: including:
......
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
#ifndef _CIFS_FS_SB_H #ifndef _CIFS_FS_SB_H
#define _CIFS_FS_SB_H #define _CIFS_FS_SB_H
#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */
#define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */
struct cifs_sb_info { struct cifs_sb_info {
struct cifsTconInfo *tcon; /* primary mount */ struct cifsTconInfo *tcon; /* primary mount */
struct list_head nested_tcon_q; struct list_head nested_tcon_q;
...@@ -28,5 +31,6 @@ struct cifs_sb_info { ...@@ -28,5 +31,6 @@ struct cifs_sb_info {
gid_t mnt_gid; gid_t mnt_gid;
mode_t mnt_file_mode; mode_t mnt_file_mode;
mode_t mnt_dir_mode; mode_t mnt_dir_mode;
int mnt_cifs_flags;
}; };
#endif /* _CIFS_FS_SB_H */ #endif /* _CIFS_FS_SB_H */
...@@ -41,8 +41,6 @@ ...@@ -41,8 +41,6 @@
#include "cifs_fs_sb.h" #include "cifs_fs_sb.h"
#include <linux/mm.h> #include <linux/mm.h>
#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
/* BB when mempool_resize is added back in, we will resize pool on new mount */
#define CIFS_MIN_RCV_POOL 11 /* enough for progress to five servers */
#ifdef CONFIG_CIFS_QUOTA #ifdef CONFIG_CIFS_QUOTA
static struct quotactl_ops cifs_quotactl_ops; static struct quotactl_ops cifs_quotactl_ops;
...@@ -192,15 +190,11 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf) ...@@ -192,15 +190,11 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf)
static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd) static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd)
{ {
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
cifs_sb = CIFS_SB(inode->i_sb); cifs_sb = CIFS_SB(inode->i_sb);
if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
/* the server supports the Unix-like mode bits and does its
own permission checks, and therefore we do not allow the file
mode to be overriden on these mounts - so do not do perm
check on client side */
return 0; return 0;
} else /* file mode might have been restricted at mount time } else /* file mode might have been restricted at mount time
on the client (above and beyond ACL on servers) for on the client (above and beyond ACL on servers) for
...@@ -746,6 +740,7 @@ init_cifs(void) ...@@ -746,6 +740,7 @@ init_cifs(void)
*/ */
atomic_set(&sesInfoAllocCount, 0); atomic_set(&sesInfoAllocCount, 0);
atomic_set(&tconInfoAllocCount, 0); atomic_set(&tconInfoAllocCount, 0);
atomic_set(&tcpSesAllocCount,0);
atomic_set(&tcpSesReconnectCount, 0); atomic_set(&tcpSesReconnectCount, 0);
atomic_set(&tconInfoReconnectCount, 0); atomic_set(&tconInfoReconnectCount, 0);
......
...@@ -32,14 +32,10 @@ ...@@ -32,14 +32,10 @@
#define TRUE 1 #define TRUE 1
#endif #endif
extern int map_cifs_error(int error_class, int error_code,
int status_codes_negotiated);
extern struct address_space_operations cifs_addr_ops; extern struct address_space_operations cifs_addr_ops;
/* Functions related to super block operations */ /* Functions related to super block operations */
extern struct super_operations cifs_super_ops; extern struct super_operations cifs_super_ops;
extern void cifs_put_inode(struct inode *);
extern void cifs_read_inode(struct inode *); extern void cifs_read_inode(struct inode *);
extern void cifs_delete_inode(struct inode *); extern void cifs_delete_inode(struct inode *);
/* extern void cifs_write_inode(struct inode *); *//* BB not needed yet */ /* extern void cifs_write_inode(struct inode *); *//* BB not needed yet */
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
termination then *2 for unicode versions */ termination then *2 for unicode versions */
#define MAX_PASSWORD_SIZE 16 #define MAX_PASSWORD_SIZE 16
#define CIFS_MIN_RCV_POOL 4
/* /*
* MAX_REQ is the maximum number of requests that WE will send * MAX_REQ is the maximum number of requests that WE will send
* on one socket concurently. It also matches the most common * on one socket concurently. It also matches the most common
...@@ -391,7 +393,7 @@ GLOBAL_EXTERN char Local_System_Name[15]; ...@@ -391,7 +393,7 @@ GLOBAL_EXTERN char Local_System_Name[15];
*/ */
GLOBAL_EXTERN atomic_t sesInfoAllocCount; GLOBAL_EXTERN atomic_t sesInfoAllocCount;
GLOBAL_EXTERN atomic_t tconInfoAllocCount; GLOBAL_EXTERN atomic_t tconInfoAllocCount;
GLOBAL_EXTERN atomic_t tcpSesAllocCount;
GLOBAL_EXTERN atomic_t tcpSesReconnectCount; GLOBAL_EXTERN atomic_t tcpSesReconnectCount;
GLOBAL_EXTERN atomic_t tconInfoReconnectCount; GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
......
...@@ -1046,6 +1046,8 @@ typedef union smb_com_transaction2 { ...@@ -1046,6 +1046,8 @@ typedef union smb_com_transaction2 {
/* PathInfo/FileInfo infolevels */ /* PathInfo/FileInfo infolevels */
#define SMB_INFO_STANDARD 1 #define SMB_INFO_STANDARD 1
#define SMB_SET_FILE_EA 2
#define SMB_QUERY_FILE_EA_SIZE 2
#define SMB_INFO_QUERY_EAS_FROM_LIST 3 #define SMB_INFO_QUERY_EAS_FROM_LIST 3
#define SMB_INFO_QUERY_ALL_EAS 4 #define SMB_INFO_QUERY_ALL_EAS 4
#define SMB_INFO_IS_NAME_VALID 6 #define SMB_INFO_IS_NAME_VALID 6
...@@ -1620,6 +1622,19 @@ typedef struct { ...@@ -1620,6 +1622,19 @@ typedef struct {
char LinkDest[1]; char LinkDest[1];
} FILE_UNIX_LINK_INFO; /* level 513 QPathInfo */ } FILE_UNIX_LINK_INFO; /* level 513 QPathInfo */
typedef struct {
__u16 CreationDate;
__u16 CreationTime;
__u16 LastAccessDate;
__u16 LastAccessTime;
__u16 LastWriteDate;
__u16 LastWriteTime;
__u32 DataSize; /* File Size (EOF) */
__u32 AllocationSize;
__u16 Attributes; /* verify not u32 */
__u32 EASize;
} FILE_INFO_STANDARD; /* level 1 SetPath/FileInfo */
/* defines for enumerating possible values of the Unix type field below */ /* defines for enumerating possible values of the Unix type field below */
#define UNIX_FILE 0 #define UNIX_FILE 0
#define UNIX_DIR 1 #define UNIX_DIR 1
...@@ -1680,12 +1695,12 @@ typedef struct { ...@@ -1680,12 +1695,12 @@ typedef struct {
} FILE_DIRECTORY_INFO; /* level 257 FF response data area */ } FILE_DIRECTORY_INFO; /* level 257 FF response data area */
struct gea { struct gea {
unsigned char cbName; unsigned char name_len;
char szName[1]; char name[1];
}; };
struct gealist { struct gealist {
unsigned long cbList; unsigned long list_len;
struct gea list[1]; struct gea list[1];
}; };
...@@ -1693,7 +1708,7 @@ struct fea { ...@@ -1693,7 +1708,7 @@ struct fea {
unsigned char EA_flags; unsigned char EA_flags;
__u8 name_len; __u8 name_len;
__u16 value_len; __u16 value_len;
char szName[1]; char name[1];
/* optionally followed by value */ /* optionally followed by value */
}; };
/* flags for _FEA.fEA */ /* flags for _FEA.fEA */
......
...@@ -128,10 +128,10 @@ extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -128,10 +128,10 @@ extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon,
char *fileName, FILE_BASIC_INFO * data, const char *fileName, const FILE_BASIC_INFO * data,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
char *fileName, __u64 size,int setAllocationSizeFlag, const char *fileName, __u64 size,int setAllocationSizeFlag,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
__u64 size, __u16 fileHandle,__u32 opener_pid, int AllocSizeFlag); __u64 size, __u16 fileHandle,__u32 opener_pid, int AllocSizeFlag);
...@@ -213,31 +213,6 @@ extern int cifs_verify_signature(const struct smb_hdr *, const char * mac_key, ...@@ -213,31 +213,6 @@ extern int cifs_verify_signature(const struct smb_hdr *, const char * mac_key,
extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass); extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass);
extern void CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, struct nls_table *); extern void CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, struct nls_table *);
extern void CalcNTLMv2_response(const struct cifsSesInfo *,char * ); extern void CalcNTLMv2_response(const struct cifsSesInfo *,char * );
extern int CIFSBuildServerList(int xid, char *serverBufferList,
int recordlength, int *entries,
int *totalEntries, int *topoChangedFlag);
extern int CIFSSMBQueryShares(int xid, struct cifsTconInfo *tcon,
struct shareInfo *shareList, int bufferLen,
int *entries, int *totalEntries);
extern int CIFSSMBQueryAlias(int xid, struct cifsTconInfo *tcon,
struct aliasInfo *aliasList, int bufferLen,
int *entries, int *totalEntries);
extern int CIFSSMBAliasInfo(int xid, struct cifsTconInfo *tcon,
char *aliasName, char *serverName,
char *shareName, char *comment);
extern int CIFSSMBGetShareInfo(int xid, struct cifsTconInfo *tcon,
char *share, char *comment);
extern int CIFSSMBGetUserPerms(int xid, struct cifsTconInfo *tcon,
char *userName, char *searchName, int *perms);
extern int CIFSSMBSync(int xid, struct cifsTconInfo *tcon, int netfid, int pid);
extern int CIFSSMBSeek(int xid,
struct cifsTconInfo *tcon,
int netfid,
int pid,
int whence, unsigned long offset, long long *newoffset);
extern int CIFSSMBCopy(int xid, extern int CIFSSMBCopy(int xid,
struct cifsTconInfo *source_tcon, struct cifsTconInfo *source_tcon,
const char *fromName, const char *fromName,
...@@ -247,8 +222,15 @@ extern int CIFSSMBCopy(int xid, ...@@ -247,8 +222,15 @@ extern int CIFSSMBCopy(int xid,
extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
const int notify_subdirs,const __u16 netfid,__u32 filter, const int notify_subdirs,const __u16 netfid,__u32 filter,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName, char * EAData,
char * EAData, size_t size, size_t bufsize, const struct nls_table *nls_codepage);
const struct nls_table *nls_codepage); extern ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon,
const unsigned char * searchName,const unsigned char * ea_name,
unsigned char * ea_value, size_t buf_size,
const struct nls_table *nls_codepage);
extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon,
const char *fileName, const char * ea_name,
const void * ea_value, const __u16 ea_value_len,
const struct nls_table *nls_codepage);
#endif /* _CIFSPROTO_H */ #endif /* _CIFSPROTO_H */
...@@ -2287,7 +2287,7 @@ CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -2287,7 +2287,7 @@ CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBQFSAttributeInfo(int xid, struct cifsTconInfo *tcon, CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon,
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
{ {
/* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */ /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
...@@ -2359,7 +2359,7 @@ CIFSSMBQFSAttributeInfo(int xid, struct cifsTconInfo *tcon, ...@@ -2359,7 +2359,7 @@ CIFSSMBQFSAttributeInfo(int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBQFSDeviceInfo(int xid, struct cifsTconInfo *tcon, CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon,
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
{ {
/* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */ /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
...@@ -2432,7 +2432,7 @@ CIFSSMBQFSDeviceInfo(int xid, struct cifsTconInfo *tcon, ...@@ -2432,7 +2432,7 @@ CIFSSMBQFSDeviceInfo(int xid, struct cifsTconInfo *tcon,
} }
int int
CIFSSMBQFSUnixInfo(int xid, struct cifsTconInfo *tcon, CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
{ {
/* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */ /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
...@@ -2512,7 +2512,7 @@ CIFSSMBQFSUnixInfo(int xid, struct cifsTconInfo *tcon, ...@@ -2512,7 +2512,7 @@ CIFSSMBQFSUnixInfo(int xid, struct cifsTconInfo *tcon,
in Samba which this routine can run into */ in Samba which this routine can run into */
int int
CIFSSMBSetEOF(int xid, struct cifsTconInfo *tcon, char *fileName, CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName,
__u64 size, int SetAllocation, const struct nls_table *nls_codepage) __u64 size, int SetAllocation, const struct nls_table *nls_codepage)
{ {
struct smb_com_transaction2_spi_req *pSMB = NULL; struct smb_com_transaction2_spi_req *pSMB = NULL;
...@@ -2692,8 +2692,9 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, ...@@ -2692,8 +2692,9 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
} }
int int
CIFSSMBSetTimes(int xid, struct cifsTconInfo *tcon, char *fileName, CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName,
FILE_BASIC_INFO * data, const struct nls_table *nls_codepage) const FILE_BASIC_INFO * data,
const struct nls_table *nls_codepage)
{ {
TRANSACTION2_SPI_REQ *pSMB = NULL; TRANSACTION2_SPI_REQ *pSMB = NULL;
TRANSACTION2_SPI_RSP *pSMBr = NULL; TRANSACTION2_SPI_RSP *pSMBr = NULL;
...@@ -2770,6 +2771,89 @@ CIFSSMBSetTimes(int xid, struct cifsTconInfo *tcon, char *fileName, ...@@ -2770,6 +2771,89 @@ CIFSSMBSetTimes(int xid, struct cifsTconInfo *tcon, char *fileName,
return rc; return rc;
} }
int
CIFSSMBSetTimesLegacy(int xid, struct cifsTconInfo *tcon, char *fileName,
FILE_INFO_STANDARD * data, const struct nls_table *nls_codepage)
{
TRANSACTION2_SPI_REQ *pSMB = NULL;
TRANSACTION2_SPI_RSP *pSMBr = NULL;
int name_len;
int rc = 0;
int bytes_returned = 0;
char *data_offset;
cFYI(1, ("In SetTimesLegacy"));
SetTimesRetryLegacy:
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr);
if (rc)
return rc;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(fileName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len);
}
/* BB fixme - we have to map to FILE_STANDARD_INFO (level 1 info
in parent function, from the better and ususal FILE_BASIC_INFO */
pSMB->ParameterCount = 6 + name_len;
pSMB->DataCount = sizeof (FILE_INFO_STANDARD);
pSMB->MaxParameterCount = cpu_to_le16(2);
pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
pSMB->Flags = 0;
pSMB->Timeout = 0;
pSMB->Reserved2 = 0;
pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_spi_req,
InformationLevel) - 4;
pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;
pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
pSMB->SetupCount = 1;
pSMB->Reserved3 = 0;
pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount + pSMB->DataCount;
pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
pSMB->TotalDataCount = pSMB->DataCount;
pSMB->TotalParameterCount = pSMB->ParameterCount;
/* I doubt that passthrough levels apply to this old
preNT info level */
/* if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
else*/
pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
pSMB->Reserved4 = 0;
pSMB->hdr.smb_buf_length += pSMB->ByteCount;
memcpy(data_offset, data, sizeof (FILE_INFO_STANDARD));
pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
cFYI(1, ("SetPathInfo (times legacy) returned %d", rc));
}
if (pSMB)
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
goto SetTimesRetryLegacy;
return rc;
}
int int
CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
char *fileName, __u64 mode, __u64 uid, __u64 gid, char *fileName, __u64 mode, __u64 uid, __u64 gid,
...@@ -2915,10 +2999,10 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, ...@@ -2915,10 +2999,10 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
return rc; return rc;
} }
#ifdef CONFIG_CIFS_XATTR #ifdef CONFIG_CIFS_XATTR
int ssize_t
CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName,
char * EAData, size_t size, char * EAData, size_t buf_size,
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
{ {
/* BB assumes one setup word */ /* BB assumes one setup word */
...@@ -2927,6 +3011,8 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, ...@@ -2927,6 +3011,8 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
int rc = 0; int rc = 0;
int bytes_returned; int bytes_returned;
int name_len; int name_len;
struct fea * temp_fea;
char * temp_ptr;
cFYI(1, ("In Query All EAs path %s", searchName)); cFYI(1, ("In Query All EAs path %s", searchName));
QAllEAsRetry: QAllEAsRetry:
...@@ -2942,7 +3028,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, ...@@ -2942,7 +3028,7 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
, nls_codepage); , nls_codepage);
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(searchName, 530); name_len = strnlen(searchName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len); strncpy(pSMB->FileName, searchName, name_len);
...@@ -3001,7 +3087,53 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, ...@@ -3001,7 +3087,53 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
ea_response_data = (struct fealist *) ea_response_data = (struct fealist *)
(((char *) &pSMBr->hdr.Protocol) + (((char *) &pSMBr->hdr.Protocol) +
pSMBr->DataOffset); pSMBr->DataOffset);
ea_response_data->list_len =
cpu_to_le32(ea_response_data->list_len);
cFYI(1,("ea length %d",ea_response_data->list_len)); cFYI(1,("ea length %d",ea_response_data->list_len));
name_len = ea_response_data->list_len;
if(name_len <= 8) {
/* returned EA size zeroed at top of function */
cFYI(1,("empty EA list returned from server"));
} else {
/* account for ea list len */
name_len -= 4;
temp_fea = ea_response_data->list;
temp_ptr = (char *)temp_fea;
while(name_len > 0) {
name_len -= 4;
temp_ptr += 4;
rc += temp_fea->name_len;
/* account for prefix user. and trailing null */
rc = rc + 5 + 1;
if(rc<buf_size) {
memcpy(EAData,"user.",5);
EAData+=5;
memcpy(EAData,temp_ptr,temp_fea->name_len);
EAData+=temp_fea->name_len;
/* null terminate name */
*EAData = 0;
EAData = EAData + 1;
} else if(buf_size == 0) {
/* skip copy - calc size only */
} else {
/* stop before overrun buffer */
rc = -ERANGE;
break;
}
name_len -= temp_fea->name_len;
temp_ptr += temp_fea->name_len;
/* account for trailing null */
name_len--;
temp_ptr++;
temp_fea->value_len = cpu_to_le16(temp_fea->value_len);
name_len -= temp_fea->value_len;
temp_ptr += temp_fea->value_len;
/* BB check that temp_ptr is still within smb BB*/
/* no trailing null to account for in value len */
/* go on to next EA */
temp_fea = (struct fea *)temp_ptr;
}
}
} }
} }
if (pSMB) if (pSMB)
...@@ -3011,4 +3143,255 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, ...@@ -3011,4 +3143,255 @@ CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
return rc; return rc;
} }
ssize_t CIFSSMBQueryEA(const int xid,struct cifsTconInfo * tcon,
const unsigned char * searchName,const unsigned char * ea_name,
unsigned char * ea_value, size_t buf_size,
const struct nls_table *nls_codepage)
{
TRANSACTION2_QPI_REQ *pSMB = NULL;
TRANSACTION2_QPI_RSP *pSMBr = NULL;
int rc = 0;
int bytes_returned;
int name_len;
struct fea * temp_fea;
char * temp_ptr;
cFYI(1, ("In Query EA path %s", searchName));
QEARetry:
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr);
if (rc)
return rc;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(searchName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len);
}
pSMB->TotalParameterCount = 2 /* level */ + 4 /* reserved */ +
name_len /* includes null */ ;
pSMB->TotalDataCount = 0;
pSMB->MaxParameterCount = cpu_to_le16(2);
pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
pSMB->Flags = 0;
pSMB->Timeout = 0;
pSMB->Reserved2 = 0;
pSMB->ParameterOffset = cpu_to_le16(offsetof(
struct smb_com_transaction2_qpi_req ,InformationLevel) - 4);
pSMB->DataCount = 0;
pSMB->DataOffset = 0;
pSMB->SetupCount = 1;
pSMB->Reserved3 = 0;
pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
pSMB->ParameterCount = pSMB->TotalParameterCount;
pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
pSMB->Reserved4 = 0;
pSMB->hdr.smb_buf_length += pSMB->ByteCount;
pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
cFYI(1, ("Send error in Query EA = %d", rc));
} else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
/* BB also check enough total bytes returned */
/* BB we need to improve the validity checking
of these trans2 responses */
if ((pSMBr->ByteCount < 4) || (pSMBr->DataOffset > 512))
rc = -EIO; /* bad smb */
/* else if (pFindData){
memcpy((char *) pFindData,
(char *) &pSMBr->hdr.Protocol +
pSMBr->DataOffset, kl);
}*/ else {
/* check that length of list is not more than bcc */
/* check that each entry does not go beyond length
of list */
/* check that each element of each entry does not
go beyond end of list */
struct fealist * ea_response_data;
rc = -ENOENT;
/* validate_trans2_offsets() */
/* BB to check if(start of smb + pSMBr->DataOffset > &bcc+ bcc)*/
ea_response_data = (struct fealist *)
(((char *) &pSMBr->hdr.Protocol) +
pSMBr->DataOffset);
ea_response_data->list_len =
cpu_to_le32(ea_response_data->list_len);
cFYI(1,("ea length %d",ea_response_data->list_len));
name_len = ea_response_data->list_len;
if(name_len <= 8) {
/* returned EA size zeroed at top of function */
cFYI(1,("empty EA list returned from server"));
} else {
/* account for ea list len */
name_len -= 4;
temp_fea = ea_response_data->list;
temp_ptr = (char *)temp_fea;
/* loop through checking if we have a matching
name and then return the associated value */
while(name_len > 0) {
name_len -= 4;
temp_ptr += 4;
temp_fea->value_len = cpu_to_le16(temp_fea->value_len);
/* BB validate that value_len falls within SMB,
even though maximum for name_len is 255 */
if(memcmp(temp_fea->name,ea_name,
temp_fea->name_len) == 0) {
/* found a match */
rc = temp_fea->value_len;
/* account for prefix user. and trailing null */
if(rc<=buf_size) {
memcpy(ea_value,
temp_fea->name+temp_fea->name_len+1,
rc);
/* ea values, unlike ea names,
are not null terminated */
} else if(buf_size == 0) {
/* skip copy - calc size only */
} else {
/* stop before overrun buffer */
rc = -ERANGE;
}
break;
}
name_len -= temp_fea->name_len;
temp_ptr += temp_fea->name_len;
/* account for trailing null */
name_len--;
temp_ptr++;
name_len -= temp_fea->value_len;
temp_ptr += temp_fea->value_len;
/* no trailing null to account for in value len */
/* go on to next EA */
temp_fea = (struct fea *)temp_ptr;
}
}
}
}
if (pSMB)
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
goto QEARetry;
return rc;
}
int
CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName,
const char * ea_name, const void * ea_value,
const __u16 ea_value_len, const struct nls_table *nls_codepage)
{
struct smb_com_transaction2_spi_req *pSMB = NULL;
struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
struct fealist *parm_data;
int name_len;
int rc = 0;
int bytes_returned = 0;
cFYI(1, ("In SetEA"));
SetEARetry:
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr);
if (rc)
return rc;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(fileName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len);
}
pSMB->ParameterCount = 6 + name_len;
/* done calculating parms using name_len of file name,
now use name_len to calculate length of ea name
we are going to create in the inode xattrs */
if(ea_name == NULL)
name_len = 0;
else
name_len = strnlen(ea_name,255);
pSMB->DataCount = sizeof(*parm_data) + ea_value_len + name_len + 1;
pSMB->MaxParameterCount = cpu_to_le16(2);
pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
pSMB->Flags = 0;
pSMB->Timeout = 0;
pSMB->Reserved2 = 0;
pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_spi_req,
InformationLevel) - 4;
pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
pSMB->InformationLevel =
cpu_to_le16(SMB_SET_FILE_EA);
parm_data =
(struct fealist *) (((char *) &pSMB->hdr.Protocol) +
pSMB->DataOffset);
pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
pSMB->SetupCount = 1;
pSMB->Reserved3 = 0;
pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount + pSMB->DataCount;
pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
parm_data->list_len = (__u32)(pSMB->DataCount);
parm_data->list[0].EA_flags = 0;
/* we checked above that name len is less than 255 */
parm_data->list[0].name_len = (__u8)name_len;;
/* EA names are always ASCII */
strncpy(parm_data->list[0].name,ea_name,name_len);
parm_data->list[0].name[name_len] = 0;
parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
/* caller ensures that ea_value_len is less than 64K but
we need to ensure that it fits within the smb */
/*BB add length check that it would fit in negotiated SMB buffer size BB */
/* if(ea_value_len > buffer_size - 512 (enough for header)) */
if(ea_value_len)
memcpy(parm_data->list[0].name+name_len+1,ea_value,ea_value_len);
pSMB->TotalDataCount = pSMB->DataCount;
pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
pSMB->TotalParameterCount = pSMB->ParameterCount;
pSMB->Reserved4 = 0;
pSMB->hdr.smb_buf_length += pSMB->ByteCount;
pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
cFYI(1, ("SetPathInfo (EA) returned %d", rc));
}
if (pSMB)
cifs_buf_release(pSMB);
if (rc == -EAGAIN)
goto SetEARetry;
return rc;
}
#endif #endif
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/utsname.h> #include <linux/utsname.h>
#include <linux/mempool.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/processor.h> #include <asm/processor.h>
#include "cifspdu.h" #include "cifspdu.h"
...@@ -49,6 +50,8 @@ extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, ...@@ -49,6 +50,8 @@ extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
unsigned char *p24); unsigned char *p24);
extern int cifs_inet_pton(int, const char *, void *dst); extern int cifs_inet_pton(int, const char *, void *dst);
extern mempool_t *cifs_req_poolp;
struct smb_vol { struct smb_vol {
char *username; char *username;
char *password; char *password;
...@@ -64,6 +67,8 @@ struct smb_vol { ...@@ -64,6 +67,8 @@ struct smb_vol {
int rw:1; int rw:1;
int retry:1; int retry:1;
int intr:1; int intr:1;
int setuids:1;
int noperm:1;
unsigned int rsize; unsigned int rsize;
unsigned int wsize; unsigned int wsize;
unsigned int sockopt; unsigned int sockopt;
...@@ -202,6 +207,15 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -202,6 +207,15 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
current->flags |= PF_MEMALLOC; current->flags |= PF_MEMALLOC;
server->tsk = current; /* save process info to wake at shutdown */ server->tsk = current; /* save process info to wake at shutdown */
cFYI(1, ("Demultiplex PID: %d", current->pid)); cFYI(1, ("Demultiplex PID: %d", current->pid));
write_lock(&GlobalSMBSeslock);
atomic_inc(&tcpSesAllocCount);
length = tcpSesAllocCount.counter;
write_unlock(&GlobalSMBSeslock);
if(length > 1) {
mempool_resize(cifs_req_poolp,
length + CIFS_MIN_RCV_POOL,
GFP_KERNEL);
}
while (server->tcpStatus != CifsExiting) { while (server->tcpStatus != CifsExiting) {
if (smb_buffer == NULL) if (smb_buffer == NULL)
...@@ -465,6 +479,16 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -465,6 +479,16 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
} }
kfree(server); kfree(server);
write_lock(&GlobalSMBSeslock);
atomic_dec(&tcpSesAllocCount);
length = tcpSesAllocCount.counter;
write_unlock(&GlobalSMBSeslock);
if(length > 0) {
mempool_resize(cifs_req_poolp,
length + CIFS_MIN_RCV_POOL,
GFP_KERNEL);
}
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/4); schedule_timeout(HZ/4);
return 0; return 0;
...@@ -740,6 +764,14 @@ cifs_parse_mount_options(char *options, const char *devname, struct smb_vol *vol ...@@ -740,6 +764,14 @@ cifs_parse_mount_options(char *options, const char *devname, struct smb_vol *vol
vol->retry = 1; vol->retry = 1;
} else if (strnicmp(data, "soft", 4) == 0) { } else if (strnicmp(data, "soft", 4) == 0) {
vol->retry = 0; vol->retry = 0;
} else if (strnicmp(data, "perm", 4) == 0) {
vol->noperm = 0;
} else if (strnicmp(data, "noperm", 6) == 0) {
vol->noperm = 1;
} else if (strnicmp(data, "setuids", 7) == 0) {
vol->setuids = 1;
} else if (strnicmp(data, "nosetuids", 9) == 0) {
vol->setuids = 0;
} else if (strnicmp(data, "nohard", 6) == 0) { } else if (strnicmp(data, "nohard", 6) == 0) {
vol->retry = 0; vol->retry = 0;
} else if (strnicmp(data, "nosoft", 6) == 0) { } else if (strnicmp(data, "nosoft", 6) == 0) {
...@@ -1314,6 +1346,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -1314,6 +1346,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cifs_sb->mnt_file_mode = volume_info.file_mode; cifs_sb->mnt_file_mode = volume_info.file_mode;
cifs_sb->mnt_dir_mode = volume_info.dir_mode; cifs_sb->mnt_dir_mode = volume_info.dir_mode;
cFYI(1,("file mode: 0x%x dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); cFYI(1,("file mode: 0x%x dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
if(volume_info.noperm)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
if(volume_info.setuids)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
tcon = tcon =
find_unc(sin_server.sin_addr.s_addr, volume_info.UNC, find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
volume_info.username); volume_info.username);
......
...@@ -243,11 +243,19 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -243,11 +243,19 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
then we now have to set the mode if possible */ then we now have to set the mode if possible */
if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) && if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
(oplock & CIFS_CREATE_ACTION)) (oplock & CIFS_CREATE_ACTION))
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
(__u64)current->euid,
(__u64)current->egid,
0 /* dev */,
cifs_sb->local_nls);
} else {
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
(__u64)-1, (__u64)-1,
(__u64)-1, (__u64)-1,
0 /* dev */, 0 /* dev */,
cifs_sb->local_nls); cifs_sb->local_nls);
}
else { else {
/* BB implement via Windows security descriptors */ /* BB implement via Windows security descriptors */
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/ /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
...@@ -348,9 +356,16 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev ...@@ -348,9 +356,16 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
rc = -ENOMEM; rc = -ENOMEM;
if (full_path && (pTcon->ses->capabilities & CAP_UNIX)) { if (full_path && (pTcon->ses->capabilities & CAP_UNIX)) {
rc = CIFSSMBUnixSetPerms(xid, pTcon, if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
full_path, mode, current->euid, current->egid, rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
device_number, cifs_sb->local_nls); mode,(__u64)current->euid,(__u64)current->egid,
device_number, cifs_sb->local_nls);
} else {
rc = CIFSSMBUnixSetPerms(xid, pTcon,
full_path, mode, (__u64)-1, (__u64)-1,
device_number, cifs_sb->local_nls);
}
if(!rc) { if(!rc) {
rc = cifs_get_inode_info_unix(&newinode, full_path, rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb,xid); inode->i_sb,xid);
......
...@@ -480,12 +480,20 @@ cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) ...@@ -480,12 +480,20 @@ cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
d_instantiate(direntry, newinode); d_instantiate(direntry, newinode);
if(direntry->d_inode) if(direntry->d_inode)
direntry->d_inode->i_nlink = 2; direntry->d_inode->i_nlink = 2;
if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
(__u64)-1, CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
(__u64)-1, (__u64)current->euid,
0 /* dev_t */, (__u64)current->egid,
cifs_sb->local_nls); 0 /* dev_t */,
cifs_sb->local_nls);
} else {
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
(__u64)-1,
(__u64)-1,
0 /* dev_t */,
cifs_sb->local_nls);
}
else { /* BB to be implemented via Windows secrty descriptors*/ else { /* BB to be implemented via Windows secrty descriptors*/
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/ /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
} }
......
...@@ -70,8 +70,6 @@ void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8, ...@@ -70,8 +70,6 @@ void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
void NTLMSSPOWFencrypt(unsigned char passwd[8], void NTLMSSPOWFencrypt(unsigned char passwd[8],
unsigned char *ntlmchalresp, unsigned char p24[24]); unsigned char *ntlmchalresp, unsigned char p24[24]);
void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
int decode_pw_buffer(char in_buffer[516], char *new_pwrd,
int new_pwrd_size, __u32 * new_pw_len);
/* /*
This implements the X/Open SMB password encryption This implements the X/Open SMB password encryption
......
...@@ -26,27 +26,178 @@ ...@@ -26,27 +26,178 @@
#include "cifsproto.h" #include "cifsproto.h"
#include "cifs_debug.h" #include "cifs_debug.h"
int cifs_removexattr(struct dentry * direntry, const char * name) #define MAX_EA_VALUE_SIZE 65535
#define CIFS_XATTR_DOS_ATTRIB "user.DOSATTRIB"
#define CIFS_XATTR_USER_PREFIX "user."
#define CIFS_XATTR_SYSTEM_PREFIX "system."
#define CIFS_XATTR_OS2_PREFIX "OS2." /* BB should check for this someday */
/* also note could add check for security prefix XATTR_SECURITY_PREFIX */
int cifs_removexattr(struct dentry * direntry, const char * ea_name)
{ {
int rc = -EOPNOTSUPP; int rc = -EOPNOTSUPP;
#ifdef CONFIG_CIFS_XATTR
int xid;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct super_block * sb;
char * full_path;
if(direntry == NULL)
return -EIO;
if(direntry->d_inode == NULL)
return -EIO;
sb = direntry->d_inode->i_sb;
if(sb == NULL)
return -EIO;
xid = GetXid();
cifs_sb = CIFS_SB(sb);
pTcon = cifs_sb->tcon;
down(&sb->s_vfs_rename_sem);
full_path = build_path_from_dentry(direntry);
up(&sb->s_vfs_rename_sem);
if(full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
}
if(ea_name == NULL) {
cFYI(1,("Null xattr names not supported"));
} else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5)) {
cFYI(1,("illegal xattr namespace %s (only user namespace supported)",ea_name));
/* BB what if no namespace prefix? */
/* Should we just pass them to server, except for
system and perhaps security prefixes? */
} else {
ea_name+=5; /* skip past user. prefix */
rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,0,
(__u16)0, cifs_sb->local_nls);
}
if (full_path)
kfree(full_path);
FreeXid(xid);
#endif
return rc; return rc;
} }
int cifs_setxattr(struct dentry * direntry, const char * name, int cifs_setxattr(struct dentry * direntry, const char * ea_name,
const void * value, size_t size, int flags) const void * ea_value, size_t value_size, int flags)
{ {
int rc = -EOPNOTSUPP; int rc = -EOPNOTSUPP;
#ifdef CONFIG_CIFS_XATTR
int xid;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct super_block * sb;
char * full_path;
if(direntry == NULL)
return -EIO;
if(direntry->d_inode == NULL)
return -EIO;
sb = direntry->d_inode->i_sb;
if(sb == NULL)
return -EIO;
xid = GetXid();
cifs_sb = CIFS_SB(sb);
pTcon = cifs_sb->tcon;
down(&sb->s_vfs_rename_sem);
full_path = build_path_from_dentry(direntry);
up(&sb->s_vfs_rename_sem);
if(full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
}
/* return dos attributes as pseudo xattr */
/* return alt name if available as pseudo attr */
/* if proc/fs/cifs/streamstoxattr is set then
search server for EAs or streams to
returns as xattrs */
if(value_size > MAX_EA_VALUE_SIZE) {
cFYI(1,("size of EA value too large"));
if(full_path)
kfree(full_path);
FreeXid(xid);
return -EOPNOTSUPP;
}
if(ea_name == NULL) {
cFYI(1,("Null xattr names not supported"));
} else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5)) {
cFYI(1,("illegal xattr namespace %s (only user namespace supported)",ea_name));
/* BB what if no namespace prefix? */
/* Should we just pass them to server, except for
system and perhaps security prefixes? */
} else {
ea_name+=5; /* skip past user. prefix */
rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value,
(__u16)value_size, cifs_sb->local_nls);
}
if (full_path)
kfree(full_path);
FreeXid(xid);
#endif
return rc; return rc;
} }
ssize_t cifs_getxattr(struct dentry * direntry, const char * name, ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
void * value, size_t size) void * ea_value, size_t buf_size)
{ {
ssize_t rc = -EOPNOTSUPP; ssize_t rc = -EOPNOTSUPP;
#ifdef CONFIG_CIFS_XATTR
int xid;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct super_block * sb;
char * full_path;
if(direntry == NULL)
return -EIO;
if(direntry->d_inode == NULL)
return -EIO;
sb = direntry->d_inode->i_sb;
if(sb == NULL)
return -EIO;
xid = GetXid();
cifs_sb = CIFS_SB(sb);
pTcon = cifs_sb->tcon;
down(&sb->s_vfs_rename_sem);
full_path = build_path_from_dentry(direntry);
up(&sb->s_vfs_rename_sem);
if(full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
}
/* return dos attributes as pseudo xattr */
/* return alt name if available as pseudo attr */
if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5)) {
cFYI(1,("illegal xattr namespace %s (only user namespace supported)",ea_name));
/* BB what if no namespace prefix? */
/* Should we just pass them to server, except for system? */
} else {
/* We could add a check here
if proc/fs/cifs/streamstoxattr is set then
search server for EAs or streams to
returns as xattrs */
ea_name+=5; /* skip past user. */
rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value,
buf_size, cifs_sb->local_nls);
}
if (full_path)
kfree(full_path);
FreeXid(xid);
#endif
return rc; return rc;
} }
ssize_t cifs_listxattr(struct dentry * direntry, char * ea_data, size_t ea_size) ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
{ {
ssize_t rc = -EOPNOTSUPP; ssize_t rc = -EOPNOTSUPP;
#ifdef CONFIG_CIFS_XATTR #ifdef CONFIG_CIFS_XATTR
...@@ -55,6 +206,7 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * ea_data, size_t ea_size) ...@@ -55,6 +206,7 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * ea_data, size_t ea_size)
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
struct super_block * sb; struct super_block * sb;
char * full_path; char * full_path;
if(direntry == NULL) if(direntry == NULL)
return -EIO; return -EIO;
if(direntry->d_inode == NULL) if(direntry->d_inode == NULL)
...@@ -74,13 +226,17 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * ea_data, size_t ea_size) ...@@ -74,13 +226,17 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * ea_data, size_t ea_size)
FreeXid(xid); FreeXid(xid);
return -ENOMEM; return -ENOMEM;
} }
/* return dosattributes as pseudo xattr */ /* return dos attributes as pseudo xattr */
/* return alt name if available as pseudo attr */ /* return alt name if available as pseudo attr */
/* if proc/fs/cifs/streamstoxattr is set then /* if proc/fs/cifs/streamstoxattr is set then
search server for EAs or streams to search server for EAs or streams to
returns as xattrs */ returns as xattrs */
rc = CIFSSMBQAllEAs(xid,pTcon,full_path,ea_data,ea_size,cifs_sb->local_nls); rc = CIFSSMBQAllEAs(xid,pTcon,full_path,data,buf_size,
cifs_sb->local_nls);
if (full_path)
kfree(full_path);
FreeXid(xid); FreeXid(xid);
#endif #endif
return rc; return rc;
......
...@@ -117,17 +117,8 @@ enum ...@@ -117,17 +117,8 @@ enum
struct tc_police struct tc_police
{ {
__u32 index; __u32 index;
#ifdef CONFIG_NET_CLS_ACT
int refcnt; int refcnt;
int bindcnt; int bindcnt;
#endif
/* Turned off because it requires new tc
* to work (for now maintain ABI)
*
#ifdef CONFIG_NET_CLS_ACT
__u32 capab;
#endif
*/
int action; int action;
#define TC_POLICE_UNSPEC TC_ACT_UNSPEC #define TC_POLICE_UNSPEC TC_ACT_UNSPEC
#define TC_POLICE_OK TC_ACT_OK #define TC_POLICE_OK TC_ACT_OK
...@@ -195,12 +186,8 @@ enum ...@@ -195,12 +186,8 @@ enum
TCA_U32_DIVISOR, TCA_U32_DIVISOR,
TCA_U32_SEL, TCA_U32_SEL,
TCA_U32_POLICE, TCA_U32_POLICE,
#ifdef CONFIG_NET_CLS_ACT
TCA_U32_ACT, TCA_U32_ACT,
#endif
#ifdef CONFIG_NET_CLS_IND
TCA_U32_INDEV, TCA_U32_INDEV,
#endif
__TCA_U32_MAX __TCA_U32_MAX
}; };
...@@ -212,9 +199,7 @@ struct tc_u32_key ...@@ -212,9 +199,7 @@ struct tc_u32_key
__u32 val; __u32 val;
int off; int off;
int offmask; int offmask;
#ifdef CONFIG_CLS_U32_PERF __u32 kcnt;
unsigned long kcnt;
#endif
}; };
struct tc_u32_sel struct tc_u32_sel
...@@ -229,11 +214,9 @@ struct tc_u32_sel ...@@ -229,11 +214,9 @@ struct tc_u32_sel
short hoff; short hoff;
__u32 hmask; __u32 hmask;
#ifdef CONFIG_CLS_U32_PERF struct tc_u32_key keys[0];
unsigned long rcnt; unsigned long rcnt;
unsigned long rhit; unsigned long rhit;
#endif
struct tc_u32_key keys[0];
}; };
/* Flags */ /* Flags */
...@@ -300,12 +283,8 @@ enum ...@@ -300,12 +283,8 @@ enum
TCA_FW_UNSPEC, TCA_FW_UNSPEC,
TCA_FW_CLASSID, TCA_FW_CLASSID,
TCA_FW_POLICE, TCA_FW_POLICE,
#ifdef CONFIG_NET_CLS_IND
TCA_FW_INDEV, TCA_FW_INDEV,
#endif
#ifdef CONFIG_NET_CLS_ACT
TCA_FW_ACT, TCA_FW_ACT,
#endif
__TCA_FW_MAX __TCA_FW_MAX
}; };
......
...@@ -37,7 +37,7 @@ config NET_SCH_CLK_GETTIMEOFDAY ...@@ -37,7 +37,7 @@ config NET_SCH_CLK_GETTIMEOFDAY
config NET_SCH_CLK_CPU config NET_SCH_CLK_CPU
bool "CPU cycle counter" bool "CPU cycle counter"
depends on X86_TSC || X86_64 || ALPHA || SPARC64 || PPC64 || IA64 depends on X86_TSC || X86_64 || SPARC64 || PPC64 || IA64
help help
Say Y here if you want to use the CPU's cycle counter as clock source. Say Y here if you want to use the CPU's cycle counter as clock source.
This is a cheap and high resolution clock source, but on some This is a cheap and high resolution clock source, but on some
...@@ -47,7 +47,6 @@ config NET_SCH_CLK_CPU ...@@ -47,7 +47,6 @@ config NET_SCH_CLK_CPU
The useable cycle counters are: The useable cycle counters are:
x86/x86_64 - Timestamp Counter x86/x86_64 - Timestamp Counter
alpha - Cycle Counter
sparc64 - %ticks register sparc64 - %ticks register
ppc64 - Time base ppc64 - Time base
ia64 - Interval Time Counter ia64 - Interval Time Counter
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment