Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cifsacl.c
Go to the documentation of this file.
1 /*
2  * fs/cifs/cifsacl.c
3  *
4  * Copyright (C) International Business Machines Corp., 2007,2008
5  * Author(s): Steve French ([email protected])
6  *
7  * Contains the routines for mapping CIFS/NTFS ACLs
8  *
9  * This library is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as published
11  * by the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17  * the GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23 
24 #include <linux/fs.h>
25 #include <linux/slab.h>
26 #include <linux/string.h>
27 #include <linux/keyctl.h>
28 #include <linux/key-type.h>
29 #include <keys/user-type.h>
30 #include "cifspdu.h"
31 #include "cifsglob.h"
32 #include "cifsacl.h"
33 #include "cifsproto.h"
34 #include "cifs_debug.h"
35 
36 /* security id for everyone/world system group */
37 static const struct cifs_sid sid_everyone = {
38  1, 1, {0, 0, 0, 0, 0, 1}, {0} };
39 /* security id for Authenticated Users system group */
40 static const struct cifs_sid sid_authusers = {
41  1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(11)} };
42 /* group users */
43 static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
44 
45 const struct cred *root_cred;
46 
47 static void
48 shrink_idmap_tree(struct rb_root *root, int nr_to_scan, int *nr_rem,
49  int *nr_del)
50 {
51  struct rb_node *node;
52  struct rb_node *tmp;
53  struct cifs_sid_id *psidid;
54 
55  node = rb_first(root);
56  while (node) {
57  tmp = node;
58  node = rb_next(tmp);
59  psidid = rb_entry(tmp, struct cifs_sid_id, rbnode);
60  if (nr_to_scan == 0 || *nr_del == nr_to_scan)
61  ++(*nr_rem);
62  else {
63  if (time_after(jiffies, psidid->time + SID_MAP_EXPIRE)
64  && psidid->refcount == 0) {
65  rb_erase(tmp, root);
66  ++(*nr_del);
67  } else
68  ++(*nr_rem);
69  }
70  }
71 }
72 
73 /*
74  * Run idmap cache shrinker.
75  */
76 static int
77 cifs_idmap_shrinker(struct shrinker *shrink, struct shrink_control *sc)
78 {
79  int nr_to_scan = sc->nr_to_scan;
80  int nr_del = 0;
81  int nr_rem = 0;
82  struct rb_root *root;
83 
84  root = &uidtree;
85  spin_lock(&siduidlock);
86  shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
87  spin_unlock(&siduidlock);
88 
89  root = &gidtree;
90  spin_lock(&sidgidlock);
91  shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
92  spin_unlock(&sidgidlock);
93 
94  root = &siduidtree;
95  spin_lock(&uidsidlock);
96  shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
97  spin_unlock(&uidsidlock);
98 
99  root = &sidgidtree;
100  spin_lock(&gidsidlock);
101  shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
102  spin_unlock(&gidsidlock);
103 
104  return nr_rem;
105 }
106 
107 static void
108 sid_rb_insert(struct rb_root *root, unsigned long cid,
109  struct cifs_sid_id **psidid, char *typestr)
110 {
111  char *strptr;
112  struct rb_node *node = root->rb_node;
113  struct rb_node *parent = NULL;
114  struct rb_node **linkto = &(root->rb_node);
115  struct cifs_sid_id *lsidid;
116 
117  while (node) {
118  lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
119  parent = node;
120  if (cid > lsidid->id) {
121  linkto = &(node->rb_left);
122  node = node->rb_left;
123  }
124  if (cid < lsidid->id) {
125  linkto = &(node->rb_right);
126  node = node->rb_right;
127  }
128  }
129 
130  (*psidid)->id = cid;
131  (*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
132  (*psidid)->refcount = 0;
133 
134  sprintf((*psidid)->sidstr, "%s", typestr);
135  strptr = (*psidid)->sidstr + strlen((*psidid)->sidstr);
136  sprintf(strptr, "%ld", cid);
137 
138  clear_bit(SID_ID_PENDING, &(*psidid)->state);
139  clear_bit(SID_ID_MAPPED, &(*psidid)->state);
140 
141  rb_link_node(&(*psidid)->rbnode, parent, linkto);
142  rb_insert_color(&(*psidid)->rbnode, root);
143 }
144 
145 static struct cifs_sid_id *
146 sid_rb_search(struct rb_root *root, unsigned long cid)
147 {
148  struct rb_node *node = root->rb_node;
149  struct cifs_sid_id *lsidid;
150 
151  while (node) {
152  lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
153  if (cid > lsidid->id)
154  node = node->rb_left;
155  else if (cid < lsidid->id)
156  node = node->rb_right;
157  else /* node found */
158  return lsidid;
159  }
160 
161  return NULL;
162 }
163 
164 static struct shrinker cifs_shrinker = {
165  .shrink = cifs_idmap_shrinker,
166  .seeks = DEFAULT_SEEKS,
167 };
168 
169 static int
170 cifs_idmap_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
171 {
172  char *payload;
173 
174  payload = kmalloc(prep->datalen, GFP_KERNEL);
175  if (!payload)
176  return -ENOMEM;
177 
178  memcpy(payload, prep->data, prep->datalen);
179  key->payload.data = payload;
180  key->datalen = prep->datalen;
181  return 0;
182 }
183 
184 static inline void
185 cifs_idmap_key_destroy(struct key *key)
186 {
187  kfree(key->payload.data);
188 }
189 
190 struct key_type cifs_idmap_key_type = {
191  .name = "cifs.idmap",
192  .instantiate = cifs_idmap_key_instantiate,
193  .destroy = cifs_idmap_key_destroy,
194  .describe = user_describe,
195  .match = user_match,
196 };
197 
198 static void
199 sid_to_str(struct cifs_sid *sidptr, char *sidstr)
200 {
201  int i;
202  unsigned long saval;
203  char *strptr;
204 
205  strptr = sidstr;
206 
207  sprintf(strptr, "%s", "S");
208  strptr = sidstr + strlen(sidstr);
209 
210  sprintf(strptr, "-%d", sidptr->revision);
211  strptr = sidstr + strlen(sidstr);
212 
213  for (i = 0; i < 6; ++i) {
214  if (sidptr->authority[i]) {
215  sprintf(strptr, "-%d", sidptr->authority[i]);
216  strptr = sidstr + strlen(sidstr);
217  }
218  }
219 
220  for (i = 0; i < sidptr->num_subauth; ++i) {
221  saval = le32_to_cpu(sidptr->sub_auth[i]);
222  sprintf(strptr, "-%ld", saval);
223  strptr = sidstr + strlen(sidstr);
224  }
225 }
226 
227 static void
228 cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
229 {
230  memcpy(dst, src, sizeof(*dst));
232 }
233 
234 static void
235 id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
236  struct cifs_sid_id **psidid, char *typestr)
237 {
238  int rc;
239  char *strptr;
240  struct rb_node *node = root->rb_node;
241  struct rb_node *parent = NULL;
242  struct rb_node **linkto = &(root->rb_node);
243  struct cifs_sid_id *lsidid;
244 
245  while (node) {
246  lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
247  parent = node;
248  rc = compare_sids(sidptr, &((lsidid)->sid));
249  if (rc > 0) {
250  linkto = &(node->rb_left);
251  node = node->rb_left;
252  } else if (rc < 0) {
253  linkto = &(node->rb_right);
254  node = node->rb_right;
255  }
256  }
257 
258  cifs_copy_sid(&(*psidid)->sid, sidptr);
259  (*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
260  (*psidid)->refcount = 0;
261 
262  sprintf((*psidid)->sidstr, "%s", typestr);
263  strptr = (*psidid)->sidstr + strlen((*psidid)->sidstr);
264  sid_to_str(&(*psidid)->sid, strptr);
265 
266  clear_bit(SID_ID_PENDING, &(*psidid)->state);
267  clear_bit(SID_ID_MAPPED, &(*psidid)->state);
268 
269  rb_link_node(&(*psidid)->rbnode, parent, linkto);
270  rb_insert_color(&(*psidid)->rbnode, root);
271 }
272 
273 static struct cifs_sid_id *
274 id_rb_search(struct rb_root *root, struct cifs_sid *sidptr)
275 {
276  int rc;
277  struct rb_node *node = root->rb_node;
278  struct cifs_sid_id *lsidid;
279 
280  while (node) {
281  lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
282  rc = compare_sids(sidptr, &((lsidid)->sid));
283  if (rc > 0) {
284  node = node->rb_left;
285  } else if (rc < 0) {
286  node = node->rb_right;
287  } else /* node found */
288  return lsidid;
289  }
290 
291  return NULL;
292 }
293 
294 static int
295 sidid_pending_wait(void *unused)
296 {
297  schedule();
298  return signal_pending(current) ? -ERESTARTSYS : 0;
299 }
300 
301 static int
302 id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
303 {
304  int rc = 0;
305  struct key *sidkey;
306  const struct cred *saved_cred;
307  struct cifs_sid *lsid;
308  struct cifs_sid_id *psidid, *npsidid;
309  struct rb_root *cidtree;
310  spinlock_t *cidlock;
311 
312  if (sidtype == SIDOWNER) {
313  cidlock = &siduidlock;
314  cidtree = &uidtree;
315  } else if (sidtype == SIDGROUP) {
316  cidlock = &sidgidlock;
317  cidtree = &gidtree;
318  } else
319  return -EINVAL;
320 
321  spin_lock(cidlock);
322  psidid = sid_rb_search(cidtree, cid);
323 
324  if (!psidid) { /* node does not exist, allocate one & attempt adding */
325  spin_unlock(cidlock);
326  npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL);
327  if (!npsidid)
328  return -ENOMEM;
329 
330  npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL);
331  if (!npsidid->sidstr) {
332  kfree(npsidid);
333  return -ENOMEM;
334  }
335 
336  spin_lock(cidlock);
337  psidid = sid_rb_search(cidtree, cid);
338  if (psidid) { /* node happened to get inserted meanwhile */
339  ++psidid->refcount;
340  spin_unlock(cidlock);
341  kfree(npsidid->sidstr);
342  kfree(npsidid);
343  } else {
344  psidid = npsidid;
345  sid_rb_insert(cidtree, cid, &psidid,
346  sidtype == SIDOWNER ? "oi:" : "gi:");
347  ++psidid->refcount;
348  spin_unlock(cidlock);
349  }
350  } else {
351  ++psidid->refcount;
352  spin_unlock(cidlock);
353  }
354 
355  /*
356  * If we are here, it is safe to access psidid and its fields
357  * since a reference was taken earlier while holding the spinlock.
358  * A reference on the node is put without holding the spinlock
359  * and it is OK to do so in this case, shrinker will not erase
360  * this node until all references are put and we do not access
361  * any fields of the node after a reference is put .
362  */
363  if (test_bit(SID_ID_MAPPED, &psidid->state)) {
364  cifs_copy_sid(ssid, &psidid->sid);
365  psidid->time = jiffies; /* update ts for accessing */
366  goto id_sid_out;
367  }
368 
369  if (time_after(psidid->time + SID_MAP_RETRY, jiffies)) {
370  rc = -EINVAL;
371  goto id_sid_out;
372  }
373 
374  if (!test_and_set_bit(SID_ID_PENDING, &psidid->state)) {
375  saved_cred = override_creds(root_cred);
376  sidkey = request_key(&cifs_idmap_key_type, psidid->sidstr, "");
377  if (IS_ERR(sidkey)) {
378  rc = -EINVAL;
379  cFYI(1, "%s: Can't map and id to a SID", __func__);
380  } else if (sidkey->datalen < sizeof(struct cifs_sid)) {
381  rc = -EIO;
382  cFYI(1, "%s: Downcall contained malformed key "
383  "(datalen=%hu)", __func__, sidkey->datalen);
384  } else {
385  lsid = (struct cifs_sid *)sidkey->payload.data;
386  cifs_copy_sid(&psidid->sid, lsid);
387  cifs_copy_sid(ssid, &psidid->sid);
388  set_bit(SID_ID_MAPPED, &psidid->state);
389  key_put(sidkey);
390  kfree(psidid->sidstr);
391  }
392  psidid->time = jiffies; /* update ts for accessing */
393  revert_creds(saved_cred);
394  clear_bit(SID_ID_PENDING, &psidid->state);
395  wake_up_bit(&psidid->state, SID_ID_PENDING);
396  } else {
397  rc = wait_on_bit(&psidid->state, SID_ID_PENDING,
398  sidid_pending_wait, TASK_INTERRUPTIBLE);
399  if (rc) {
400  cFYI(1, "%s: sidid_pending_wait interrupted %d",
401  __func__, rc);
402  --psidid->refcount;
403  return rc;
404  }
405  if (test_bit(SID_ID_MAPPED, &psidid->state))
406  cifs_copy_sid(ssid, &psidid->sid);
407  else
408  rc = -EINVAL;
409  }
410 id_sid_out:
411  --psidid->refcount;
412  return rc;
413 }
414 
415 static int
416 sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
417  struct cifs_fattr *fattr, uint sidtype)
418 {
419  int rc;
420  unsigned long cid;
421  struct key *idkey;
422  const struct cred *saved_cred;
423  struct cifs_sid_id *psidid, *npsidid;
424  struct rb_root *cidtree;
425  spinlock_t *cidlock;
426 
427  if (sidtype == SIDOWNER) {
428  cid = cifs_sb->mnt_uid; /* default uid, in case upcall fails */
429  cidlock = &siduidlock;
430  cidtree = &uidtree;
431  } else if (sidtype == SIDGROUP) {
432  cid = cifs_sb->mnt_gid; /* default gid, in case upcall fails */
433  cidlock = &sidgidlock;
434  cidtree = &gidtree;
435  } else
436  return -ENOENT;
437 
438  spin_lock(cidlock);
439  psidid = id_rb_search(cidtree, psid);
440 
441  if (!psidid) { /* node does not exist, allocate one & attempt adding */
442  spin_unlock(cidlock);
443  npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL);
444  if (!npsidid)
445  return -ENOMEM;
446 
447  npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL);
448  if (!npsidid->sidstr) {
449  kfree(npsidid);
450  return -ENOMEM;
451  }
452 
453  spin_lock(cidlock);
454  psidid = id_rb_search(cidtree, psid);
455  if (psidid) { /* node happened to get inserted meanwhile */
456  ++psidid->refcount;
457  spin_unlock(cidlock);
458  kfree(npsidid->sidstr);
459  kfree(npsidid);
460  } else {
461  psidid = npsidid;
462  id_rb_insert(cidtree, psid, &psidid,
463  sidtype == SIDOWNER ? "os:" : "gs:");
464  ++psidid->refcount;
465  spin_unlock(cidlock);
466  }
467  } else {
468  ++psidid->refcount;
469  spin_unlock(cidlock);
470  }
471 
472  /*
473  * If we are here, it is safe to access psidid and its fields
474  * since a reference was taken earlier while holding the spinlock.
475  * A reference on the node is put without holding the spinlock
476  * and it is OK to do so in this case, shrinker will not erase
477  * this node until all references are put and we do not access
478  * any fields of the node after a reference is put .
479  */
480  if (test_bit(SID_ID_MAPPED, &psidid->state)) {
481  cid = psidid->id;
482  psidid->time = jiffies; /* update ts for accessing */
483  goto sid_to_id_out;
484  }
485 
486  if (time_after(psidid->time + SID_MAP_RETRY, jiffies))
487  goto sid_to_id_out;
488 
489  if (!test_and_set_bit(SID_ID_PENDING, &psidid->state)) {
490  saved_cred = override_creds(root_cred);
491  idkey = request_key(&cifs_idmap_key_type, psidid->sidstr, "");
492  if (IS_ERR(idkey))
493  cFYI(1, "%s: Can't map SID to an id", __func__);
494  else {
495  cid = *(unsigned long *)idkey->payload.value;
496  psidid->id = cid;
497  set_bit(SID_ID_MAPPED, &psidid->state);
498  key_put(idkey);
499  kfree(psidid->sidstr);
500  }
501  revert_creds(saved_cred);
502  psidid->time = jiffies; /* update ts for accessing */
503  clear_bit(SID_ID_PENDING, &psidid->state);
504  wake_up_bit(&psidid->state, SID_ID_PENDING);
505  } else {
506  rc = wait_on_bit(&psidid->state, SID_ID_PENDING,
507  sidid_pending_wait, TASK_INTERRUPTIBLE);
508  if (rc) {
509  cFYI(1, "%s: sidid_pending_wait interrupted %d",
510  __func__, rc);
511  --psidid->refcount; /* decremented without spinlock */
512  return rc;
513  }
514  if (test_bit(SID_ID_MAPPED, &psidid->state))
515  cid = psidid->id;
516  }
517 
518 sid_to_id_out:
519  --psidid->refcount; /* decremented without spinlock */
520  if (sidtype == SIDOWNER)
521  fattr->cf_uid = cid;
522  else
523  fattr->cf_gid = cid;
524 
525  return 0;
526 }
527 
528 int
530 {
531  struct cred *cred;
532  struct key *keyring;
533  int ret;
534 
535  cFYI(1, "Registering the %s key type", cifs_idmap_key_type.name);
536 
537  /* create an override credential set with a special thread keyring in
538  * which requests are cached
539  *
540  * this is used to prevent malicious redirections from being installed
541  * with add_key().
542  */
543  cred = prepare_kernel_cred(NULL);
544  if (!cred)
545  return -ENOMEM;
546 
547  keyring = key_alloc(&key_type_keyring, ".cifs_idmap", 0, 0, cred,
548  (KEY_POS_ALL & ~KEY_POS_SETATTR) |
549  KEY_USR_VIEW | KEY_USR_READ,
550  KEY_ALLOC_NOT_IN_QUOTA);
551  if (IS_ERR(keyring)) {
552  ret = PTR_ERR(keyring);
553  goto failed_put_cred;
554  }
555 
556  ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL);
557  if (ret < 0)
558  goto failed_put_key;
559 
560  ret = register_key_type(&cifs_idmap_key_type);
561  if (ret < 0)
562  goto failed_put_key;
563 
564  /* instruct request_key() to use this special keyring as a cache for
565  * the results it looks up */
566  set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
567  cred->thread_keyring = keyring;
568  cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
569  root_cred = cred;
570 
571  spin_lock_init(&siduidlock);
572  uidtree = RB_ROOT;
573  spin_lock_init(&sidgidlock);
574  gidtree = RB_ROOT;
575 
576  spin_lock_init(&uidsidlock);
577  siduidtree = RB_ROOT;
578  spin_lock_init(&gidsidlock);
579  sidgidtree = RB_ROOT;
580  register_shrinker(&cifs_shrinker);
581 
582  cFYI(1, "cifs idmap keyring: %d", key_serial(keyring));
583  return 0;
584 
585 failed_put_key:
586  key_put(keyring);
587 failed_put_cred:
588  put_cred(cred);
589  return ret;
590 }
591 
592 void
594 {
595  key_revoke(root_cred->thread_keyring);
596  unregister_key_type(&cifs_idmap_key_type);
597  put_cred(root_cred);
598  unregister_shrinker(&cifs_shrinker);
599  cFYI(1, "Unregistered %s key type", cifs_idmap_key_type.name);
600 }
601 
602 void
604 {
605  struct rb_root *root;
606  struct rb_node *node;
607 
608  root = &uidtree;
609  spin_lock(&siduidlock);
610  while ((node = rb_first(root)))
611  rb_erase(node, root);
612  spin_unlock(&siduidlock);
613 
614  root = &gidtree;
615  spin_lock(&sidgidlock);
616  while ((node = rb_first(root)))
617  rb_erase(node, root);
618  spin_unlock(&sidgidlock);
619 
620  root = &siduidtree;
621  spin_lock(&uidsidlock);
622  while ((node = rb_first(root)))
623  rb_erase(node, root);
624  spin_unlock(&uidsidlock);
625 
626  root = &sidgidtree;
627  spin_lock(&gidsidlock);
628  while ((node = rb_first(root)))
629  rb_erase(node, root);
630  spin_unlock(&gidsidlock);
631 }
632 
633 /* if the two SIDs (roughly equivalent to a UUID for a user or group) are
634  the same returns 1, if they do not match returns 0 */
635 int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
636 {
637  int i;
638  int num_subauth, num_sat, num_saw;
639 
640  if ((!ctsid) || (!cwsid))
641  return 1;
642 
643  /* compare the revision */
644  if (ctsid->revision != cwsid->revision) {
645  if (ctsid->revision > cwsid->revision)
646  return 1;
647  else
648  return -1;
649  }
650 
651  /* compare all of the six auth values */
652  for (i = 0; i < 6; ++i) {
653  if (ctsid->authority[i] != cwsid->authority[i]) {
654  if (ctsid->authority[i] > cwsid->authority[i])
655  return 1;
656  else
657  return -1;
658  }
659  }
660 
661  /* compare all of the subauth values if any */
662  num_sat = ctsid->num_subauth;
663  num_saw = cwsid->num_subauth;
664  num_subauth = num_sat < num_saw ? num_sat : num_saw;
665  if (num_subauth) {
666  for (i = 0; i < num_subauth; ++i) {
667  if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
668  if (le32_to_cpu(ctsid->sub_auth[i]) >
669  le32_to_cpu(cwsid->sub_auth[i]))
670  return 1;
671  else
672  return -1;
673  }
674  }
675  }
676 
677  return 0; /* sids compare/match */
678 }
679 
680 
681 /* copy ntsd, owner sid, and group sid from a security descriptor to another */
682 static void copy_sec_desc(const struct cifs_ntsd *pntsd,
683  struct cifs_ntsd *pnntsd, __u32 sidsoffset)
684 {
685  struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
686  struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
687 
688  /* copy security descriptor control portion */
689  pnntsd->revision = pntsd->revision;
690  pnntsd->type = pntsd->type;
691  pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
692  pnntsd->sacloffset = 0;
693  pnntsd->osidoffset = cpu_to_le32(sidsoffset);
694  pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
695 
696  /* copy owner sid */
697  owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
698  le32_to_cpu(pntsd->osidoffset));
699  nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
700  cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
701 
702  /* copy group sid */
703  group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
704  le32_to_cpu(pntsd->gsidoffset));
705  ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
706  sizeof(struct cifs_sid));
707  cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
708 
709  return;
710 }
711 
712 
713 /*
714  change posix mode to reflect permissions
715  pmode is the existing mode (we only want to overwrite part of this
716  bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
717 */
718 static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
719  umode_t *pbits_to_set)
720 {
721  __u32 flags = le32_to_cpu(ace_flags);
722  /* the order of ACEs is important. The canonical order is to begin with
723  DENY entries followed by ALLOW, otherwise an allow entry could be
724  encountered first, making the subsequent deny entry like "dead code"
725  which would be superflous since Windows stops when a match is made
726  for the operation you are trying to perform for your user */
727 
728  /* For deny ACEs we change the mask so that subsequent allow access
729  control entries do not turn on the bits we are denying */
730  if (type == ACCESS_DENIED) {
731  if (flags & GENERIC_ALL)
732  *pbits_to_set &= ~S_IRWXUGO;
733 
734  if ((flags & GENERIC_WRITE) ||
735  ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
736  *pbits_to_set &= ~S_IWUGO;
737  if ((flags & GENERIC_READ) ||
738  ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
739  *pbits_to_set &= ~S_IRUGO;
740  if ((flags & GENERIC_EXECUTE) ||
741  ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
742  *pbits_to_set &= ~S_IXUGO;
743  return;
744  } else if (type != ACCESS_ALLOWED) {
745  cERROR(1, "unknown access control type %d", type);
746  return;
747  }
748  /* else ACCESS_ALLOWED type */
749 
750  if (flags & GENERIC_ALL) {
751  *pmode |= (S_IRWXUGO & (*pbits_to_set));
752  cFYI(DBG2, "all perms");
753  return;
754  }
755  if ((flags & GENERIC_WRITE) ||
756  ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
757  *pmode |= (S_IWUGO & (*pbits_to_set));
758  if ((flags & GENERIC_READ) ||
759  ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
760  *pmode |= (S_IRUGO & (*pbits_to_set));
761  if ((flags & GENERIC_EXECUTE) ||
762  ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
763  *pmode |= (S_IXUGO & (*pbits_to_set));
764 
765  cFYI(DBG2, "access flags 0x%x mode now 0x%x", flags, *pmode);
766  return;
767 }
768 
769 /*
770  Generate access flags to reflect permissions mode is the existing mode.
771  This function is called for every ACE in the DACL whose SID matches
772  with either owner or group or everyone.
773 */
774 
775 static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
776  __u32 *pace_flags)
777 {
778  /* reset access mask */
779  *pace_flags = 0x0;
780 
781  /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
782  mode &= bits_to_use;
783 
784  /* check for R/W/X UGO since we do not know whose flags
785  is this but we have cleared all the bits sans RWX for
786  either user or group or other as per bits_to_use */
787  if (mode & S_IRUGO)
788  *pace_flags |= SET_FILE_READ_RIGHTS;
789  if (mode & S_IWUGO)
790  *pace_flags |= SET_FILE_WRITE_RIGHTS;
791  if (mode & S_IXUGO)
792  *pace_flags |= SET_FILE_EXEC_RIGHTS;
793 
794  cFYI(DBG2, "mode: 0x%x, access flags now 0x%x", mode, *pace_flags);
795  return;
796 }
797 
798 static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
799  const struct cifs_sid *psid, __u64 nmode, umode_t bits)
800 {
801  int i;
802  __u16 size = 0;
803  __u32 access_req = 0;
804 
805  pntace->type = ACCESS_ALLOWED;
806  pntace->flags = 0x0;
807  mode_to_access_flags(nmode, bits, &access_req);
808  if (!access_req)
809  access_req = SET_MINIMUM_RIGHTS;
810  pntace->access_req = cpu_to_le32(access_req);
811 
812  pntace->sid.revision = psid->revision;
813  pntace->sid.num_subauth = psid->num_subauth;
814  for (i = 0; i < 6; i++)
815  pntace->sid.authority[i] = psid->authority[i];
816  for (i = 0; i < psid->num_subauth; i++)
817  pntace->sid.sub_auth[i] = psid->sub_auth[i];
818 
819  size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
820  pntace->size = cpu_to_le16(size);
821 
822  return size;
823 }
824 
825 
826 #ifdef CONFIG_CIFS_DEBUG2
827 static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
828 {
829  int num_subauth;
830 
831  /* validate that we do not go past end of acl */
832 
833  if (le16_to_cpu(pace->size) < 16) {
834  cERROR(1, "ACE too small %d", le16_to_cpu(pace->size));
835  return;
836  }
837 
838  if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
839  cERROR(1, "ACL too small to parse ACE");
840  return;
841  }
842 
843  num_subauth = pace->sid.num_subauth;
844  if (num_subauth) {
845  int i;
846  cFYI(1, "ACE revision %d num_auth %d type %d flags %d size %d",
847  pace->sid.revision, pace->sid.num_subauth, pace->type,
848  pace->flags, le16_to_cpu(pace->size));
849  for (i = 0; i < num_subauth; ++i) {
850  cFYI(1, "ACE sub_auth[%d]: 0x%x", i,
851  le32_to_cpu(pace->sid.sub_auth[i]));
852  }
853 
854  /* BB add length check to make sure that we do not have huge
855  num auths and therefore go off the end */
856  }
857 
858  return;
859 }
860 #endif
861 
862 
863 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
864  struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
865  struct cifs_fattr *fattr)
866 {
867  int i;
868  int num_aces = 0;
869  int acl_size;
870  char *acl_base;
871  struct cifs_ace **ppace;
872 
873  /* BB need to add parm so we can store the SID BB */
874 
875  if (!pdacl) {
876  /* no DACL in the security descriptor, set
877  all the permissions for user/group/other */
878  fattr->cf_mode |= S_IRWXUGO;
879  return;
880  }
881 
882  /* validate that we do not go past end of acl */
883  if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
884  cERROR(1, "ACL too small to parse DACL");
885  return;
886  }
887 
888  cFYI(DBG2, "DACL revision %d size %d num aces %d",
889  le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
890  le32_to_cpu(pdacl->num_aces));
891 
892  /* reset rwx permissions for user/group/other.
893  Also, if num_aces is 0 i.e. DACL has no ACEs,
894  user/group/other have no permissions */
895  fattr->cf_mode &= ~(S_IRWXUGO);
896 
897  acl_base = (char *)pdacl;
898  acl_size = sizeof(struct cifs_acl);
899 
900  num_aces = le32_to_cpu(pdacl->num_aces);
901  if (num_aces > 0) {
902  umode_t user_mask = S_IRWXU;
903  umode_t group_mask = S_IRWXG;
904  umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
905 
906  if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
907  return;
908  ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
909  GFP_KERNEL);
910  if (!ppace) {
911  cERROR(1, "DACL memory allocation error");
912  return;
913  }
914 
915  for (i = 0; i < num_aces; ++i) {
916  ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
917 #ifdef CONFIG_CIFS_DEBUG2
918  dump_ace(ppace[i], end_of_acl);
919 #endif
920  if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
921  access_flags_to_mode(ppace[i]->access_req,
922  ppace[i]->type,
923  &fattr->cf_mode,
924  &user_mask);
925  if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
926  access_flags_to_mode(ppace[i]->access_req,
927  ppace[i]->type,
928  &fattr->cf_mode,
929  &group_mask);
930  if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
931  access_flags_to_mode(ppace[i]->access_req,
932  ppace[i]->type,
933  &fattr->cf_mode,
934  &other_mask);
935  if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
936  access_flags_to_mode(ppace[i]->access_req,
937  ppace[i]->type,
938  &fattr->cf_mode,
939  &other_mask);
940 
941 
942 /* memcpy((void *)(&(cifscred->aces[i])),
943  (void *)ppace[i],
944  sizeof(struct cifs_ace)); */
945 
946  acl_base = (char *)ppace[i];
947  acl_size = le16_to_cpu(ppace[i]->size);
948  }
949 
950  kfree(ppace);
951  }
952 
953  return;
954 }
955 
956 
957 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
958  struct cifs_sid *pgrpsid, __u64 nmode)
959 {
960  u16 size = 0;
961  struct cifs_acl *pnndacl;
962 
963  pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
964 
965  size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
966  pownersid, nmode, S_IRWXU);
967  size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
968  pgrpsid, nmode, S_IRWXG);
969  size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
970  &sid_everyone, nmode, S_IRWXO);
971 
972  pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
973  pndacl->num_aces = cpu_to_le32(3);
974 
975  return 0;
976 }
977 
978 
979 static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
980 {
981  /* BB need to add parm so we can store the SID BB */
982 
983  /* validate that we do not go past end of ACL - sid must be at least 8
984  bytes long (assuming no sub-auths - e.g. the null SID */
985  if (end_of_acl < (char *)psid + 8) {
986  cERROR(1, "ACL too small to parse SID %p", psid);
987  return -EINVAL;
988  }
989 
990  if (psid->num_subauth) {
991 #ifdef CONFIG_CIFS_DEBUG2
992  int i;
993  cFYI(1, "SID revision %d num_auth %d",
994  psid->revision, psid->num_subauth);
995 
996  for (i = 0; i < psid->num_subauth; i++) {
997  cFYI(1, "SID sub_auth[%d]: 0x%x ", i,
998  le32_to_cpu(psid->sub_auth[i]));
999  }
1000 
1001  /* BB add length check to make sure that we do not have huge
1002  num auths and therefore go off the end */
1003  cFYI(1, "RID 0x%x",
1004  le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
1005 #endif
1006  }
1007 
1008  return 0;
1009 }
1010 
1011 
1012 /* Convert CIFS ACL to POSIX form */
1013 static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
1014  struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr)
1015 {
1016  int rc = 0;
1017  struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1018  struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
1019  char *end_of_acl = ((char *)pntsd) + acl_len;
1020  __u32 dacloffset;
1021 
1022  if (pntsd == NULL)
1023  return -EIO;
1024 
1025  owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1026  le32_to_cpu(pntsd->osidoffset));
1027  group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1028  le32_to_cpu(pntsd->gsidoffset));
1029  dacloffset = le32_to_cpu(pntsd->dacloffset);
1030  dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1031  cFYI(DBG2, "revision %d type 0x%x ooffset 0x%x goffset 0x%x "
1032  "sacloffset 0x%x dacloffset 0x%x",
1033  pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
1034  le32_to_cpu(pntsd->gsidoffset),
1035  le32_to_cpu(pntsd->sacloffset), dacloffset);
1036 /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
1037  rc = parse_sid(owner_sid_ptr, end_of_acl);
1038  if (rc) {
1039  cFYI(1, "%s: Error %d parsing Owner SID", __func__, rc);
1040  return rc;
1041  }
1042  rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
1043  if (rc) {
1044  cFYI(1, "%s: Error %d mapping Owner SID to uid", __func__, rc);
1045  return rc;
1046  }
1047 
1048  rc = parse_sid(group_sid_ptr, end_of_acl);
1049  if (rc) {
1050  cFYI(1, "%s: Error %d mapping Owner SID to gid", __func__, rc);
1051  return rc;
1052  }
1053  rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
1054  if (rc) {
1055  cFYI(1, "%s: Error %d mapping Group SID to gid", __func__, rc);
1056  return rc;
1057  }
1058 
1059  if (dacloffset)
1060  parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
1061  group_sid_ptr, fattr);
1062  else
1063  cFYI(1, "no ACL"); /* BB grant all or default perms? */
1064 
1065  return rc;
1066 }
1067 
1068 /* Convert permission bits from mode to equivalent CIFS ACL */
1069 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
1070  __u32 secdesclen, __u64 nmode, uid_t uid, gid_t gid, int *aclflag)
1071 {
1072  int rc = 0;
1073  __u32 dacloffset;
1074  __u32 ndacloffset;
1075  __u32 sidsoffset;
1076  struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
1077  struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
1078  struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */
1079  struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
1080 
1081  if (nmode != NO_CHANGE_64) { /* chmod */
1082  owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1083  le32_to_cpu(pntsd->osidoffset));
1084  group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
1085  le32_to_cpu(pntsd->gsidoffset));
1086  dacloffset = le32_to_cpu(pntsd->dacloffset);
1087  dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
1088  ndacloffset = sizeof(struct cifs_ntsd);
1089  ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
1090  ndacl_ptr->revision = dacl_ptr->revision;
1091  ndacl_ptr->size = 0;
1092  ndacl_ptr->num_aces = 0;
1093 
1094  rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
1095  nmode);
1096  sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
1097  /* copy sec desc control portion & owner and group sids */
1098  copy_sec_desc(pntsd, pnntsd, sidsoffset);
1099  *aclflag = CIFS_ACL_DACL;
1100  } else {
1101  memcpy(pnntsd, pntsd, secdesclen);
1102  if (uid != NO_CHANGE_32) { /* chown */
1103  owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1104  le32_to_cpu(pnntsd->osidoffset));
1105  nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1106  GFP_KERNEL);
1107  if (!nowner_sid_ptr)
1108  return -ENOMEM;
1109  rc = id_to_sid(uid, SIDOWNER, nowner_sid_ptr);
1110  if (rc) {
1111  cFYI(1, "%s: Mapping error %d for owner id %d",
1112  __func__, rc, uid);
1113  kfree(nowner_sid_ptr);
1114  return rc;
1115  }
1116  cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
1117  kfree(nowner_sid_ptr);
1118  *aclflag = CIFS_ACL_OWNER;
1119  }
1120  if (gid != NO_CHANGE_32) { /* chgrp */
1121  group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
1122  le32_to_cpu(pnntsd->gsidoffset));
1123  ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
1124  GFP_KERNEL);
1125  if (!ngroup_sid_ptr)
1126  return -ENOMEM;
1127  rc = id_to_sid(gid, SIDGROUP, ngroup_sid_ptr);
1128  if (rc) {
1129  cFYI(1, "%s: Mapping error %d for group id %d",
1130  __func__, rc, gid);
1131  kfree(ngroup_sid_ptr);
1132  return rc;
1133  }
1134  cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
1135  kfree(ngroup_sid_ptr);
1136  *aclflag = CIFS_ACL_GROUP;
1137  }
1138  }
1139 
1140  return rc;
1141 }
1142 
1143 static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
1144  __u16 fid, u32 *pacllen)
1145 {
1146  struct cifs_ntsd *pntsd = NULL;
1147  unsigned int xid;
1148  int rc;
1149  struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1150 
1151  if (IS_ERR(tlink))
1152  return ERR_CAST(tlink);
1153 
1154  xid = get_xid();
1155  rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
1156  free_xid(xid);
1157 
1158  cifs_put_tlink(tlink);
1159 
1160  cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
1161  if (rc)
1162  return ERR_PTR(rc);
1163  return pntsd;
1164 }
1165 
1166 static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
1167  const char *path, u32 *pacllen)
1168 {
1169  struct cifs_ntsd *pntsd = NULL;
1170  int oplock = 0;
1171  unsigned int xid;
1172  int rc, create_options = 0;
1173  __u16 fid;
1174  struct cifs_tcon *tcon;
1175  struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1176 
1177  if (IS_ERR(tlink))
1178  return ERR_CAST(tlink);
1179 
1180  tcon = tlink_tcon(tlink);
1181  xid = get_xid();
1182 
1183  if (backup_cred(cifs_sb))
1184  create_options |= CREATE_OPEN_BACKUP_INTENT;
1185 
1186  rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
1187  create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
1189  if (!rc) {
1190  rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
1191  CIFSSMBClose(xid, tcon, fid);
1192  }
1193 
1194  cifs_put_tlink(tlink);
1195  free_xid(xid);
1196 
1197  cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
1198  if (rc)
1199  return ERR_PTR(rc);
1200  return pntsd;
1201 }
1202 
1203 /* Retrieve an ACL from the server */
1204 struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
1205  struct inode *inode, const char *path,
1206  u32 *pacllen)
1207 {
1208  struct cifs_ntsd *pntsd = NULL;
1209  struct cifsFileInfo *open_file = NULL;
1210 
1211  if (inode)
1212  open_file = find_readable_file(CIFS_I(inode), true);
1213  if (!open_file)
1214  return get_cifs_acl_by_path(cifs_sb, path, pacllen);
1215 
1216  pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->fid.netfid, pacllen);
1217  cifsFileInfo_put(open_file);
1218  return pntsd;
1219 }
1220 
1221  /* Set an ACL on the server */
1222 int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
1223  struct inode *inode, const char *path, int aclflag)
1224 {
1225  int oplock = 0;
1226  unsigned int xid;
1227  int rc, access_flags, create_options = 0;
1228  __u16 fid;
1229  struct cifs_tcon *tcon;
1230  struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1231  struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1232 
1233  if (IS_ERR(tlink))
1234  return PTR_ERR(tlink);
1235 
1236  tcon = tlink_tcon(tlink);
1237  xid = get_xid();
1238 
1239  if (backup_cred(cifs_sb))
1240  create_options |= CREATE_OPEN_BACKUP_INTENT;
1241 
1242  if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
1243  access_flags = WRITE_OWNER;
1244  else
1245  access_flags = WRITE_DAC;
1246 
1247  rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, access_flags,
1248  create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
1250  if (rc) {
1251  cERROR(1, "Unable to open file to set ACL");
1252  goto out;
1253  }
1254 
1255  rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen, aclflag);
1256  cFYI(DBG2, "SetCIFSACL rc = %d", rc);
1257 
1258  CIFSSMBClose(xid, tcon, fid);
1259 out:
1260  free_xid(xid);
1261  cifs_put_tlink(tlink);
1262  return rc;
1263 }
1264 
1265 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
1266 int
1267 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
1268  struct inode *inode, const char *path, const __u16 *pfid)
1269 {
1270  struct cifs_ntsd *pntsd = NULL;
1271  u32 acllen = 0;
1272  int rc = 0;
1273 
1274  cFYI(DBG2, "converting ACL to mode for %s", path);
1275 
1276  if (pfid)
1277  pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
1278  else
1279  pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
1280 
1281  /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
1282  if (IS_ERR(pntsd)) {
1283  rc = PTR_ERR(pntsd);
1284  cERROR(1, "%s: error %d getting sec desc", __func__, rc);
1285  } else {
1286  rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr);
1287  kfree(pntsd);
1288  if (rc)
1289  cERROR(1, "parse sec desc failed rc = %d", rc);
1290  }
1291 
1292  return rc;
1293 }
1294 
1295 /* Convert mode bits to an ACL so we can update the ACL on the server */
1296 int
1297 id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
1298  uid_t uid, gid_t gid)
1299 {
1300  int rc = 0;
1301  int aclflag = CIFS_ACL_DACL; /* default flag to set */
1302  __u32 secdesclen = 0;
1303  struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
1304  struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
1305 
1306  cFYI(DBG2, "set ACL from mode for %s", path);
1307 
1308  /* Get the security descriptor */
1309  pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
1310 
1311  /* Add three ACEs for owner, group, everyone getting rid of
1312  other ACEs as chmod disables ACEs and set the security descriptor */
1313 
1314  if (IS_ERR(pntsd)) {
1315  rc = PTR_ERR(pntsd);
1316  cERROR(1, "%s: error %d getting sec desc", __func__, rc);
1317  } else {
1318  /* allocate memory for the smb header,
1319  set security descriptor request security descriptor
1320  parameters, and secuirty descriptor itself */
1321 
1322  secdesclen = secdesclen < DEFSECDESCLEN ?
1323  DEFSECDESCLEN : secdesclen;
1324  pnntsd = kmalloc(secdesclen, GFP_KERNEL);
1325  if (!pnntsd) {
1326  cERROR(1, "Unable to allocate security descriptor");
1327  kfree(pntsd);
1328  return -ENOMEM;
1329  }
1330 
1331  rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
1332  &aclflag);
1333 
1334  cFYI(DBG2, "build_sec_desc rc: %d", rc);
1335 
1336  if (!rc) {
1337  /* Set the security descriptor */
1338  rc = set_cifs_acl(pnntsd, secdesclen, inode,
1339  path, aclflag);
1340  cFYI(DBG2, "set_cifs_acl rc: %d", rc);
1341  }
1342 
1343  kfree(pnntsd);
1344  kfree(pntsd);
1345  }
1346 
1347  return rc;
1348 }