Blame view

fs/cifs/cifsacl.c 20.8 KB
bcb020341   Steve French   [CIFS] move cifs ...
1
2
3
  /*
   *   fs/cifs/cifsacl.c
   *
8b1327f6e   Steve French   [CIFS] file creat...
4
   *   Copyright (C) International Business Machines  Corp., 2007,2008
bcb020341   Steve French   [CIFS] move cifs ...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   *   Author(s): Steve French (sfrench@us.ibm.com)
   *
   *   Contains the routines for mapping CIFS/NTFS ACLs
   *
   *   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
   */
65874007c   Steve French   [CIFS] fix cut an...
23
  #include <linux/fs.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
24
  #include <linux/slab.h>
65874007c   Steve French   [CIFS] fix cut an...
25
26
  #include "cifspdu.h"
  #include "cifsglob.h"
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
27
  #include "cifsacl.h"
65874007c   Steve French   [CIFS] fix cut an...
28
29
  #include "cifsproto.h"
  #include "cifs_debug.h"
65874007c   Steve French   [CIFS] fix cut an...
30

297647c21   Steve French   [CIFS] CIFS ACL s...
31
32
  
  #ifdef CONFIG_CIFS_EXPERIMENTAL
af6f4612f   Steve French   [CIFS] Fix some e...
33
  static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
297647c21   Steve French   [CIFS] CIFS ACL s...
34
35
  	{{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
  	{{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
536abdb08   Jeff Layton   cifs: fix wksidar...
36
37
38
39
40
  	{{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"},
  	{{1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(18), 0, 0, 0, 0} }, "sys"},
  	{{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(544), 0, 0, 0} }, "root"},
  	{{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(545), 0, 0, 0} }, "users"},
  	{{1, 2, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(32), __constant_cpu_to_le32(546), 0, 0, 0} }, "guest"} }
44093ca2f   Steve French   [CIFS] acl suppor...
41
  ;
297647c21   Steve French   [CIFS] CIFS ACL s...
42

bcb020341   Steve French   [CIFS] move cifs ...
43
  /* security id for everyone */
e01b64001   Shirish Pargaonkar   [CIFS] enable get...
44
45
  static const struct cifs_sid sid_everyone = {
  	1, 1, {0, 0, 0, 0, 0, 1}, {0} };
bcb020341   Steve French   [CIFS] move cifs ...
46
  /* group users */
ad7a2926b   Steve French   [CIFS] reduce che...
47
  static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
48

297647c21   Steve French   [CIFS] CIFS ACL s...
49
50
51
52
53
54
55
56
  
  int match_sid(struct cifs_sid *ctsid)
  {
  	int i, j;
  	int num_subauth, num_sat, num_saw;
  	struct cifs_sid *cwsid;
  
  	if (!ctsid)
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
57
  		return -1;
297647c21   Steve French   [CIFS] CIFS ACL s...
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
  
  	for (i = 0; i < NUM_WK_SIDS; ++i) {
  		cwsid = &(wksidarr[i].cifssid);
  
  		/* compare the revision */
  		if (ctsid->revision != cwsid->revision)
  			continue;
  
  		/* compare all of the six auth values */
  		for (j = 0; j < 6; ++j) {
  			if (ctsid->authority[j] != cwsid->authority[j])
  				break;
  		}
  		if (j < 6)
  			continue; /* all of the auth values did not match */
  
  		/* compare all of the subauth values if any */
ce51ae14a   Dave Kleikamp   [CIFS] endian fix...
75
76
  		num_sat = ctsid->num_subauth;
  		num_saw = cwsid->num_subauth;
297647c21   Steve French   [CIFS] CIFS ACL s...
77
78
79
80
81
82
83
84
85
  		num_subauth = num_sat < num_saw ? num_sat : num_saw;
  		if (num_subauth) {
  			for (j = 0; j < num_subauth; ++j) {
  				if (ctsid->sub_auth[j] != cwsid->sub_auth[j])
  					break;
  			}
  			if (j < num_subauth)
  				continue; /* all sub_auth values do not match */
  		}
b6b38f704   Joe Perches   [CIFS] Neaten cER...
86
87
  		cFYI(1, "matching sid: %s
  ", wksidarr[i].sidname);
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
88
  		return 0; /* sids compare/match */
297647c21   Steve French   [CIFS] CIFS ACL s...
89
  	}
b6b38f704   Joe Perches   [CIFS] Neaten cER...
90
  	cFYI(1, "No matching sid");
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
91
  	return -1;
297647c21   Steve French   [CIFS] CIFS ACL s...
92
  }
a750e77c2   Steve French   [CIFS] acl suppor...
93
94
  /* if the two SIDs (roughly equivalent to a UUID for a user or group) are
     the same returns 1, if they do not match returns 0 */
630f3f0c4   Steve French   [CIFS] acl suppor...
95
  int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
297647c21   Steve French   [CIFS] CIFS ACL s...
96
97
98
99
100
  {
  	int i;
  	int num_subauth, num_sat, num_saw;
  
  	if ((!ctsid) || (!cwsid))
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
101
  		return 0;
297647c21   Steve French   [CIFS] CIFS ACL s...
102
103
104
  
  	/* compare the revision */
  	if (ctsid->revision != cwsid->revision)
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
105
  		return 0;
297647c21   Steve French   [CIFS] CIFS ACL s...
106
107
108
109
  
  	/* compare all of the six auth values */
  	for (i = 0; i < 6; ++i) {
  		if (ctsid->authority[i] != cwsid->authority[i])
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
110
  			return 0;
297647c21   Steve French   [CIFS] CIFS ACL s...
111
112
113
  	}
  
  	/* compare all of the subauth values if any */
adbc03587   Steve French   [CIFS] endian fixes
114
  	num_sat = ctsid->num_subauth;
adddd49dd   Steve French   [CIFS] build break
115
  	num_saw = cwsid->num_subauth;
297647c21   Steve French   [CIFS] CIFS ACL s...
116
117
118
119
  	num_subauth = num_sat < num_saw ? num_sat : num_saw;
  	if (num_subauth) {
  		for (i = 0; i < num_subauth; ++i) {
  			if (ctsid->sub_auth[i] != cwsid->sub_auth[i])
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
120
  				return 0;
297647c21   Steve French   [CIFS] CIFS ACL s...
121
122
  		}
  	}
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
123
  	return 1; /* sids compare/match */
297647c21   Steve French   [CIFS] CIFS ACL s...
124
  }
97837582b   Steve French   [CIFS] Allow sett...
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  
  /* copy ntsd, owner sid, and group sid from a security descriptor to another */
  static void copy_sec_desc(const struct cifs_ntsd *pntsd,
  				struct cifs_ntsd *pnntsd, __u32 sidsoffset)
  {
  	int i;
  
  	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
  	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
  
  	/* copy security descriptor control portion */
  	pnntsd->revision = pntsd->revision;
  	pnntsd->type = pntsd->type;
  	pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
  	pnntsd->sacloffset = 0;
  	pnntsd->osidoffset = cpu_to_le32(sidsoffset);
  	pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
  
  	/* copy owner sid */
  	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
  				le32_to_cpu(pntsd->osidoffset));
  	nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
  
  	nowner_sid_ptr->revision = owner_sid_ptr->revision;
  	nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
  	for (i = 0; i < 6; i++)
  		nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
  	for (i = 0; i < 5; i++)
  		nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
  
  	/* copy group sid */
  	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
  				le32_to_cpu(pntsd->gsidoffset));
  	ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
  					sizeof(struct cifs_sid));
  
  	ngroup_sid_ptr->revision = group_sid_ptr->revision;
  	ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
  	for (i = 0; i < 6; i++)
  		ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
  	for (i = 0; i < 5; i++)
