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