aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/CHANGES5
-rw-r--r--fs/cifs/cifsacl.c120
-rw-r--r--fs/cifs/cifsacl.h24
-rw-r--r--fs/cifs/cifsfs.c4
-rw-r--r--fs/cifs/cifsfs.h7
-rw-r--r--fs/cifs/cifssmb.c2
-rw-r--r--fs/cifs/export.c1
7 files changed, 141 insertions, 22 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index c8ad87de4a78..13071faf8af7 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -6,7 +6,10 @@ which support the current POSIX Extensions to provide better semantics
6(e.g. delete for open files opened with posix open). Take into 6(e.g. delete for open files opened with posix open). Take into
7account umask on posix mkdir not just older style mkdir. Add 7account umask on posix mkdir not just older style mkdir. Add
8ability to mount to IPC$ share (which allows CIFS named pipes to be 8ability to mount to IPC$ share (which allows CIFS named pipes to be
9opened, read and written as if they were files). 9opened, read and written as if they were files). When 1st tree
10connect fails (e.g. due to signing negotiation failure) fix
11leak that causes cifsd not to stop and rmmod to fail to cleanup
12cifs_request_buffers pool.
10 13
11Version 1.50 14Version 1.50
12------------ 15------------
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 52f9cb808fd0..43ab26fff398 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -28,6 +28,20 @@
28#include "cifsproto.h" 28#include "cifsproto.h"
29#include "cifs_debug.h" 29#include "cifs_debug.h"
30 30
31
32#ifdef CONFIG_CIFS_EXPERIMENTAL
33
34struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
35 {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
36 {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
37 {{1, 1, {0, 0, 0, 0, 0, 5}, {11, 0, 0, 0, 0} }, "net-users"},
38 {{1, 1, {0, 0, 0, 0, 0, 5}, {18, 0, 0, 0, 0} }, "sys"},
39 {{1, 2, {0, 0, 0, 0, 0, 5}, {32, 544, 0, 0, 0} }, "root"},
40 {{1, 2, {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0, 0} }, "users"},
41 {{1, 2, {0, 0, 0, 0, 0, 5}, {32, 546, 0, 0, 0} }, "guest"}
42};
43
44
31/* security id for everyone */ 45/* security id for everyone */
32static const struct cifs_sid sid_everyone = 46static const struct cifs_sid sid_everyone =
33 {1, 1, {0, 0, 0, 0, 0, 0}, {} }; 47 {1, 1, {0, 0, 0, 0, 0, 0}, {} };
@@ -35,33 +49,113 @@ static const struct cifs_sid sid_everyone =
35static const struct cifs_sid sid_user = 49static const struct cifs_sid sid_user =
36 {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; 50 {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
37 51
52
53int match_sid(struct cifs_sid *ctsid)
54{
55 int i, j;
56 int num_subauth, num_sat, num_saw;
57 struct cifs_sid *cwsid;
58
59 if (!ctsid)
60 return (-1);
61
62 for (i = 0; i < NUM_WK_SIDS; ++i) {
63 cwsid = &(wksidarr[i].cifssid);
64
65 /* compare the revision */
66 if (ctsid->revision != cwsid->revision)
67 continue;
68
69 /* compare all of the six auth values */
70 for (j = 0; j < 6; ++j) {
71 if (ctsid->authority[j] != cwsid->authority[j])
72 break;
73 }
74 if (j < 6)
75 continue; /* all of the auth values did not match */
76
77 /* compare all of the subauth values if any */
78 num_sat = cpu_to_le32(ctsid->num_subauth);
79 num_saw = cpu_to_le32(cwsid->num_subauth);
80 num_subauth = num_sat < num_saw ? num_sat : num_saw;
81 if (num_subauth) {
82 for (j = 0; j < num_subauth; ++j) {
83 if (ctsid->sub_auth[j] != cwsid->sub_auth[j])
84 break;
85 }
86 if (j < num_subauth)
87 continue; /* all sub_auth values do not match */
88 }
89
90 cFYI(1, ("matching sid: %s\n", wksidarr[i].sidname));
91 return (0); /* sids compare/match */
92 }
93
94 cFYI(1, ("No matching sid"));
95 return (-1);
96}
97
98
99int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid)
100{
101 int i;
102 int num_subauth, num_sat, num_saw;
103
104 if ((!ctsid) || (!cwsid))
105 return (-1);
106
107 /* compare the revision */
108 if (ctsid->revision != cwsid->revision)
109 return (-1);
110
111 /* compare all of the six auth values */
112 for (i = 0; i < 6; ++i) {
113 if (ctsid->authority[i] != cwsid->authority[i])
114 return (-1);
115 }
116
117 /* compare all of the subauth values if any */
118 num_sat = cpu_to_le32(ctsid->num_subauth);
119 num_saw = cpu_to_le32(cwsid->num_subauth);
120 num_subauth = num_sat < num_saw ? num_sat : num_saw;
121 if (num_subauth) {
122 for (i = 0; i < num_subauth; ++i) {
123 if (ctsid->sub_auth[i] != cwsid->sub_auth[i])
124 return (-1);
125 }
126 }
127
128 return (0); /* sids compare/match */
129}
130
131
38static void parse_ace(struct cifs_ace *pace, char *end_of_acl) 132static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
39{ 133{
40 int i; 134 int i;
41 int num_subauth; 135 int num_subauth;
42 __u32 *psub_auth;
43 136
44 /* validate that we do not go past end of acl */ 137 /* validate that we do not go past end of acl */
138
139 /* XXX this if statement can be removed
45 if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) { 140 if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) {
46 cERROR(1, ("ACL too small to parse ACE")); 141 cERROR(1, ("ACL too small to parse ACE"));
47 return; 142 return;
48 } 143 } */
49 144
50 num_subauth = cpu_to_le32(pace->num_subauth); 145 num_subauth = cpu_to_le32(pace->num_subauth);
51 if (num_subauth) { 146 if (num_subauth) {
52 psub_auth = (__u32 *)((char *)pace + sizeof(struct cifs_ace));
53#ifdef CONFIG_CIFS_DEBUG2 147#ifdef CONFIG_CIFS_DEBUG2
54 cFYI(1, ("ACE revision %d num_subauth %d", 148 cFYI(1, ("ACE revision %d num_subauth %d",
55 pace->revision, pace->num_subauth)); 149 pace->revision, pace->num_subauth));
56 for (i = 0; i < num_subauth; ++i) { 150 for (i = 0; i < num_subauth; ++i) {
57 cFYI(1, ("ACE sub_auth[%d]: 0x%x", i, 151 cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
58 le32_to_cpu(psub_auth[i]))); 152 le32_to_cpu(pace->sub_auth[i])));
59 } 153 }
60 154
61 /* BB add length check to make sure that we do not have huge 155 /* BB add length check to make sure that we do not have huge
62 num auths and therefore go off the end */ 156 num auths and therefore go off the end */
63 157
64 cFYI(1, ("RID %d", le32_to_cpu(psub_auth[num_subauth-1]))); 158 cFYI(1, ("RID %d", le32_to_cpu(pace->sub_auth[num_subauth-1])));
65#endif 159#endif
66 } 160 }
67 161
@@ -132,7 +226,13 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl)
132 sizeof(struct cifs_ntace)); 226 sizeof(struct cifs_ntace));
133 227
134 parse_ntace(ppntace[i], end_of_acl); 228 parse_ntace(ppntace[i], end_of_acl);
135 parse_ace(ppace[i], end_of_acl); 229 if (end_of_acl < ((char *)ppace[i] +
230 (ppntace[i]->size -
231 sizeof(struct cifs_ntace)))) {
232 cERROR(1, ("ACL too small to parse ACE"));
233 break;
234 } else
235 parse_ace(ppace[i], end_of_acl);
136 236
137/* memcpy((void *)(&(cifscred->ntaces[i])), 237/* memcpy((void *)(&(cifscred->ntaces[i])),
138 (void *)ppntace[i], 238 (void *)ppntace[i],
@@ -157,7 +257,6 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
157{ 257{
158 int i; 258 int i;
159 int num_subauth; 259 int num_subauth;
160 __u32 *psub_auth;
161 260
162 /* BB need to add parm so we can store the SID BB */ 261 /* BB need to add parm so we can store the SID BB */
163 262
@@ -169,20 +268,19 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
169 268
170 num_subauth = cpu_to_le32(psid->num_subauth); 269 num_subauth = cpu_to_le32(psid->num_subauth);
171 if (num_subauth) { 270 if (num_subauth) {
172 psub_auth = (__u32 *)((char *)psid + sizeof(struct cifs_sid));
173#ifdef CONFIG_CIFS_DEBUG2 271#ifdef CONFIG_CIFS_DEBUG2
174 cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x", 272 cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x",
175 psid->revision, psid->num_subauth, psid->sub_auth[0])); 273 psid->revision, psid->num_subauth, psid->sub_auth[0]));
176 274
177 for (i = 0; i < num_subauth; ++i) { 275 for (i = 0; i < num_subauth; ++i) {
178 cFYI(1, ("SID sub_auth[%d]: 0x%x ", i, 276 cFYI(1, ("SID sub_auth[%d]: 0x%x ", i,
179 le32_to_cpu(psub_auth[i]))); 277 le32_to_cpu(psid->sub_auth[i])));
180 } 278 }
181 279
182 /* BB add length check to make sure that we do not have huge 280 /* BB add length check to make sure that we do not have huge
183 num auths and therefore go off the end */ 281 num auths and therefore go off the end */
184 cFYI(1, ("RID 0x%x", 282 cFYI(1, ("RID 0x%x",
185 le32_to_cpu(psid->sub_auth[psid->num_subauth]))); 283 le32_to_cpu(psid->sub_auth[num_subauth-1])));
186#endif 284#endif
187 } 285 }
188 286
@@ -228,5 +326,7 @@ int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
228 memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, 326 memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
229 sizeof (struct cifs_sid)); */ 327 sizeof (struct cifs_sid)); */
230 328
329
231 return (0); 330 return (0);
232} 331}
332#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index bf297ea1905a..1b115641b722 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -22,6 +22,10 @@
22#ifndef _CIFSACL_H 22#ifndef _CIFSACL_H
23#define _CIFSACL_H 23#define _CIFSACL_H
24 24
25
26#define NUM_WK_SIDS 7 /* number of well known sids */
27#define SIDNAMELENGTH 20 /* long enough for the ones we care about */
28
25struct cifs_ntsd { 29struct cifs_ntsd {
26 __u16 revision; /* revision level */ 30 __u16 revision; /* revision level */
27 __u16 type; 31 __u16 type;
@@ -35,7 +39,7 @@ struct cifs_sid {
35 __u8 revision; /* revision level */ 39 __u8 revision; /* revision level */
36 __u8 num_subauth; 40 __u8 num_subauth;
37 __u8 authority[6]; 41 __u8 authority[6];
38 __u32 sub_auth[0]; /* sub_auth[num_subauth] */ 42 __u32 sub_auth[5]; /* sub_auth[num_subauth] */
39} __attribute__((packed)); 43} __attribute__((packed));
40 44
41struct cifs_acl { 45struct cifs_acl {
@@ -55,12 +59,20 @@ struct cifs_ace { /* last part of ACE which includes user info */
55 __u8 revision; /* revision level */ 59 __u8 revision; /* revision level */
56 __u8 num_subauth; 60 __u8 num_subauth;
57 __u8 authority[6]; 61 __u8 authority[6];
58 __u32 sub_auth[0]; 62 __u32 sub_auth[5];
63} __attribute__((packed));
64
65struct cifs_wksid {
66 struct cifs_sid cifssid;
67 char sidname[SIDNAMELENGTH];
59} __attribute__((packed)); 68} __attribute__((packed));
60 69
61/* everyone */ 70#ifdef CONFIG_CIFS_EXPERIMENTAL
62/* extern const struct cifs_sid sid_everyone;*/ 71
63/* group users */ 72extern struct cifs_wksid wksidarr[NUM_WK_SIDS];
64/* extern const struct cifs_sid sid_user;*/ 73extern int match_sid(struct cifs_sid *);
74extern int compare_sids(struct cifs_sid *, struct cifs_sid *);
75
76#endif /* CONFIG_CIFS_EXPERIMENTAL */
65 77
66#endif /* _CIFSACL_H */ 78#endif /* _CIFSACL_H */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index c7c3521aa7cd..abca6b084ed1 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -49,10 +49,6 @@
49static struct quotactl_ops cifs_quotactl_ops; 49static struct quotactl_ops cifs_quotactl_ops;
50#endif /* QUOTA */ 50#endif /* QUOTA */
51 51
52#ifdef CONFIG_CIFS_EXPERIMENTAL
53extern struct export_operations cifs_export_ops;
54#endif /* EXPERIMENTAL */
55
56int cifsFYI = 0; 52int cifsFYI = 0;
57int cifsERROR = 1; 53int cifsERROR = 1;
58int traceSMB = 0; 54int traceSMB = 0;
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 13c53a4ee0f7..0a3ee5a322b0 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsfs.h 2 * fs/cifs/cifsfs.h
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2002, 2005 4 * Copyright (c) International Business Machines Corp., 2002, 2007
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -101,5 +101,10 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
101extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 101extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
102extern int cifs_ioctl(struct inode *inode, struct file *filep, 102extern int cifs_ioctl(struct inode *inode, struct file *filep,
103 unsigned int command, unsigned long arg); 103 unsigned int command, unsigned long arg);
104
105#ifdef CONFIG_CIFS_EXPERIMENTAL
106extern struct export_operations cifs_export_ops;
107#endif /* EXPERIMENTAL */
108
104#define CIFS_VERSION "1.51" 109#define CIFS_VERSION "1.51"
105#endif /* _CIFSFS_H */ 110#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index fda8b2490263..eff3226b2104 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -3058,6 +3058,7 @@ GetExtAttrOut:
3058 3058
3059#endif /* CONFIG_POSIX */ 3059#endif /* CONFIG_POSIX */
3060 3060
3061#ifdef CONFIG_CIFS_EXPERIMENTAL
3061/* Get Security Descriptor (by handle) from remote server for a file or dir */ 3062/* Get Security Descriptor (by handle) from remote server for a file or dir */
3062int 3063int
3063CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, 3064CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
@@ -3129,6 +3130,7 @@ qsec_out:
3129/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 3130/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3130 return rc; 3131 return rc;
3131} 3132}
3133#endif /* CONFIG_CIFS_EXPERIMENTAL */
3132 3134
3133/* Legacy Query Path Information call for lookup to old servers such 3135/* Legacy Query Path Information call for lookup to old servers such
3134 as Win9x/WinME */ 3136 as Win9x/WinME */
diff --git a/fs/cifs/export.c b/fs/cifs/export.c
index 893fd0aebff8..d614b91caeca 100644
--- a/fs/cifs/export.c
+++ b/fs/cifs/export.c
@@ -43,6 +43,7 @@
43#include <linux/exportfs.h> 43#include <linux/exportfs.h>
44#include "cifsglob.h" 44#include "cifsglob.h"
45#include "cifs_debug.h" 45#include "cifs_debug.h"
46#include "cifsfs.h"
46 47
47#ifdef CONFIG_CIFS_EXPERIMENTAL 48#ifdef CONFIG_CIFS_EXPERIMENTAL
48static struct dentry *cifs_get_parent(struct dentry *dentry) 49static struct dentry *cifs_get_parent(struct dentry *dentry)