b1910ad62   Shirish Pargaonkar   [CIFS] Fix improp...
166
  		ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
97837582b   Steve French   [CIFS] Allow sett...
167
168
169
  
  	return;
  }
630f3f0c4   Steve French   [CIFS] acl suppor...
170
171
172
173
174
  /*
     change posix mode to reflect permissions
     pmode is the existing mode (we only want to overwrite part of this
     bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
  */
9b5e6857b   Al Viro   regression: cifs ...
175
  static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
15b039591   Steve French   [CIFS] Fix incorr...
176
  				 umode_t *pbits_to_set)
630f3f0c4   Steve French   [CIFS] acl suppor...
177
  {
9b5e6857b   Al Viro   regression: cifs ...
178
  	__u32 flags = le32_to_cpu(ace_flags);
15b039591   Steve French   [CIFS] Fix incorr...
179
  	/* the order of ACEs is important.  The canonical order is to begin with
ce06c9f02   Steve French   [CIFS] add mode t...
180
  	   DENY entries followed by ALLOW, otherwise an allow entry could be
15b039591   Steve French   [CIFS] Fix incorr...
181
  	   encountered first, making the subsequent deny entry like "dead code"
ce06c9f02   Steve French   [CIFS] add mode t...
182
  	   which would be superflous since Windows stops when a match is made
15b039591   Steve French   [CIFS] Fix incorr...
183
184
185
186
187
  	   for the operation you are trying to perform for your user */
  
  	/* For deny ACEs we change the mask so that subsequent allow access
  	   control entries do not turn on the bits we are denying */
  	if (type == ACCESS_DENIED) {
ad7a2926b   Steve French   [CIFS] reduce che...
188
  		if (flags & GENERIC_ALL)
15b039591   Steve French   [CIFS] Fix incorr...
189
  			*pbits_to_set &= ~S_IRWXUGO;
ad7a2926b   Steve French   [CIFS] reduce che...
190

9b5e6857b   Al Viro   regression: cifs ...
191
192
  		if ((flags & GENERIC_WRITE) ||
  			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
15b039591   Steve French   [CIFS] Fix incorr...
193
  			*pbits_to_set &= ~S_IWUGO;
9b5e6857b   Al Viro   regression: cifs ...
194
195
  		if ((flags & GENERIC_READ) ||
  			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
15b039591   Steve French   [CIFS] Fix incorr...
196
  			*pbits_to_set &= ~S_IRUGO;
9b5e6857b   Al Viro   regression: cifs ...
197
198
  		if ((flags & GENERIC_EXECUTE) ||
  			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
15b039591   Steve French   [CIFS] Fix incorr...
199
200
201
  			*pbits_to_set &= ~S_IXUGO;
  		return;
  	} else if (type != ACCESS_ALLOWED) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
202
  		cERROR(1, "unknown access control type %d", type);
15b039591   Steve French   [CIFS] Fix incorr...
203
204
205
  		return;
  	}
  	/* else ACCESS_ALLOWED type */
630f3f0c4   Steve French   [CIFS] acl suppor...
206

9b5e6857b   Al Viro   regression: cifs ...
207
  	if (flags & GENERIC_ALL) {
15b039591   Steve French   [CIFS] Fix incorr...
208
  		*pmode |= (S_IRWXUGO & (*pbits_to_set));
b6b38f704   Joe Perches   [CIFS] Neaten cER...
209
  		cFYI(DBG2, "all perms");
d61e5808d   Steve French   [CIFS] acl suppor...
210
211
  		return;
  	}
9b5e6857b   Al Viro   regression: cifs ...
212
213
  	if ((flags & GENERIC_WRITE) ||
  			((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
15b039591   Steve French   [CIFS] Fix incorr...
214
  		*pmode |= (S_IWUGO & (*pbits_to_set));
9b5e6857b   Al Viro   regression: cifs ...
215
216
  	if ((flags & GENERIC_READ) ||
  			((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
15b039591   Steve French   [CIFS] Fix incorr...
217
  		*pmode |= (S_IRUGO & (*pbits_to_set));
9b5e6857b   Al Viro   regression: cifs ...
218
219
  	if ((flags & GENERIC_EXECUTE) ||
  			((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
15b039591   Steve French   [CIFS] Fix incorr...
220
  		*pmode |= (S_IXUGO & (*pbits_to_set));
630f3f0c4   Steve French   [CIFS] acl suppor...
221

b6b38f704   Joe Perches   [CIFS] Neaten cER...
222
  	cFYI(DBG2, "access flags 0x%x mode now 0x%x", flags, *pmode);
630f3f0c4   Steve French   [CIFS] acl suppor...
223
224
  	return;
  }
ce06c9f02   Steve French   [CIFS] add mode t...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
  /*
     Generate access flags to reflect permissions mode is the existing mode.
     This function is called for every ACE in the DACL whose SID matches
     with either owner or group or everyone.
  */
  
  static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
  				__u32 *pace_flags)
  {
  	/* reset access mask */
  	*pace_flags = 0x0;
  
  	/* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
  	mode &= bits_to_use;
  
  	/* check for R/W/X UGO since we do not know whose flags
  	   is this but we have cleared all the bits sans RWX for
  	   either user or group or other as per bits_to_use */
  	if (mode & S_IRUGO)
  		*pace_flags |= SET_FILE_READ_RIGHTS;
  	if (mode & S_IWUGO)
  		*pace_flags |= SET_FILE_WRITE_RIGHTS;
  	if (mode & S_IXUGO)
  		*pace_flags |= SET_FILE_EXEC_RIGHTS;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
249
  	cFYI(DBG2, "mode: 0x%x, access flags now 0x%x", mode, *pace_flags);
ce06c9f02   Steve French   [CIFS] add mode t...
250
251
  	return;
  }
2b210adcb   Al Viro   cifs: fix misanno...
252
  static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
97837582b   Steve French   [CIFS] Allow sett...
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
  			const struct cifs_sid *psid, __u64 nmode, umode_t bits)
  {
  	int i;
  	__u16 size = 0;
  	__u32 access_req = 0;
  
  	pntace->type = ACCESS_ALLOWED;
  	pntace->flags = 0x0;
  	mode_to_access_flags(nmode, bits, &access_req);
  	if (!access_req)
  		access_req = SET_MINIMUM_RIGHTS;
  	pntace->access_req = cpu_to_le32(access_req);
  
  	pntace->sid.revision = psid->revision;
  	pntace->sid.num_subauth = psid->num_subauth;
  	for (i = 0; i < 6; i++)
  		pntace->sid.authority[i] = psid->authority[i];
  	for (i = 0; i < psid->num_subauth; i++)
  		pntace->sid.sub_auth[i] = psid->sub_auth[i];
  
  	size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
  	pntace->size = cpu_to_le16(size);
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
275
  	return size;
97837582b   Steve French   [CIFS] Allow sett...
276
  }
297647c21   Steve French   [CIFS] CIFS ACL s...
277

953f86813   Steve French   [CIFS] Don't requ...
278
279
  #ifdef CONFIG_CIFS_DEBUG2
  static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
280
  {
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
281
  	int num_subauth;
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
282
283
  
  	/* validate that we do not go past end of acl */
297647c21   Steve French   [CIFS] CIFS ACL s...
284

44093ca2f   Steve French   [CIFS] acl suppor...
285
  	if (le16_to_cpu(pace->size) < 16) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
286
  		cERROR(1, "ACE too small %d", le16_to_cpu(pace->size));
44093ca2f   Steve French   [CIFS] acl suppor...
287
288
289
290
  		return;
  	}
  
  	if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
291
  		cERROR(1, "ACL too small to parse ACE");
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
292
  		return;
44093ca2f   Steve French   [CIFS] acl suppor...
293
  	}
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
294

44093ca2f   Steve French   [CIFS] acl suppor...
295
  	num_subauth = pace->sid.num_subauth;
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
296
  	if (num_subauth) {
8f18c1316   Steve French   [CIFS] remove com...
297
  		int i;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
298
  		cFYI(1, "ACE revision %d num_auth %d type %d flags %d size %d",
44093ca2f   Steve French   [CIFS] acl suppor...
299
  			pace->sid.revision, pace->sid.num_subauth, pace->type,
b6b38f704   Joe Perches   [CIFS] Neaten cER...
300
  			pace->flags, le16_to_cpu(pace->size));
d12fd121a   Steve French   [CIFS] Cleanup fo...
301
  		for (i = 0; i < num_subauth; ++i) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
302
303
  			cFYI(1, "ACE sub_auth[%d]: 0x%x", i,
  				le32_to_cpu(pace->sid.sub_auth[i]));
d12fd121a   Steve French   [CIFS] Cleanup fo...
304
305
306
307
  		}
  
  		/* BB add length check to make sure that we do not have huge
  			num auths and therefore go off the end */
d12fd121a   Steve French   [CIFS] Cleanup fo...
308
309
310
311
  	}
  
  	return;
  }
953f86813   Steve French   [CIFS] Don't requ...
312
  #endif
d12fd121a   Steve French   [CIFS] Cleanup fo...
313

d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
314

a750e77c2   Steve French   [CIFS] acl suppor...
315
  static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
d61e5808d   Steve French   [CIFS] acl suppor...
316
  		       struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
0b8f18e35   Jeff Layton   cifs: convert cif...
317
  		       struct cifs_fattr *fattr)
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
318
319
320
321
322
  {
  	int i;
  	int num_aces = 0;
  	int acl_size;
  	char *acl_base;
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
323
324
325
  	struct cifs_ace **ppace;
  
  	/* BB need to add parm so we can store the SID BB */
2b83457bd   Steve French   [CIFS] Fix check ...
326
327
328
  	if (!pdacl) {
  		/* no DACL in the security descriptor, set
  		   all the permissions for user/group/other */
0b8f18e35   Jeff Layton   cifs: convert cif...
329
  		fattr->cf_mode |= S_IRWXUGO;
2b83457bd   Steve French   [CIFS] Fix check ...
330
331
  		return;
  	}
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
332
  	/* validate that we do not go past end of acl */
af6f4612f   Steve French   [CIFS] Fix some e...
333
  	if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
334
  		cERROR(1, "ACL too small to parse DACL");
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
335
336
  		return;
  	}
b6b38f704   Joe Perches   [CIFS] Neaten cER...
337
  	cFYI(DBG2, "DACL revision %d size %d num aces %d",
af6f4612f   Steve French   [CIFS] Fix some e...
338
  		le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
b6b38f704   Joe Perches   [CIFS] Neaten cER...
339
  		le32_to_cpu(pdacl->num_aces));
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
340

7505e0525   Steve French   [CIFS] If no Acce...
341
342
343
  	/* reset rwx permissions for user/group/other.
  	   Also, if num_aces is 0 i.e. DACL has no ACEs,
  	   user/group/other have no permissions */
0b8f18e35   Jeff Layton   cifs: convert cif...
344
  	fattr->cf_mode &= ~(S_IRWXUGO);
7505e0525   Steve French   [CIFS] If no Acce...
345

d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
346
347
  	acl_base = (char *)pdacl;
  	acl_size = sizeof(struct cifs_acl);
adbc03587   Steve French   [CIFS] endian fixes
348
  	num_aces = le32_to_cpu(pdacl->num_aces);
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
349
  	if (num_aces  > 0) {
15b039591   Steve French   [CIFS] Fix incorr...
350
351
352
  		umode_t user_mask = S_IRWXU;
  		umode_t group_mask = S_IRWXG;
  		umode_t other_mask = S_IRWXO;
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
353
354
  		ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
  				GFP_KERNEL);
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
355
  		for (i = 0; i < num_aces; ++i) {
44093ca2f   Steve French   [CIFS] acl suppor...
356
  			ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
953f86813   Steve French   [CIFS] Don't requ...
357
358
359
  #ifdef CONFIG_CIFS_DEBUG2
  			dump_ace(ppace[i], end_of_acl);
  #endif
e01b64001   Shirish Pargaonkar   [CIFS] enable get...
360
361
  			if (compare_sids(&(ppace[i]->sid), pownersid))
  				access_flags_to_mode(ppace[i]->access_req,
15b039591   Steve French   [CIFS] Fix incorr...
362
  						     ppace[i]->type,
0b8f18e35   Jeff Layton   cifs: convert cif...
363
  						     &fattr->cf_mode,
15b039591   Steve French   [CIFS] Fix incorr...
364
  						     &user_mask);
e01b64001   Shirish Pargaonkar   [CIFS] enable get...
365
366
  			if (compare_sids(&(ppace[i]->sid), pgrpsid))
  				access_flags_to_mode(ppace[i]->access_req,
15b039591   Steve French   [CIFS] Fix incorr...
367
  						     ppace[i]->type,
0b8f18e35   Jeff Layton   cifs: convert cif...
368
  						     &fattr->cf_mode,
15b039591   Steve French   [CIFS] Fix incorr...
369
  						     &group_mask);
e01b64001   Shirish Pargaonkar   [CIFS] enable get...
370
371
  			if (compare_sids(&(ppace[i]->sid), &sid_everyone))
  				access_flags_to_mode(ppace[i]->access_req,
15b039591   Steve French   [CIFS] Fix incorr...
372
  						     ppace[i]->type,
0b8f18e35   Jeff Layton   cifs: convert cif...
373
  						     &fattr->cf_mode,
15b039591   Steve French   [CIFS] Fix incorr...
374
  						     &other_mask);
e01b64001   Shirish Pargaonkar   [CIFS] enable get...
375

44093ca2f   Steve French   [CIFS] acl suppor...
376
  /*			memcpy((void *)(&(cifscred->aces[i])),
d12fd121a   Steve French   [CIFS] Cleanup fo...
377
378
  				(void *)ppace[i],
  				sizeof(struct cifs_ace)); */
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
379

44093ca2f   Steve French   [CIFS] acl suppor...
380
381
  			acl_base = (char *)ppace[i];
  			acl_size = le16_to_cpu(ppace[i]->size);
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
382
383
384
  		}
  
  		kfree(ppace);
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
385
386
387
388
  	}
  
  	return;
  }
bcb020341   Steve French   [CIFS] move cifs ...
389

97837582b   Steve French   [CIFS] Allow sett...
390
391
392
  static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
  			struct cifs_sid *pgrpsid, __u64 nmode)
  {
2b210adcb   Al Viro   cifs: fix misanno...
393
  	u16 size = 0;
97837582b   Steve French   [CIFS] Allow sett...
394
395
396
397
398
399
400
401
402
403
404
405
  	struct cifs_acl *pnndacl;
  
  	pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
  
  	size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
  					pownersid, nmode, S_IRWXU);
  	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
  					pgrpsid, nmode, S_IRWXG);
  	size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
  					 &sid_everyone, nmode, S_IRWXO);
  
  	pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
