]>
Commit | Line | Data |
---|---|---|
bcb02034 SF |
1 | /* |
2 | * fs/cifs/cifsacl.c | |
3 | * | |
4 | * Copyright (C) International Business Machines Corp., 2007 | |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | |
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 | /* security id for everyone */ | |
25 | static const struct cifs_sid sid_everyone = | |
26 | {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; | |
27 | /* group users */ | |
28 | static const struct cifs_sid sid_user = | |
29 | {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; | |
30 | ||
31 | static int parse_sid(struct cifs_sid *psid, char *end_of_acl) | |
32 | { | |
33 | /* BB need to add parm so we can store the SID BB */ | |
34 | ||
35 | /* validate that we do not go past end of acl */ | |
36 | if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) { | |
37 | cERROR(1, ("ACL to small to parse SID")); | |
38 | return -EINVAL; | |
39 | } | |
40 | #ifdef CONFIG_CIFS_DEBUG2 | |
41 | cFYI(1, ("revision %d num_auth %d First subauth 0x%x", | |
42 | psid->revision, psid->num_auth, psid->sub_auth[0])); | |
43 | ||
44 | /* BB add length check to make sure that we do not have huge num auths | |
45 | and therefore go off the end */ | |
46 | cFYI(1, ("RID 0x%x", le32_to_cpu(psid->sub_auth[psid->num_auth]))); | |
47 | #endif | |
48 | return 0; | |
49 | } | |
50 | ||
51 | /* Convert CIFS ACL to POSIX form */ | |
52 | int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len) | |
53 | { | |
54 | int i; | |
55 | int num_aces = 0; | |
56 | int acl_size; | |
57 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; | |
58 | struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ | |
59 | struct cifs_ntace **ppntace; | |
60 | struct cifs_ace **ppace; | |
61 | char *acl_base; | |
62 | char *end_of_acl = ((char *)pntsd) + acl_len; | |
63 | ||
64 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + | |
65 | cpu_to_le32(pntsd->osidoffset)); | |
66 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + | |
67 | cpu_to_le32(pntsd->gsidoffset)); | |
68 | dacl_ptr = (struct cifs_acl *)((char *)pntsd + | |
69 | cpu_to_le32(pntsd->dacloffset)); | |
70 | #ifdef CONFIG_CIFS_DEBUG2 | |
71 | cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " | |
72 | "sacloffset 0x%x dacloffset 0x%x", | |
73 | pntsd->revision, pntsd->type, | |
74 | pntsd->osidoffset, pntsd->gsidoffset, pntsd->sacloffset, | |
75 | pntsd->dacloffset)); | |
76 | #endif | |
77 | rc = parse_sid(owner_sid_ptr, end_of_acl); | |
78 | if (rc) | |
79 | return rc; | |
80 | ||
81 | rc = parse_sid(group_sid_ptr, end_of_acl); | |
82 | if (rc) | |
83 | return rc; | |
84 | ||
85 | /* cifscred->uid = owner_sid_ptr->rid; | |
86 | cifscred->gid = group_sid_ptr->rid; | |
87 | memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, | |
88 | sizeof (struct cifs_sid)); | |
89 | memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, | |
90 | sizeof (struct cifs_sid)); */ | |
91 | ||
92 | num_aces = cpu_to_le32(dacl_ptr->num_aces); | |
93 | cFYI(1, ("num aces %d", num_aces)); | |
94 | if (num_aces > 0) { | |
95 | ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *), | |
96 | GFP_KERNEL); | |
97 | ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), | |
98 | GFP_KERNEL); | |
99 | ||
100 | /* cifscred->cecount = dacl_ptr->num_aces; | |
101 | cifscred->ntaces = kmalloc(num_aces * | |
102 | sizeof(struct cifs_ntace *), GFP_KERNEL); | |
103 | cifscred->aces = kmalloc(num_aces * | |
104 | sizeof(struct cifs_ace *), GFP_KERNEL);*/ | |
105 | ||
106 | acl_base = (char *)dacl_ptr; | |
107 | acl_size = sizeof(struct cifs_acl); | |
108 | ||
109 | for (i = 0; i < num_aces; ++i) { | |
110 | ppntace[i] = (struct cifs_ntace *) | |
111 | (acl_base + acl_size); | |
112 | ppace[i] = (struct cifs_ace *) | |
113 | ((char *)ppntace[i] + | |
114 | sizeof(struct cifs_ntace)); | |
115 | ||
116 | /* memcpy((void *)(&(cifscred->ntaces[i])), | |
117 | (void *)ntace_ptrptr[i], | |
118 | sizeof(struct cifs_ntace)); | |
119 | memcpy((void *)(&(cifscred->aces[i])), | |
120 | (void *)ace_ptrptr[i], | |
121 | sizeof(struct cifs_ace)); */ | |
122 | ||
123 | acl_base = (char *)ppntace[i]; | |
124 | acl_size = cpu_to_le32(ppntace[i]->size); | |
125 | #ifdef CONFIG_CIFS_DEBUG2 | |
126 | cFYI(1, ("ACE revision:%d", ppace[i]->revision)); | |
127 | #endif | |
128 | } | |
129 | kfree(ppace); | |
130 | kfree(ppntace); | |
131 | } | |
132 | ||
133 | return (0); | |
134 | } |