nfs4acl.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954
  1. /*
  2. * fs/nfs4acl/acl.c
  3. *
  4. * Common NFSv4 ACL handling code.
  5. *
  6. * Copyright (c) 2002, 2003 The Regents of the University of Michigan.
  7. * All rights reserved.
  8. *
  9. * Marius Aamodt Eriksen <marius@umich.edu>
  10. * Jeff Sedlak <jsedlak@umich.edu>
  11. * J. Bruce Fields <bfields@umich.edu>
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions
  15. * are met:
  16. *
  17. * 1. Redistributions of source code must retain the above copyright
  18. * notice, this list of conditions and the following disclaimer.
  19. * 2. Redistributions in binary form must reproduce the above copyright
  20. * notice, this list of conditions and the following disclaimer in the
  21. * documentation and/or other materials provided with the distribution.
  22. * 3. Neither the name of the University nor the names of its
  23. * contributors may be used to endorse or promote products derived
  24. * from this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  27. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  28. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  29. * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  33. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  34. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  35. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37. */
  38. #include <linux/string.h>
  39. #include <linux/slab.h>
  40. #include <linux/list.h>
  41. #include <linux/types.h>
  42. #include <linux/fs.h>
  43. #include <linux/module.h>
  44. #include <linux/nfs_fs.h>
  45. #include <linux/posix_acl.h>
  46. #include <linux/nfs4.h>
  47. #include <linux/nfs4_acl.h>
  48. /* mode bit translations: */
  49. #define NFS4_READ_MODE (NFS4_ACE_READ_DATA)
  50. #define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA)
  51. #define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE
  52. #define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | NFS4_ACE_SYNCHRONIZE)
  53. #define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL)
  54. /* We don't support these bits; insist they be neither allowed nor denied */
  55. #define NFS4_MASK_UNSUPP (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \
  56. | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS)
  57. /* flags used to simulate posix default ACLs */
  58. #define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \
  59. | NFS4_ACE_DIRECTORY_INHERIT_ACE | NFS4_ACE_INHERIT_ONLY_ACE)
  60. #define MASK_EQUAL(mask1, mask2) \
  61. ( ((mask1) & NFS4_ACE_MASK_ALL) == ((mask2) & NFS4_ACE_MASK_ALL) )
  62. static u32
  63. mask_from_posix(unsigned short perm, unsigned int flags)
  64. {
  65. int mask = NFS4_ANYONE_MODE;
  66. if (flags & NFS4_ACL_OWNER)
  67. mask |= NFS4_OWNER_MODE;
  68. if (perm & ACL_READ)
  69. mask |= NFS4_READ_MODE;
  70. if (perm & ACL_WRITE)
  71. mask |= NFS4_WRITE_MODE;
  72. if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR))
  73. mask |= NFS4_ACE_DELETE_CHILD;
  74. if (perm & ACL_EXECUTE)
  75. mask |= NFS4_EXECUTE_MODE;
  76. return mask;
  77. }
  78. static u32
  79. deny_mask(u32 allow_mask, unsigned int flags)
  80. {
  81. u32 ret = ~allow_mask & ~NFS4_MASK_UNSUPP;
  82. if (!(flags & NFS4_ACL_DIR))
  83. ret &= ~NFS4_ACE_DELETE_CHILD;
  84. return ret;
  85. }
  86. /* XXX: modify functions to return NFS errors; they're only ever
  87. * used by nfs code, after all.... */
  88. static int
  89. mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags)
  90. {
  91. u32 ignore = 0;
  92. if (!(flags & NFS4_ACL_DIR))
  93. ignore |= NFS4_ACE_DELETE_CHILD; /* ignore it */
  94. perm |= ignore;
  95. *mode = 0;
  96. if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE)
  97. *mode |= ACL_READ;
  98. if ((perm & NFS4_WRITE_MODE) == NFS4_WRITE_MODE)
  99. *mode |= ACL_WRITE;
  100. if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE)
  101. *mode |= ACL_EXECUTE;
  102. if (!MASK_EQUAL(perm, ignore|mask_from_posix(*mode, flags)))
  103. return -EINVAL;
  104. return 0;
  105. }
  106. struct ace_container {
  107. struct nfs4_ace *ace;
  108. struct list_head ace_l;
  109. };
  110. static short ace2type(struct nfs4_ace *);
  111. static int _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, unsigned int);
  112. static struct posix_acl *_nfsv4_to_posix_one(struct nfs4_acl *, unsigned int);
  113. int nfs4_acl_add_ace(struct nfs4_acl *, u32, u32, u32, int, uid_t);
  114. static int nfs4_acl_split(struct nfs4_acl *, struct nfs4_acl *);
  115. struct nfs4_acl *
  116. nfs4_acl_posix_to_nfsv4(struct posix_acl *pacl, struct posix_acl *dpacl,
  117. unsigned int flags)
  118. {
  119. struct nfs4_acl *acl;
  120. int error = -EINVAL;
  121. if ((pacl != NULL &&
  122. (posix_acl_valid(pacl) < 0 || pacl->a_count == 0)) ||
  123. (dpacl != NULL &&
  124. (posix_acl_valid(dpacl) < 0 || dpacl->a_count == 0)))
  125. goto out_err;
  126. acl = nfs4_acl_new();
  127. if (acl == NULL) {
  128. error = -ENOMEM;
  129. goto out_err;
  130. }
  131. if (pacl != NULL) {
  132. error = _posix_to_nfsv4_one(pacl, acl,
  133. flags & ~NFS4_ACL_TYPE_DEFAULT);
  134. if (error < 0)
  135. goto out_acl;
  136. }
  137. if (dpacl != NULL) {
  138. error = _posix_to_nfsv4_one(dpacl, acl,
  139. flags | NFS4_ACL_TYPE_DEFAULT);
  140. if (error < 0)
  141. goto out_acl;
  142. }
  143. return acl;
  144. out_acl:
  145. nfs4_acl_free(acl);
  146. out_err:
  147. acl = ERR_PTR(error);
  148. return acl;
  149. }
  150. static int
  151. nfs4_acl_add_pair(struct nfs4_acl *acl, int eflag, u32 mask, int whotype,
  152. uid_t owner, unsigned int flags)
  153. {
  154. int error;
  155. error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE,
  156. eflag, mask, whotype, owner);
  157. if (error < 0)
  158. return error;
  159. error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
  160. eflag, deny_mask(mask, flags), whotype, owner);
  161. return error;
  162. }
  163. /* We assume the acl has been verified with posix_acl_valid. */
  164. static int
  165. _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
  166. unsigned int flags)
  167. {
  168. struct posix_acl_entry *pa, *pe, *group_owner_entry;
  169. int error = -EINVAL;
  170. u32 mask, mask_mask;
  171. int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ?
  172. NFS4_INHERITANCE_FLAGS : 0);
  173. BUG_ON(pacl->a_count < 3);
  174. pe = pacl->a_entries + pacl->a_count;
  175. pa = pe - 2; /* if mask entry exists, it's second from the last. */
  176. if (pa->e_tag == ACL_MASK)
  177. mask_mask = deny_mask(mask_from_posix(pa->e_perm, flags), flags);
  178. else
  179. mask_mask = 0;
  180. pa = pacl->a_entries;
  181. BUG_ON(pa->e_tag != ACL_USER_OBJ);
  182. mask = mask_from_posix(pa->e_perm, flags | NFS4_ACL_OWNER);
  183. error = nfs4_acl_add_pair(acl, eflag, mask, NFS4_ACL_WHO_OWNER, 0, flags);
  184. if (error < 0)
  185. goto out;
  186. pa++;
  187. while (pa->e_tag == ACL_USER) {
  188. mask = mask_from_posix(pa->e_perm, flags);
  189. error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
  190. eflag, mask_mask, NFS4_ACL_WHO_NAMED, pa->e_id);
  191. if (error < 0)
  192. goto out;
  193. error = nfs4_acl_add_pair(acl, eflag, mask,
  194. NFS4_ACL_WHO_NAMED, pa->e_id, flags);
  195. if (error < 0)
  196. goto out;
  197. pa++;
  198. }
  199. /* In the case of groups, we apply allow ACEs first, then deny ACEs,
  200. * since a user can be in more than one group. */
  201. /* allow ACEs */
  202. if (pacl->a_count > 3) {
  203. BUG_ON(pa->e_tag != ACL_GROUP_OBJ);
  204. error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
  205. NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask,
  206. NFS4_ACL_WHO_GROUP, 0);
  207. if (error < 0)
  208. goto out;
  209. }
  210. group_owner_entry = pa;
  211. mask = mask_from_posix(pa->e_perm, flags);
  212. error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE,
  213. NFS4_ACE_IDENTIFIER_GROUP | eflag, mask,
  214. NFS4_ACL_WHO_GROUP, 0);
  215. if (error < 0)
  216. goto out;
  217. pa++;
  218. while (pa->e_tag == ACL_GROUP) {
  219. mask = mask_from_posix(pa->e_perm, flags);
  220. error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
  221. NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask,
  222. NFS4_ACL_WHO_NAMED, pa->e_id);
  223. if (error < 0)
  224. goto out;
  225. error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE,
  226. NFS4_ACE_IDENTIFIER_GROUP | eflag, mask,
  227. NFS4_ACL_WHO_NAMED, pa->e_id);
  228. if (error < 0)
  229. goto out;
  230. pa++;
  231. }
  232. /* deny ACEs */
  233. pa = group_owner_entry;
  234. mask = mask_from_posix(pa->e_perm, flags);
  235. error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
  236. NFS4_ACE_IDENTIFIER_GROUP | eflag,
  237. deny_mask(mask, flags), NFS4_ACL_WHO_GROUP, 0);
  238. if (error < 0)
  239. goto out;
  240. pa++;
  241. while (pa->e_tag == ACL_GROUP) {
  242. mask = mask_from_posix(pa->e_perm, flags);
  243. error = nfs4_acl_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE,
  244. NFS4_ACE_IDENTIFIER_GROUP | eflag,
  245. deny_mask(mask, flags), NFS4_ACL_WHO_NAMED, pa->e_id);
  246. if (error < 0)
  247. goto out;
  248. pa++;
  249. }
  250. if (pa->e_tag == ACL_MASK)
  251. pa++;
  252. BUG_ON(pa->e_tag != ACL_OTHER);
  253. mask = mask_from_posix(pa->e_perm, flags);
  254. error = nfs4_acl_add_pair(acl, eflag, mask, NFS4_ACL_WHO_EVERYONE, 0, flags);
  255. out:
  256. return error;
  257. }
  258. static void
  259. sort_pacl_range(struct posix_acl *pacl, int start, int end) {
  260. int sorted = 0, i;
  261. struct posix_acl_entry tmp;
  262. /* We just do a bubble sort; easy to do in place, and we're not
  263. * expecting acl's to be long enough to justify anything more. */
  264. while (!sorted) {
  265. sorted = 1;
  266. for (i = start; i < end; i++) {
  267. if (pacl->a_entries[i].e_id
  268. > pacl->a_entries[i+1].e_id) {
  269. sorted = 0;
  270. tmp = pacl->a_entries[i];
  271. pacl->a_entries[i] = pacl->a_entries[i+1];
  272. pacl->a_entries[i+1] = tmp;
  273. }
  274. }
  275. }
  276. }
  277. static void
  278. sort_pacl(struct posix_acl *pacl)
  279. {
  280. /* posix_acl_valid requires that users and groups be in order
  281. * by uid/gid. */
  282. int i, j;
  283. if (pacl->a_count <= 4)
  284. return; /* no users or groups */
  285. i = 1;
  286. while (pacl->a_entries[i].e_tag == ACL_USER)
  287. i++;
  288. sort_pacl_range(pacl, 1, i-1);
  289. BUG_ON(pacl->a_entries[i].e_tag != ACL_GROUP_OBJ);
  290. j = i++;
  291. while (pacl->a_entries[j].e_tag == ACL_GROUP)
  292. j++;
  293. sort_pacl_range(pacl, i, j-1);
  294. return;
  295. }
  296. static int
  297. write_pace(struct nfs4_ace *ace, struct posix_acl *pacl,
  298. struct posix_acl_entry **pace, short tag, unsigned int flags)
  299. {
  300. struct posix_acl_entry *this = *pace;
  301. if (*pace == pacl->a_entries + pacl->a_count)
  302. return -EINVAL; /* fell off the end */
  303. (*pace)++;
  304. this->e_tag = tag;
  305. if (tag == ACL_USER_OBJ)
  306. flags |= NFS4_ACL_OWNER;
  307. if (mode_from_nfs4(ace->access_mask, &this->e_perm, flags))
  308. return -EINVAL;
  309. this->e_id = (tag == ACL_USER || tag == ACL_GROUP ?
  310. ace->who : ACL_UNDEFINED_ID);
  311. return 0;
  312. }
  313. static struct nfs4_ace *
  314. get_next_v4_ace(struct list_head **p, struct list_head *head)
  315. {
  316. struct nfs4_ace *ace;
  317. *p = (*p)->next;
  318. if (*p == head)
  319. return NULL;
  320. ace = list_entry(*p, struct nfs4_ace, l_ace);
  321. return ace;
  322. }
  323. int
  324. nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, struct posix_acl **pacl,
  325. struct posix_acl **dpacl, unsigned int flags)
  326. {
  327. struct nfs4_acl *dacl;
  328. int error = -ENOMEM;
  329. *pacl = NULL;
  330. *dpacl = NULL;
  331. dacl = nfs4_acl_new();
  332. if (dacl == NULL)
  333. goto out;
  334. error = nfs4_acl_split(acl, dacl);
  335. if (error < 0)
  336. goto out_acl;
  337. if (pacl != NULL) {
  338. if (acl->naces == 0) {
  339. error = -ENODATA;
  340. goto try_dpacl;
  341. }
  342. *pacl = _nfsv4_to_posix_one(acl, flags);
  343. if (IS_ERR(*pacl)) {
  344. error = PTR_ERR(*pacl);
  345. *pacl = NULL;
  346. goto out_acl;
  347. }
  348. }
  349. try_dpacl:
  350. if (dpacl != NULL) {
  351. if (dacl->naces == 0) {
  352. if (pacl == NULL || *pacl == NULL)
  353. error = -ENODATA;
  354. goto out_acl;
  355. }
  356. error = 0;
  357. *dpacl = _nfsv4_to_posix_one(dacl, flags);
  358. if (IS_ERR(*dpacl)) {
  359. error = PTR_ERR(*dpacl);
  360. *dpacl = NULL;
  361. goto out_acl;
  362. }
  363. }
  364. out_acl:
  365. if (error && pacl) {
  366. posix_acl_release(*pacl);
  367. *pacl = NULL;
  368. }
  369. nfs4_acl_free(dacl);
  370. out:
  371. return error;
  372. }
  373. static int
  374. same_who(struct nfs4_ace *a, struct nfs4_ace *b)
  375. {
  376. return a->whotype == b->whotype &&
  377. (a->whotype != NFS4_ACL_WHO_NAMED || a->who == b->who);
  378. }
  379. static int
  380. complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny,
  381. unsigned int flags)
  382. {
  383. int ignore = 0;
  384. if (!(flags & NFS4_ACL_DIR))
  385. ignore |= NFS4_ACE_DELETE_CHILD;
  386. return MASK_EQUAL(ignore|deny_mask(allow->access_mask, flags),
  387. ignore|deny->access_mask) &&
  388. allow->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE &&
  389. deny->type == NFS4_ACE_ACCESS_DENIED_ACE_TYPE &&
  390. allow->flag == deny->flag &&
  391. same_who(allow, deny);
  392. }
  393. static inline int
  394. user_obj_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
  395. struct posix_acl *pacl, struct posix_acl_entry **pace,
  396. unsigned int flags)
  397. {
  398. int error = -EINVAL;
  399. struct nfs4_ace *ace, *ace2;
  400. ace = get_next_v4_ace(p, &n4acl->ace_head);
  401. if (ace == NULL)
  402. goto out;
  403. if (ace2type(ace) != ACL_USER_OBJ)
  404. goto out;
  405. error = write_pace(ace, pacl, pace, ACL_USER_OBJ, flags);
  406. if (error < 0)
  407. goto out;
  408. error = -EINVAL;
  409. ace2 = get_next_v4_ace(p, &n4acl->ace_head);
  410. if (ace2 == NULL)
  411. goto out;
  412. if (!complementary_ace_pair(ace, ace2, flags))
  413. goto out;
  414. error = 0;
  415. out:
  416. return error;
  417. }
  418. static inline int
  419. users_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
  420. struct nfs4_ace **mask_ace,
  421. struct posix_acl *pacl, struct posix_acl_entry **pace,
  422. unsigned int flags)
  423. {
  424. int error = -EINVAL;
  425. struct nfs4_ace *ace, *ace2;
  426. ace = get_next_v4_ace(p, &n4acl->ace_head);
  427. if (ace == NULL)
  428. goto out;
  429. while (ace2type(ace) == ACL_USER) {
  430. if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
  431. goto out;
  432. if (*mask_ace &&
  433. !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
  434. goto out;
  435. *mask_ace = ace;
  436. ace = get_next_v4_ace(p, &n4acl->ace_head);
  437. if (ace == NULL)
  438. goto out;
  439. if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
  440. goto out;
  441. error = write_pace(ace, pacl, pace, ACL_USER, flags);
  442. if (error < 0)
  443. goto out;
  444. error = -EINVAL;
  445. ace2 = get_next_v4_ace(p, &n4acl->ace_head);
  446. if (ace2 == NULL)
  447. goto out;
  448. if (!complementary_ace_pair(ace, ace2, flags))
  449. goto out;
  450. if ((*mask_ace)->flag != ace2->flag ||
  451. !same_who(*mask_ace, ace2))
  452. goto out;
  453. ace = get_next_v4_ace(p, &n4acl->ace_head);
  454. if (ace == NULL)
  455. goto out;
  456. }
  457. error = 0;
  458. out:
  459. return error;
  460. }
  461. static inline int
  462. group_obj_and_groups_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
  463. struct nfs4_ace **mask_ace,
  464. struct posix_acl *pacl, struct posix_acl_entry **pace,
  465. unsigned int flags)
  466. {
  467. int error = -EINVAL;
  468. struct nfs4_ace *ace, *ace2;
  469. struct ace_container *ac;
  470. struct list_head group_l;
  471. INIT_LIST_HEAD(&group_l);
  472. ace = list_entry(*p, struct nfs4_ace, l_ace);
  473. /* group owner (mask and allow aces) */
  474. if (pacl->a_count != 3) {
  475. /* then the group owner should be preceded by mask */
  476. if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE)
  477. goto out;
  478. if (*mask_ace &&
  479. !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
  480. goto out;
  481. *mask_ace = ace;
  482. ace = get_next_v4_ace(p, &n4acl->ace_head);
  483. if (ace == NULL)
  484. goto out;
  485. if ((*mask_ace)->flag != ace->flag || !same_who(*mask_ace, ace))
  486. goto out;
  487. }
  488. if (ace2type(ace) != ACL_GROUP_OBJ)
  489. goto out;
  490. ac = kmalloc(sizeof(*ac), GFP_KERNEL);
  491. error = -ENOMEM;
  492. if (ac == NULL)
  493. goto out;
  494. ac->ace = ace;
  495. list_add_tail(&ac->ace_l, &group_l);
  496. error = -EINVAL;
  497. if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
  498. goto out;
  499. error = write_pace(ace, pacl, pace, ACL_GROUP_OBJ, flags);
  500. if (error < 0)
  501. goto out;
  502. error = -EINVAL;
  503. ace = get_next_v4_ace(p, &n4acl->ace_head);
  504. if (ace == NULL)
  505. goto out;
  506. /* groups (mask and allow aces) */
  507. while (ace2type(ace) == ACL_GROUP) {
  508. if (*mask_ace == NULL)
  509. goto out;
  510. if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE ||
  511. !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask))
  512. goto out;
  513. *mask_ace = ace;
  514. ace = get_next_v4_ace(p, &n4acl->ace_head);
  515. if (ace == NULL)
  516. goto out;
  517. ac = kmalloc(sizeof(*ac), GFP_KERNEL);
  518. error = -ENOMEM;
  519. if (ac == NULL)
  520. goto out;
  521. error = -EINVAL;
  522. if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE ||
  523. !same_who(ace, *mask_ace))
  524. goto out;
  525. ac->ace = ace;
  526. list_add_tail(&ac->ace_l, &group_l);
  527. error = write_pace(ace, pacl, pace, ACL_GROUP, flags);
  528. if (error < 0)
  529. goto out;
  530. error = -EINVAL;
  531. ace = get_next_v4_ace(p, &n4acl->ace_head);
  532. if (ace == NULL)
  533. goto out;
  534. }
  535. /* group owner (deny ace) */
  536. if (ace2type(ace) != ACL_GROUP_OBJ)
  537. goto out;
  538. ac = list_entry(group_l.next, struct ace_container, ace_l);
  539. ace2 = ac->ace;
  540. if (!complementary_ace_pair(ace2, ace, flags))
  541. goto out;
  542. list_del(group_l.next);
  543. kfree(ac);
  544. /* groups (deny aces) */
  545. while (!list_empty(&group_l)) {
  546. ace = get_next_v4_ace(p, &n4acl->ace_head);
  547. if (ace == NULL)
  548. goto out;
  549. if (ace2type(ace) != ACL_GROUP)
  550. goto out;
  551. ac = list_entry(group_l.next, struct ace_container, ace_l);
  552. ace2 = ac->ace;
  553. if (!complementary_ace_pair(ace2, ace, flags))
  554. goto out;
  555. list_del(group_l.next);
  556. kfree(ac);
  557. }
  558. ace = get_next_v4_ace(p, &n4acl->ace_head);
  559. if (ace == NULL)
  560. goto out;
  561. if (ace2type(ace) != ACL_OTHER)
  562. goto out;
  563. error = 0;
  564. out:
  565. while (!list_empty(&group_l)) {
  566. ac = list_entry(group_l.next, struct ace_container, ace_l);
  567. list_del(group_l.next);
  568. kfree(ac);
  569. }
  570. return error;
  571. }
  572. static inline int
  573. mask_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
  574. struct nfs4_ace **mask_ace,
  575. struct posix_acl *pacl, struct posix_acl_entry **pace,
  576. unsigned int flags)
  577. {
  578. int error = -EINVAL;
  579. struct nfs4_ace *ace;
  580. ace = list_entry(*p, struct nfs4_ace, l_ace);
  581. if (pacl->a_count != 3) {
  582. if (*mask_ace == NULL)
  583. goto out;
  584. (*mask_ace)->access_mask = deny_mask((*mask_ace)->access_mask, flags);
  585. write_pace(*mask_ace, pacl, pace, ACL_MASK, flags);
  586. }
  587. error = 0;
  588. out:
  589. return error;
  590. }
  591. static inline int
  592. other_from_v4(struct nfs4_acl *n4acl, struct list_head **p,
  593. struct posix_acl *pacl, struct posix_acl_entry **pace,
  594. unsigned int flags)
  595. {
  596. int error = -EINVAL;
  597. struct nfs4_ace *ace, *ace2;
  598. ace = list_entry(*p, struct nfs4_ace, l_ace);
  599. if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE)
  600. goto out;
  601. error = write_pace(ace, pacl, pace, ACL_OTHER, flags);
  602. if (error < 0)
  603. goto out;
  604. error = -EINVAL;
  605. ace2 = get_next_v4_ace(p, &n4acl->ace_head);
  606. if (ace2 == NULL)
  607. goto out;
  608. if (!complementary_ace_pair(ace, ace2, flags))
  609. goto out;
  610. error = 0;
  611. out:
  612. return error;
  613. }
  614. static int
  615. calculate_posix_ace_count(struct nfs4_acl *n4acl)
  616. {
  617. if (n4acl->naces == 6) /* owner, owner group, and other only */
  618. return 3;
  619. else { /* Otherwise there must be a mask entry. */
  620. /* Also, the remaining entries are for named users and
  621. * groups, and come in threes (mask, allow, deny): */
  622. if (n4acl->naces < 7)
  623. return -EINVAL;
  624. if ((n4acl->naces - 7) % 3)
  625. return -EINVAL;
  626. return 4 + (n4acl->naces - 7)/3;
  627. }
  628. }
  629. static struct posix_acl *
  630. _nfsv4_to_posix_one(struct nfs4_acl *n4acl, unsigned int flags)
  631. {
  632. struct posix_acl *pacl;
  633. int error = -EINVAL, nace = 0;
  634. struct list_head *p;
  635. struct nfs4_ace *mask_ace = NULL;
  636. struct posix_acl_entry *pace;
  637. nace = calculate_posix_ace_count(n4acl);
  638. if (nace < 0)
  639. goto out_err;
  640. pacl = posix_acl_alloc(nace, GFP_KERNEL);
  641. error = -ENOMEM;
  642. if (pacl == NULL)
  643. goto out_err;
  644. pace = &pacl->a_entries[0];
  645. p = &n4acl->ace_head;
  646. error = user_obj_from_v4(n4acl, &p, pacl, &pace, flags);
  647. if (error)
  648. goto out_acl;
  649. error = users_from_v4(n4acl, &p, &mask_ace, pacl, &pace, flags);
  650. if (error)
  651. goto out_acl;
  652. error = group_obj_and_groups_from_v4(n4acl, &p, &mask_ace, pacl, &pace,
  653. flags);
  654. if (error)
  655. goto out_acl;
  656. error = mask_from_v4(n4acl, &p, &mask_ace, pacl, &pace, flags);
  657. if (error)
  658. goto out_acl;
  659. error = other_from_v4(n4acl, &p, pacl, &pace, flags);
  660. if (error)
  661. goto out_acl;
  662. error = -EINVAL;
  663. if (p->next != &n4acl->ace_head)
  664. goto out_acl;
  665. if (pace != pacl->a_entries + pacl->a_count)
  666. goto out_acl;
  667. sort_pacl(pacl);
  668. return pacl;
  669. out_acl:
  670. posix_acl_release(pacl);
  671. out_err:
  672. pacl = ERR_PTR(error);
  673. return pacl;
  674. }
  675. static int
  676. nfs4_acl_split(struct nfs4_acl *acl, struct nfs4_acl *dacl)
  677. {
  678. struct list_head *h, *n;
  679. struct nfs4_ace *ace;
  680. int error = 0;
  681. list_for_each_safe(h, n, &acl->ace_head) {
  682. ace = list_entry(h, struct nfs4_ace, l_ace);
  683. if ((ace->flag & NFS4_INHERITANCE_FLAGS)
  684. != NFS4_INHERITANCE_FLAGS)
  685. continue;
  686. error = nfs4_acl_add_ace(dacl, ace->type, ace->flag,
  687. ace->access_mask, ace->whotype, ace->who);
  688. if (error < 0)
  689. goto out;
  690. list_del(h);
  691. kfree(ace);
  692. acl->naces--;
  693. }
  694. out:
  695. return error;
  696. }
  697. static short
  698. ace2type(struct nfs4_ace *ace)
  699. {
  700. switch (ace->whotype) {
  701. case NFS4_ACL_WHO_NAMED:
  702. return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ?
  703. ACL_GROUP : ACL_USER);
  704. case NFS4_ACL_WHO_OWNER:
  705. return ACL_USER_OBJ;
  706. case NFS4_ACL_WHO_GROUP:
  707. return ACL_GROUP_OBJ;
  708. case NFS4_ACL_WHO_EVERYONE:
  709. return ACL_OTHER;
  710. }
  711. BUG();
  712. return -1;
  713. }
  714. EXPORT_SYMBOL(nfs4_acl_posix_to_nfsv4);
  715. EXPORT_SYMBOL(nfs4_acl_nfsv4_to_posix);
  716. struct nfs4_acl *
  717. nfs4_acl_new(void)
  718. {
  719. struct nfs4_acl *acl;
  720. if ((acl = kmalloc(sizeof(*acl), GFP_KERNEL)) == NULL)
  721. return NULL;
  722. acl->naces = 0;
  723. INIT_LIST_HEAD(&acl->ace_head);
  724. return acl;
  725. }
  726. void
  727. nfs4_acl_free(struct nfs4_acl *acl)
  728. {
  729. struct list_head *h;
  730. struct nfs4_ace *ace;
  731. if (!acl)
  732. return;
  733. while (!list_empty(&acl->ace_head)) {
  734. h = acl->ace_head.next;
  735. list_del(h);
  736. ace = list_entry(h, struct nfs4_ace, l_ace);
  737. kfree(ace);
  738. }
  739. kfree(acl);
  740. return;
  741. }
  742. int
  743. nfs4_acl_add_ace(struct nfs4_acl *acl, u32 type, u32 flag, u32 access_mask,
  744. int whotype, uid_t who)
  745. {
  746. struct nfs4_ace *ace;
  747. if ((ace = kmalloc(sizeof(*ace), GFP_KERNEL)) == NULL)
  748. return -ENOMEM;
  749. ace->type = type;
  750. ace->flag = flag;
  751. ace->access_mask = access_mask;
  752. ace->whotype = whotype;
  753. ace->who = who;
  754. list_add_tail(&ace->l_ace, &acl->ace_head);
  755. acl->naces++;
  756. return 0;
  757. }
  758. static struct {
  759. char *string;
  760. int stringlen;
  761. int type;
  762. } s2t_map[] = {
  763. {
  764. .string = "OWNER@",
  765. .stringlen = sizeof("OWNER@") - 1,
  766. .type = NFS4_ACL_WHO_OWNER,
  767. },
  768. {
  769. .string = "GROUP@",
  770. .stringlen = sizeof("GROUP@") - 1,
  771. .type = NFS4_ACL_WHO_GROUP,
  772. },
  773. {
  774. .string = "EVERYONE@",
  775. .stringlen = sizeof("EVERYONE@") - 1,
  776. .type = NFS4_ACL_WHO_EVERYONE,
  777. },
  778. };
  779. int
  780. nfs4_acl_get_whotype(char *p, u32 len)
  781. {
  782. int i;
  783. for (i = 0; i < ARRAY_SIZE(s2t_map); i++) {
  784. if (s2t_map[i].stringlen == len &&
  785. 0 == memcmp(s2t_map[i].string, p, len))
  786. return s2t_map[i].type;
  787. }
  788. return NFS4_ACL_WHO_NAMED;
  789. }
  790. int
  791. nfs4_acl_write_who(int who, char *p)
  792. {
  793. int i;
  794. for (i = 0; i < ARRAY_SIZE(s2t_map); i++) {
  795. if (s2t_map[i].type == who) {
  796. memcpy(p, s2t_map[i].string, s2t_map[i].stringlen);
  797. return s2t_map[i].stringlen;
  798. }
  799. }
  800. BUG();
  801. return -1;
  802. }
  803. static inline int
  804. match_who(struct nfs4_ace *ace, uid_t owner, gid_t group, uid_t who)
  805. {
  806. switch (ace->whotype) {
  807. case NFS4_ACL_WHO_NAMED:
  808. return who == ace->who;
  809. case NFS4_ACL_WHO_OWNER:
  810. return who == owner;
  811. case NFS4_ACL_WHO_GROUP:
  812. return who == group;
  813. case NFS4_ACL_WHO_EVERYONE:
  814. return 1;
  815. default:
  816. return 0;
  817. }
  818. }
  819. EXPORT_SYMBOL(nfs4_acl_new);
  820. EXPORT_SYMBOL(nfs4_acl_free);
  821. EXPORT_SYMBOL(nfs4_acl_add_ace);
  822. EXPORT_SYMBOL(nfs4_acl_get_whotype);
  823. EXPORT_SYMBOL(nfs4_acl_write_who);