d9f382eff   Shirish Pargaonkar   [CIFS] patch to f...
406
  	pndacl->num_aces = cpu_to_le32(3);
97837582b   Steve French   [CIFS] Allow sett...
407

ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
408
  	return 0;
97837582b   Steve French   [CIFS] Allow sett...
409
  }
bcb020341   Steve French   [CIFS] move cifs ...
410
411
412
  static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
  {
  	/* BB need to add parm so we can store the SID BB */
b9c7a2bb1   Steve French   [CIFS] ACL suppor...
413
414
415
  	/* validate that we do not go past end of ACL - sid must be at least 8
  	   bytes long (assuming no sub-auths - e.g. the null SID */
  	if (end_of_acl < (char *)psid + 8) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
416
  		cERROR(1, "ACL too small to parse SID %p", psid);
bcb020341   Steve French   [CIFS] move cifs ...
417
418
  		return -EINVAL;
  	}
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
419

af6f4612f   Steve French   [CIFS] Fix some e...
420
  	if (psid->num_subauth) {
bcb020341   Steve French   [CIFS] move cifs ...
421
  #ifdef CONFIG_CIFS_DEBUG2
8f18c1316   Steve French   [CIFS] remove com...
422
  		int i;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
423
424
  		cFYI(1, "SID revision %d num_auth %d",
  			psid->revision, psid->num_subauth);
bcb020341   Steve French   [CIFS] move cifs ...
425

af6f4612f   Steve French   [CIFS] Fix some e...
426
  		for (i = 0; i < psid->num_subauth; i++) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
427
428
  			cFYI(1, "SID sub_auth[%d]: 0x%x ", i,
  				le32_to_cpu(psid->sub_auth[i]));
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
429
  		}
d12fd121a   Steve French   [CIFS] Cleanup fo...
430
  		/* BB add length check to make sure that we do not have huge
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
431
  			num auths and therefore go off the end */
b6b38f704   Joe Perches   [CIFS] Neaten cER...
432
433
  		cFYI(1, "RID 0x%x",
  			le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
bcb020341   Steve French   [CIFS] move cifs ...
434
  #endif
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
435
  	}
bcb020341   Steve French   [CIFS] move cifs ...
436
437
  	return 0;
  }
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
438

bcb020341   Steve French   [CIFS] move cifs ...
439
  /* Convert CIFS ACL to POSIX form */
630f3f0c4   Steve French   [CIFS] acl suppor...
440
  static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
0b8f18e35   Jeff Layton   cifs: convert cif...
441
  			  struct cifs_fattr *fattr)
bcb020341   Steve French   [CIFS] move cifs ...
442
  {
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
443
  	int rc;
bcb020341   Steve French   [CIFS] move cifs ...
444
445
  	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
  	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
bcb020341   Steve French   [CIFS] move cifs ...
446
  	char *end_of_acl = ((char *)pntsd) + acl_len;
7505e0525   Steve French   [CIFS] If no Acce...
447
  	__u32 dacloffset;
bcb020341   Steve French   [CIFS] move cifs ...
448

0b8f18e35   Jeff Layton   cifs: convert cif...
449
  	if (pntsd == NULL)
b9c7a2bb1   Steve French   [CIFS] ACL suppor...
450
  		return -EIO;
bcb020341   Steve French   [CIFS] move cifs ...
451
  	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
af6f4612f   Steve French   [CIFS] Fix some e...
452
  				le32_to_cpu(pntsd->osidoffset));
bcb020341   Steve French   [CIFS] move cifs ...
453
  	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
af6f4612f   Steve French   [CIFS] Fix some e...
454
  				le32_to_cpu(pntsd->gsidoffset));
7505e0525   Steve French   [CIFS] If no Acce...
455
  	dacloffset = le32_to_cpu(pntsd->dacloffset);
63d2583f5   Steve French   [CIFS] Fix walkin...
456
  	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
b6b38f704   Joe Perches   [CIFS] Neaten cER...
457
  	cFYI(DBG2, "revision %d type 0x%x ooffset 0x%x goffset 0x%x "
bcb020341   Steve French   [CIFS] move cifs ...
458
  		 "sacloffset 0x%x dacloffset 0x%x",
af6f4612f   Steve French   [CIFS] Fix some e...
459
460
  		 pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
  		 le32_to_cpu(pntsd->gsidoffset),
b6b38f704   Joe Perches   [CIFS] Neaten cER...
461
  		 le32_to_cpu(pntsd->sacloffset), dacloffset);
b9c7a2bb1   Steve French   [CIFS] ACL suppor...
462
  /*	cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
bcb020341   Steve French   [CIFS] move cifs ...
463
464
465
466
467
468
469
  	rc = parse_sid(owner_sid_ptr, end_of_acl);
  	if (rc)
  		return rc;
  
  	rc = parse_sid(group_sid_ptr, end_of_acl);
  	if (rc)
  		return rc;
7505e0525   Steve French   [CIFS] If no Acce...
470
471
  	if (dacloffset)
  		parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
0b8f18e35   Jeff Layton   cifs: convert cif...
472
  			   group_sid_ptr, fattr);
7505e0525   Steve French   [CIFS] If no Acce...
473
  	else
b6b38f704   Joe Perches   [CIFS] Neaten cER...
474
  		cFYI(1, "no ACL"); /* BB grant all or default perms? */
d0d66c443   Shirish Pargaonkar   [CIFS] CIFS ACL s...
475

bcb020341   Steve French   [CIFS] move cifs ...
476
477
478
  /*	cifscred->uid = owner_sid_ptr->rid;
  	cifscred->gid = group_sid_ptr->rid;
  	memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr,
630f3f0c4   Steve French   [CIFS] acl suppor...
479
  			sizeof(struct cifs_sid));
bcb020341   Steve French   [CIFS] move cifs ...
480
  	memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
630f3f0c4   Steve French   [CIFS] acl suppor...
481
  			sizeof(struct cifs_sid)); */
bcb020341   Steve French   [CIFS] move cifs ...
482

ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
483
  	return 0;
bcb020341   Steve French   [CIFS] move cifs ...
484
  }
b9c7a2bb1   Steve French   [CIFS] ACL suppor...
485

97837582b   Steve French   [CIFS] Allow sett...
486
487
  /* Convert permission bits from mode to equivalent CIFS ACL */
  static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
cce246ee5   Steve French   [CIFS] Fix acl le...
488
  				struct inode *inode, __u64 nmode)
97837582b   Steve French   [CIFS] Allow sett...
489
490
491
492
493
494
495
496
497
498
  {
  	int rc = 0;
  	__u32 dacloffset;
  	__u32 ndacloffset;
  	__u32 sidsoffset;
  	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
  	struct cifs_acl *dacl_ptr = NULL;  /* no need for SACL ptr */
  	struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
  
  	if ((inode == NULL) || (pntsd == NULL) || (pnntsd == NULL))
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
499
  		return -EIO;
97837582b   Steve French   [CIFS] Allow sett...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
  
  	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
  				le32_to_cpu(pntsd->osidoffset));
  	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
  				le32_to_cpu(pntsd->gsidoffset));
  
  	dacloffset = le32_to_cpu(pntsd->dacloffset);
  	dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
  
  	ndacloffset = sizeof(struct cifs_ntsd);
  	ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
  	ndacl_ptr->revision = dacl_ptr->revision;
  	ndacl_ptr->size = 0;
  	ndacl_ptr->num_aces = 0;
  
  	rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr, nmode);
  
  	sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
  
  	/* copy security descriptor control portion and owner and group sid */
  	copy_sec_desc(pntsd, pnntsd, sidsoffset);
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
521
  	return rc;
97837582b   Steve French   [CIFS] Allow sett...
522
  }
1bf4072da   Christoph Hellwig   cifs: reorganize ...
523
524
  static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
  		__u16 fid, u32 *pacllen)
b9c7a2bb1   Steve French   [CIFS] ACL suppor...
525
  {
b9c7a2bb1   Steve French   [CIFS] ACL suppor...
526
  	struct cifs_ntsd *pntsd = NULL;
1bf4072da   Christoph Hellwig   cifs: reorganize ...
527
  	int xid, rc;
b9c7a2bb1   Steve French   [CIFS] ACL suppor...
528

1bf4072da   Christoph Hellwig   cifs: reorganize ...
529
530
531
  	xid = GetXid();
  	rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
  	FreeXid(xid);
b9c7a2bb1   Steve French   [CIFS] ACL suppor...
532

b9c7a2bb1   Steve French   [CIFS] ACL suppor...
533

b6b38f704   Joe Perches   [CIFS] Neaten cER...
534
  	cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
1bf4072da   Christoph Hellwig   cifs: reorganize ...
535
536
  	return pntsd;
  }
8b1327f6e   Steve French   [CIFS] file creat...
537

1bf4072da   Christoph Hellwig   cifs: reorganize ...
538
539
540
541
542
543
544
  static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
  		const char *path, u32 *pacllen)
  {
  	struct cifs_ntsd *pntsd = NULL;
  	int oplock = 0;
  	int xid, rc;
  	__u16 fid;
b9c7a2bb1   Steve French   [CIFS] ACL suppor...
545

1bf4072da   Christoph Hellwig   cifs: reorganize ...
546
547
548
549
550
551
  	xid = GetXid();
  
  	rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, READ_CONTROL, 0,
  			 &fid, &oplock, NULL, cifs_sb->local_nls,
  			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
  	if (rc) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
552
  		cERROR(1, "Unable to open file to get ACL");
1bf4072da   Christoph Hellwig   cifs: reorganize ...
553
  		goto out;
b9c7a2bb1   Steve French   [CIFS] ACL suppor...
554
  	}
7505e0525   Steve French   [CIFS] If no Acce...
555
  	rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
b6b38f704   Joe Perches   [CIFS] Neaten cER...
556
  	cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
b9c7a2bb1   Steve French   [CIFS] ACL suppor...
557

1bf4072da   Christoph Hellwig   cifs: reorganize ...
558
559
  	CIFSSMBClose(xid, cifs_sb->tcon, fid);
   out:
7505e0525   Steve French   [CIFS] If no Acce...
560
561
562
  	FreeXid(xid);
  	return pntsd;
  }
1bf4072da   Christoph Hellwig   cifs: reorganize ...
563
564
565
566
567
568
569
570
571
572
573
574
575
576
  /* Retrieve an ACL from the server */
  static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
  				      struct inode *inode, const char *path,
  				      u32 *pacllen)
  {
  	struct cifs_ntsd *pntsd = NULL;
  	struct cifsFileInfo *open_file = NULL;
  
  	if (inode)
  		open_file = find_readable_file(CIFS_I(inode));
  	if (!open_file)
  		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
  
  	pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen);
6ab409b53   Dave Kleikamp   cifs: Replace wrt...
577
  	cifsFileInfo_put(open_file);
1bf4072da   Christoph Hellwig   cifs: reorganize ...
578
579
  	return pntsd;
  }
b96d31a62   Christoph Hellwig   cifs: clean up se...
580
581
  static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid,
  		struct cifs_ntsd *pnntsd, u32 acllen)
97837582b   Steve French   [CIFS] Allow sett...
582
  {
b96d31a62   Christoph Hellwig   cifs: clean up se...
583
  	int xid, rc;
97837582b   Steve French   [CIFS] Allow sett...
584

b96d31a62   Christoph Hellwig   cifs: clean up se...
585
586
587
  	xid = GetXid();
  	rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
  	FreeXid(xid);
97837582b   Steve French   [CIFS] Allow sett...
588

b6b38f704   Joe Perches   [CIFS] Neaten cER...
589
  	cFYI(DBG2, "SetCIFSACL rc = %d", rc);
b96d31a62   Christoph Hellwig   cifs: clean up se...
590
591
  	return rc;
  }
97837582b   Steve French   [CIFS] Allow sett...
592

b96d31a62   Christoph Hellwig   cifs: clean up se...
593
594
595
596
597
598
  static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
  		struct cifs_ntsd *pnntsd, u32 acllen)
  {
  	int oplock = 0;
  	int xid, rc;
  	__u16 fid;
97837582b   Steve French   [CIFS] Allow sett...
599

97837582b   Steve French   [CIFS] Allow sett...
600
  	xid = GetXid();
b96d31a62   Christoph Hellwig   cifs: clean up se...
601
602
603
604
  	rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, WRITE_DAC, 0,
  			 &fid, &oplock, NULL, cifs_sb->local_nls,
  			 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
  	if (rc) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
605
  		cERROR(1, "Unable to open file to set ACL");
b96d31a62   Christoph Hellwig   cifs: clean up se...
606
  		goto out;
97837582b   Steve French   [CIFS] Allow sett...
607
608
609
  	}
  
  	rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
b6b38f704   Joe Perches   [CIFS] Neaten cER...
610
  	cFYI(DBG2, "SetCIFSACL rc = %d", rc);
97837582b   Steve French   [CIFS] Allow sett...
611

b96d31a62   Christoph Hellwig   cifs: clean up se...
612
613
  	CIFSSMBClose(xid, cifs_sb->tcon, fid);
   out:
97837582b   Steve French   [CIFS] Allow sett...
614
  	FreeXid(xid);
b96d31a62   Christoph Hellwig   cifs: clean up se...
615
616
  	return rc;
  }
97837582b   Steve French   [CIFS] Allow sett...
617

b96d31a62   Christoph Hellwig   cifs: clean up se...
618
619
620
621
622
623
624
  /* Set an ACL on the server */
  static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
  				struct inode *inode, const char *path)
  {
  	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
  	struct cifsFileInfo *open_file;
  	int rc;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
625
  	cFYI(DBG2, "set ACL for %s from mode 0x%x", path, inode->i_mode);
b96d31a62   Christoph Hellwig   cifs: clean up se...
626
627
628
629
630
631
  
  	open_file = find_readable_file(CIFS_I(inode));
  	if (!open_file)
  		return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen);
  
  	rc = set_cifs_acl_by_fid(cifs_sb, open_file->netfid, pnntsd, acllen);
6ab409b53   Dave Kleikamp   cifs: Replace wrt...
632
  	cifsFileInfo_put(open_file);
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
633
  	return rc;
97837582b   Steve French   [CIFS] Allow sett...
634
  }
7505e0525   Steve French   [CIFS] If no Acce...
635
  /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
0b8f18e35   Jeff Layton   cifs: convert cif...
636
637
638
  void
  cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
  		  struct inode *inode, const char *path, const __u16 *pfid)
7505e0525   Steve French   [CIFS] If no Acce...
639
640
641
642
  {
  	struct cifs_ntsd *pntsd = NULL;
  	u32 acllen = 0;
  	int rc = 0;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
643
  	cFYI(DBG2, "converting ACL to mode for %s", path);
1bf4072da   Christoph Hellwig   cifs: reorganize ...
644
645
646
647
648
  
  	if (pfid)
  		pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
  	else
  		pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
7505e0525   Steve French   [CIFS] If no Acce...
649
650
651
  
  	/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
  	if (pntsd)
0b8f18e35   Jeff Layton   cifs: convert cif...
652
  		rc = parse_sec_desc(pntsd, acllen, fattr);
7505e0525   Steve French   [CIFS] If no Acce...
653
  	if (rc)
b6b38f704   Joe Perches   [CIFS] Neaten cER...
654
  		cFYI(1, "parse sec desc failed rc = %d", rc);
7505e0525   Steve French   [CIFS] If no Acce...
655

b9c7a2bb1   Steve French   [CIFS] ACL suppor...
656
  	kfree(pntsd);
b9c7a2bb1   Steve French   [CIFS] ACL suppor...
657
658
  	return;
  }
953f86813   Steve French   [CIFS] Don't requ...
659

7505e0525   Steve French   [CIFS] If no Acce...
660
  /* Convert mode bits to an ACL so we can update the ACL on the server */
97837582b   Steve French   [CIFS] Allow sett...
661
  int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
953f86813   Steve French   [CIFS] Don't requ...
662
663
  {
  	int rc = 0;
cce246ee5   Steve French   [CIFS] Fix acl le...
664
  	__u32 secdesclen = 0;
97837582b   Steve French   [CIFS] Allow sett...
665
666
  	struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
  	struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
953f86813   Steve French   [CIFS] Don't requ...
667

b6b38f704   Joe Perches   [CIFS] Neaten cER...
668
  	cFYI(DBG2, "set ACL from mode for %s", path);
953f86813   Steve French   [CIFS] Don't requ...
669
670
  
  	/* Get the security descriptor */
1bf4072da   Christoph Hellwig   cifs: reorganize ...
671
  	pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
953f86813   Steve French   [CIFS] Don't requ...
672

97837582b   Steve French   [CIFS] Allow sett...
673
674
  	/* Add three ACEs for owner, group, everyone getting rid of
  	   other ACEs as chmod disables ACEs and set the security descriptor */
953f86813   Steve French   [CIFS] Don't requ...
675

97837582b   Steve French   [CIFS] Allow sett...
676
677
678
679
  	if (pntsd) {
  		/* allocate memory for the smb header,
  		   set security descriptor request security descriptor
  		   parameters, and secuirty descriptor itself */
953f86813   Steve French   [CIFS] Don't requ...
680

cce246ee5   Steve French   [CIFS] Fix acl le...
681
682
683
  		secdesclen = secdesclen < DEFSECDESCLEN ?
  					DEFSECDESCLEN : secdesclen;
  		pnntsd = kmalloc(secdesclen, GFP_KERNEL);
97837582b   Steve French   [CIFS] Allow sett...
684
  		if (!pnntsd) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
685
  			cERROR(1, "Unable to allocate security descriptor");
97837582b   Steve French   [CIFS] Allow sett...
686
  			kfree(pntsd);
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
687
  			return -ENOMEM;
97837582b   Steve French   [CIFS] Allow sett...
688
  		}
7505e0525   Steve French   [CIFS] If no Acce...
689

cce246ee5   Steve French   [CIFS] Fix acl le...
690
  		rc = build_sec_desc(pntsd, pnntsd, inode, nmode);
97837582b   Steve French   [CIFS] Allow sett...
691

b6b38f704   Joe Perches   [CIFS] Neaten cER...
692
  		cFYI(DBG2, "build_sec_desc rc: %d", rc);
97837582b   Steve French   [CIFS] Allow sett...
693
694
695
  
  		if (!rc) {
  			/* Set the security descriptor */
cce246ee5   Steve French   [CIFS] Fix acl le...
696
  			rc = set_cifs_acl(pnntsd, secdesclen, inode, path);
b6b38f704   Joe Perches   [CIFS] Neaten cER...
697
  			cFYI(DBG2, "set_cifs_acl rc: %d", rc);
97837582b   Steve French   [CIFS] Allow sett...
698
699
700
701
702
  		}
  
  		kfree(pnntsd);
  		kfree(pntsd);
  	}
ef571cadd   Shirish Pargaonkar   [CIFS] Fix warnin...
703
  	return rc;
953f86813   Steve French   [CIFS] Don't requ...
704
  }
297647c21   Steve French   [CIFS] CIFS ACL s...
705
  #endif /* CONFIG_CIFS_EXPERIMENTAL */