diff options
-rw-r--r-- | fs/cifs/cifsacl.c | 325 | ||||
-rw-r--r-- | fs/cifs/cifsacl.h | 24 |
2 files changed, 325 insertions, 24 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 061fc3afd841..a4aa0f0af5c3 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -54,7 +54,33 @@ static const struct cifs_sid sid_authusers = { | |||
54 | /* group users */ | 54 | /* group users */ |
55 | static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; | 55 | static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; |
56 | 56 | ||
57 | static const struct cred *root_cred; | 57 | const struct cred *root_cred; |
58 | |||
59 | static void | ||
60 | shrink_idmap_tree(struct rb_root *root, int nr_to_scan, int *nr_rem, | ||
61 | int *nr_del) | ||
62 | { | ||
63 | struct rb_node *node; | ||
64 | struct rb_node *tmp; | ||
65 | struct cifs_sid_id *psidid; | ||
66 | |||
67 | node = rb_first(root); | ||
68 | while (node) { | ||
69 | tmp = node; | ||
70 | node = rb_next(tmp); | ||
71 | psidid = rb_entry(tmp, struct cifs_sid_id, rbnode); | ||
72 | if (nr_to_scan == 0 || *nr_del == nr_to_scan) | ||
73 | ++(*nr_rem); | ||
74 | else { | ||
75 | if (time_after(jiffies, psidid->time + SID_MAP_EXPIRE) | ||
76 | && psidid->refcount == 0) { | ||
77 | rb_erase(tmp, root); | ||
78 | ++(*nr_del); | ||
79 | } else | ||
80 | ++(*nr_rem); | ||
81 | } | ||
82 | } | ||
83 | } | ||
58 | 84 | ||
59 | /* | 85 | /* |
60 | * Run idmap cache shrinker. | 86 | * Run idmap cache shrinker. |
@@ -62,9 +88,21 @@ static const struct cred *root_cred; | |||
62 | static int | 88 | static int |
63 | cifs_idmap_shrinker(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask) | 89 | cifs_idmap_shrinker(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask) |
64 | { | 90 | { |
65 | /* Use a pruning scheme in a subsequent patch instead */ | 91 | int nr_del = 0; |
66 | cifs_destroy_idmaptrees(); | 92 | int nr_rem = 0; |
67 | return 0; | 93 | struct rb_root *root; |
94 | |||
95 | root = &uidtree; | ||
96 | spin_lock(&siduidlock); | ||
97 | shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del); | ||
98 | spin_unlock(&siduidlock); | ||
99 | |||
100 | root = &gidtree; | ||
101 | spin_lock(&sidgidlock); | ||
102 | shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del); | ||
103 | spin_unlock(&sidgidlock); | ||
104 | |||
105 | return nr_rem; | ||
68 | } | 106 | } |
69 | 107 | ||
70 | static struct shrinker cifs_shrinker = { | 108 | static struct shrinker cifs_shrinker = { |
@@ -92,7 +130,6 @@ cifs_idmap_key_destroy(struct key *key) | |||
92 | kfree(key->payload.data); | 130 | kfree(key->payload.data); |
93 | } | 131 | } |
94 | 132 | ||
95 | static | ||
96 | struct key_type cifs_idmap_key_type = { | 133 | struct key_type cifs_idmap_key_type = { |
97 | .name = "cifs.cifs_idmap", | 134 | .name = "cifs.cifs_idmap", |
98 | .instantiate = cifs_idmap_key_instantiate, | 135 | .instantiate = cifs_idmap_key_instantiate, |
@@ -101,6 +138,220 @@ struct key_type cifs_idmap_key_type = { | |||
101 | .match = user_match, | 138 | .match = user_match, |
102 | }; | 139 | }; |
103 | 140 | ||
141 | static void | ||
142 | sid_to_str(struct cifs_sid *sidptr, char *sidstr) | ||
143 | { | ||
144 | int i; | ||
145 | unsigned long saval; | ||
146 | char *strptr; | ||
147 | |||
148 | strptr = sidstr; | ||
149 | |||
150 | sprintf(strptr, "%s", "S"); | ||
151 | strptr = sidstr + strlen(sidstr); | ||
152 | |||
153 | sprintf(strptr, "-%d", sidptr->revision); | ||
154 | strptr = sidstr + strlen(sidstr); | ||
155 | |||
156 | for (i = 0; i < 6; ++i) { | ||
157 | if (sidptr->authority[i]) { | ||
158 | sprintf(strptr, "-%d", sidptr->authority[i]); | ||
159 | strptr = sidstr + strlen(sidstr); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | for (i = 0; i < sidptr->num_subauth; ++i) { | ||
164 | saval = le32_to_cpu(sidptr->sub_auth[i]); | ||
165 | sprintf(strptr, "-%ld", saval); | ||
166 | strptr = sidstr + strlen(sidstr); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static void | ||
171 | id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr, | ||
172 | struct cifs_sid_id **psidid, char *typestr) | ||
173 | { | ||
174 | int rc; | ||
175 | char *strptr; | ||
176 | struct rb_node *node = root->rb_node; | ||
177 | struct rb_node *parent = NULL; | ||
178 | struct rb_node **linkto = &(root->rb_node); | ||
179 | struct cifs_sid_id *lsidid; | ||
180 | |||
181 | while (node) { | ||
182 | lsidid = rb_entry(node, struct cifs_sid_id, rbnode); | ||
183 | parent = node; | ||
184 | rc = compare_sids(sidptr, &((lsidid)->sid)); | ||
185 | if (rc > 0) { | ||
186 | linkto = &(node->rb_left); | ||
187 | node = node->rb_left; | ||
188 | } else if (rc < 0) { | ||
189 | linkto = &(node->rb_right); | ||
190 | node = node->rb_right; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid)); | ||
195 | (*psidid)->time = jiffies - (SID_MAP_RETRY + 1); | ||
196 | (*psidid)->refcount = 0; | ||
197 | |||
198 | sprintf((*psidid)->sidstr, "%s", typestr); | ||
199 | strptr = (*psidid)->sidstr + strlen((*psidid)->sidstr); | ||
200 | sid_to_str(&(*psidid)->sid, strptr); | ||
201 | |||
202 | clear_bit(SID_ID_PENDING, &(*psidid)->state); | ||
203 | clear_bit(SID_ID_MAPPED, &(*psidid)->state); | ||
204 | |||
205 | rb_link_node(&(*psidid)->rbnode, parent, linkto); | ||
206 | rb_insert_color(&(*psidid)->rbnode, root); | ||
207 | } | ||
208 | |||
209 | static struct cifs_sid_id * | ||
210 | id_rb_search(struct rb_root *root, struct cifs_sid *sidptr) | ||
211 | { | ||
212 | int rc; | ||
213 | struct rb_node *node = root->rb_node; | ||
214 | struct rb_node *parent = NULL; | ||
215 | struct rb_node **linkto = &(root->rb_node); | ||
216 | struct cifs_sid_id *lsidid; | ||
217 | |||
218 | while (node) { | ||
219 | lsidid = rb_entry(node, struct cifs_sid_id, rbnode); | ||
220 | parent = node; | ||
221 | rc = compare_sids(sidptr, &((lsidid)->sid)); | ||
222 | if (rc > 0) { | ||
223 | linkto = &(node->rb_left); | ||
224 | node = node->rb_left; | ||
225 | } else if (rc < 0) { | ||
226 | linkto = &(node->rb_right); | ||
227 | node = node->rb_right; | ||
228 | } else /* node found */ | ||
229 | return lsidid; | ||
230 | } | ||
231 | |||
232 | return NULL; | ||
233 | } | ||
234 | |||
235 | static int | ||
236 | sidid_pending_wait(void *unused) | ||
237 | { | ||
238 | schedule(); | ||
239 | return signal_pending(current) ? -ERESTARTSYS : 0; | ||
240 | } | ||
241 | |||
242 | static int | ||
243 | sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid, | ||
244 | struct cifs_fattr *fattr, uint sidtype) | ||
245 | { | ||
246 | int rc; | ||
247 | unsigned long cid; | ||
248 | struct key *idkey; | ||
249 | const struct cred *saved_cred; | ||
250 | struct cifs_sid_id *psidid, *npsidid; | ||
251 | struct rb_root *cidtree; | ||
252 | spinlock_t *cidlock; | ||
253 | |||
254 | if (sidtype == SIDOWNER) { | ||
255 | cid = cifs_sb->mnt_uid; /* default uid, in case upcall fails */ | ||
256 | cidlock = &siduidlock; | ||
257 | cidtree = &uidtree; | ||
258 | } else if (sidtype == SIDGROUP) { | ||
259 | cid = cifs_sb->mnt_gid; /* default gid, in case upcall fails */ | ||
260 | cidlock = &sidgidlock; | ||
261 | cidtree = &gidtree; | ||
262 | } else | ||
263 | return -ENOENT; | ||
264 | |||
265 | spin_lock(cidlock); | ||
266 | psidid = id_rb_search(cidtree, psid); | ||
267 | |||
268 | if (!psidid) { /* node does not exist, allocate one & attempt adding */ | ||
269 | spin_unlock(cidlock); | ||
270 | npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL); | ||
271 | if (!npsidid) | ||
272 | return -ENOMEM; | ||
273 | |||
274 | npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL); | ||
275 | if (!npsidid->sidstr) { | ||
276 | kfree(npsidid); | ||
277 | return -ENOMEM; | ||
278 | } | ||
279 | |||
280 | spin_lock(cidlock); | ||
281 | psidid = id_rb_search(cidtree, psid); | ||
282 | if (psidid) { /* node happened to get inserted meanwhile */ | ||
283 | ++psidid->refcount; | ||
284 | spin_unlock(cidlock); | ||
285 | kfree(npsidid->sidstr); | ||
286 | kfree(npsidid); | ||
287 | } else { | ||
288 | psidid = npsidid; | ||
289 | id_rb_insert(cidtree, psid, &psidid, | ||
290 | sidtype == SIDOWNER ? "os:" : "gs:"); | ||
291 | ++psidid->refcount; | ||
292 | spin_unlock(cidlock); | ||
293 | } | ||
294 | } else { | ||
295 | ++psidid->refcount; | ||
296 | spin_unlock(cidlock); | ||
297 | } | ||
298 | |||
299 | /* | ||
300 | * If we are here, it is safe to access psidid and its fields | ||
301 | * since a reference was taken earlier while holding the spinlock. | ||
302 | * A reference on the node is put without holding the spinlock | ||
303 | * and it is OK to do so in this case, shrinker will not erase | ||
304 | * this node until all references are put and we do not access | ||
305 | * any fields of the node after a reference is put . | ||
306 | */ | ||
307 | if (test_bit(SID_ID_MAPPED, &psidid->state)) { | ||
308 | cid = psidid->id; | ||
309 | psidid->time = jiffies; /* update ts for accessing */ | ||
310 | goto sid_to_id_out; | ||
311 | } | ||
312 | |||
313 | if (time_after(psidid->time + SID_MAP_RETRY, jiffies)) | ||
314 | goto sid_to_id_out; | ||
315 | |||
316 | if (!test_and_set_bit(SID_ID_PENDING, &psidid->state)) { | ||
317 | saved_cred = override_creds(root_cred); | ||
318 | idkey = request_key(&cifs_idmap_key_type, psidid->sidstr, ""); | ||
319 | if (IS_ERR(idkey)) | ||
320 | cFYI(1, "%s: Can't map SID to an id", __func__); | ||
321 | else { | ||
322 | cid = *(unsigned long *)idkey->payload.value; | ||
323 | psidid->id = cid; | ||
324 | set_bit(SID_ID_MAPPED, &psidid->state); | ||
325 | key_put(idkey); | ||
326 | kfree(psidid->sidstr); | ||
327 | } | ||
328 | revert_creds(saved_cred); | ||
329 | psidid->time = jiffies; /* update ts for accessing */ | ||
330 | clear_bit(SID_ID_PENDING, &psidid->state); | ||
331 | wake_up_bit(&psidid->state, SID_ID_PENDING); | ||
332 | } else { | ||
333 | rc = wait_on_bit(&psidid->state, SID_ID_PENDING, | ||
334 | sidid_pending_wait, TASK_INTERRUPTIBLE); | ||
335 | if (rc) { | ||
336 | cFYI(1, "%s: sidid_pending_wait interrupted %d", | ||
337 | __func__, rc); | ||
338 | --psidid->refcount; /* decremented without spinlock */ | ||
339 | return rc; | ||
340 | } | ||
341 | if (test_bit(SID_ID_MAPPED, &psidid->state)) | ||
342 | cid = psidid->id; | ||
343 | } | ||
344 | |||
345 | sid_to_id_out: | ||
346 | --psidid->refcount; /* decremented without spinlock */ | ||
347 | if (sidtype == SIDOWNER) | ||
348 | fattr->cf_uid = cid; | ||
349 | else | ||
350 | fattr->cf_gid = cid; | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | |||
104 | int | 355 | int |
105 | init_cifs_idmap(void) | 356 | init_cifs_idmap(void) |
106 | { | 357 | { |
@@ -242,16 +493,24 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) | |||
242 | int num_subauth, num_sat, num_saw; | 493 | int num_subauth, num_sat, num_saw; |
243 | 494 | ||
244 | if ((!ctsid) || (!cwsid)) | 495 | if ((!ctsid) || (!cwsid)) |
245 | return 0; | 496 | return 1; |
246 | 497 | ||
247 | /* compare the revision */ | 498 | /* compare the revision */ |
248 | if (ctsid->revision != cwsid->revision) | 499 | if (ctsid->revision != cwsid->revision) { |
249 | return 0; | 500 | if (ctsid->revision > cwsid->revision) |
501 | return 1; | ||
502 | else | ||
503 | return -1; | ||
504 | } | ||
250 | 505 | ||
251 | /* compare all of the six auth values */ | 506 | /* compare all of the six auth values */ |
252 | for (i = 0; i < 6; ++i) { | 507 | for (i = 0; i < 6; ++i) { |
253 | if (ctsid->authority[i] != cwsid->authority[i]) | 508 | if (ctsid->authority[i] != cwsid->authority[i]) { |
254 | return 0; | 509 | if (ctsid->authority[i] > cwsid->authority[i]) |
510 | return 1; | ||
511 | else | ||
512 | return -1; | ||
513 | } | ||
255 | } | 514 | } |
256 | 515 | ||
257 | /* compare all of the subauth values if any */ | 516 | /* compare all of the subauth values if any */ |
@@ -260,12 +519,16 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid) | |||
260 | num_subauth = num_sat < num_saw ? num_sat : num_saw; | 519 | num_subauth = num_sat < num_saw ? num_sat : num_saw; |
261 | if (num_subauth) { | 520 | if (num_subauth) { |
262 | for (i = 0; i < num_subauth; ++i) { | 521 | for (i = 0; i < num_subauth; ++i) { |
263 | if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) | 522 | if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) { |
264 | return 0; | 523 | if (ctsid->sub_auth[i] > cwsid->sub_auth[i]) |
524 | return 1; | ||
525 | else | ||
526 | return -1; | ||
527 | } | ||
265 | } | 528 | } |
266 | } | 529 | } |
267 | 530 | ||
268 | return 1; /* sids compare/match */ | 531 | return 0; /* sids compare/match */ |
269 | } | 532 | } |
270 | 533 | ||
271 | 534 | ||
@@ -520,22 +783,22 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | |||
520 | #ifdef CONFIG_CIFS_DEBUG2 | 783 | #ifdef CONFIG_CIFS_DEBUG2 |
521 | dump_ace(ppace[i], end_of_acl); | 784 | dump_ace(ppace[i], end_of_acl); |
522 | #endif | 785 | #endif |
523 | if (compare_sids(&(ppace[i]->sid), pownersid)) | 786 | if (compare_sids(&(ppace[i]->sid), pownersid) == 0) |
524 | access_flags_to_mode(ppace[i]->access_req, | 787 | access_flags_to_mode(ppace[i]->access_req, |
525 | ppace[i]->type, | 788 | ppace[i]->type, |
526 | &fattr->cf_mode, | 789 | &fattr->cf_mode, |
527 | &user_mask); | 790 | &user_mask); |
528 | if (compare_sids(&(ppace[i]->sid), pgrpsid)) | 791 | if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) |
529 | access_flags_to_mode(ppace[i]->access_req, | 792 | access_flags_to_mode(ppace[i]->access_req, |
530 | ppace[i]->type, | 793 | ppace[i]->type, |
531 | &fattr->cf_mode, | 794 | &fattr->cf_mode, |
532 | &group_mask); | 795 | &group_mask); |
533 | if (compare_sids(&(ppace[i]->sid), &sid_everyone)) | 796 | if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) |
534 | access_flags_to_mode(ppace[i]->access_req, | 797 | access_flags_to_mode(ppace[i]->access_req, |
535 | ppace[i]->type, | 798 | ppace[i]->type, |
536 | &fattr->cf_mode, | 799 | &fattr->cf_mode, |
537 | &other_mask); | 800 | &other_mask); |
538 | if (compare_sids(&(ppace[i]->sid), &sid_authusers)) | 801 | if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0) |
539 | access_flags_to_mode(ppace[i]->access_req, | 802 | access_flags_to_mode(ppace[i]->access_req, |
540 | ppace[i]->type, | 803 | ppace[i]->type, |
541 | &fattr->cf_mode, | 804 | &fattr->cf_mode, |
@@ -613,10 +876,10 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl) | |||
613 | 876 | ||
614 | 877 | ||
615 | /* Convert CIFS ACL to POSIX form */ | 878 | /* Convert CIFS ACL to POSIX form */ |
616 | static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, | 879 | static int parse_sec_desc(struct cifs_sb_info *cifs_sb, |
617 | struct cifs_fattr *fattr) | 880 | struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr) |
618 | { | 881 | { |
619 | int rc; | 882 | int rc = 0; |
620 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; | 883 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; |
621 | struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ | 884 | struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ |
622 | char *end_of_acl = ((char *)pntsd) + acl_len; | 885 | char *end_of_acl = ((char *)pntsd) + acl_len; |
@@ -638,12 +901,26 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, | |||
638 | le32_to_cpu(pntsd->sacloffset), dacloffset); | 901 | le32_to_cpu(pntsd->sacloffset), dacloffset); |
639 | /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */ | 902 | /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */ |
640 | rc = parse_sid(owner_sid_ptr, end_of_acl); | 903 | rc = parse_sid(owner_sid_ptr, end_of_acl); |
641 | if (rc) | 904 | if (rc) { |
905 | cFYI(1, "%s: Error %d parsing Owner SID", __func__, rc); | ||
642 | return rc; | 906 | return rc; |
907 | } | ||
908 | rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER); | ||
909 | if (rc) { | ||
910 | cFYI(1, "%s: Error %d mapping Owner SID to uid", __func__, rc); | ||
911 | return rc; | ||
912 | } | ||
643 | 913 | ||
644 | rc = parse_sid(group_sid_ptr, end_of_acl); | 914 | rc = parse_sid(group_sid_ptr, end_of_acl); |
645 | if (rc) | 915 | if (rc) { |
916 | cFYI(1, "%s: Error %d mapping Owner SID to gid", __func__, rc); | ||
646 | return rc; | 917 | return rc; |
918 | } | ||
919 | rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP); | ||
920 | if (rc) { | ||
921 | cFYI(1, "%s: Error %d mapping Group SID to gid", __func__, rc); | ||
922 | return rc; | ||
923 | } | ||
647 | 924 | ||
648 | if (dacloffset) | 925 | if (dacloffset) |
649 | parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, | 926 | parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, |
@@ -658,7 +935,7 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, | |||
658 | memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, | 935 | memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, |
659 | sizeof(struct cifs_sid)); */ | 936 | sizeof(struct cifs_sid)); */ |
660 | 937 | ||
661 | return 0; | 938 | return rc; |
662 | } | 939 | } |
663 | 940 | ||
664 | 941 | ||
@@ -865,7 +1142,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, | |||
865 | rc = PTR_ERR(pntsd); | 1142 | rc = PTR_ERR(pntsd); |
866 | cERROR(1, "%s: error %d getting sec desc", __func__, rc); | 1143 | cERROR(1, "%s: error %d getting sec desc", __func__, rc); |
867 | } else { | 1144 | } else { |
868 | rc = parse_sec_desc(pntsd, acllen, fattr); | 1145 | rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr); |
869 | kfree(pntsd); | 1146 | kfree(pntsd); |
870 | if (rc) | 1147 | if (rc) |
871 | cERROR(1, "parse sec desc failed rc = %d", rc); | 1148 | cERROR(1, "parse sec desc failed rc = %d", rc); |
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h index c4ae7d036563..757cf5aec3ee 100644 --- a/fs/cifs/cifsacl.h +++ b/fs/cifs/cifsacl.h | |||
@@ -39,6 +39,15 @@ | |||
39 | #define ACCESS_ALLOWED 0 | 39 | #define ACCESS_ALLOWED 0 |
40 | #define ACCESS_DENIED 1 | 40 | #define ACCESS_DENIED 1 |
41 | 41 | ||
42 | #define SIDOWNER 1 | ||
43 | #define SIDGROUP 2 | ||
44 | #define SIDLEN 150 /* S- 1 revision- 6 authorities- max 5 sub authorities */ | ||
45 | |||
46 | #define SID_ID_MAPPED 0 | ||
47 | #define SID_ID_PENDING 1 | ||
48 | #define SID_MAP_EXPIRE (3600 * HZ) /* map entry expires after one hour */ | ||
49 | #define SID_MAP_RETRY (300 * HZ) /* wait 5 minutes for next attempt to map */ | ||
50 | |||
42 | struct cifs_ntsd { | 51 | struct cifs_ntsd { |
43 | __le16 revision; /* revision level */ | 52 | __le16 revision; /* revision level */ |
44 | __le16 type; | 53 | __le16 type; |
@@ -74,6 +83,21 @@ struct cifs_wksid { | |||
74 | char sidname[SIDNAMELENGTH]; | 83 | char sidname[SIDNAMELENGTH]; |
75 | } __attribute__((packed)); | 84 | } __attribute__((packed)); |
76 | 85 | ||
86 | struct cifs_sid_id { | ||
87 | unsigned int refcount; /* increment with spinlock, decrement without */ | ||
88 | unsigned long id; | ||
89 | unsigned long time; | ||
90 | unsigned long state; | ||
91 | char *sidstr; | ||
92 | struct rb_node rbnode; | ||
93 | struct cifs_sid sid; | ||
94 | }; | ||
95 | |||
96 | #ifdef __KERNEL__ | ||
97 | extern struct key_type cifs_idmap_key_type; | ||
98 | extern const struct cred *root_cred; | ||
99 | #endif /* KERNEL */ | ||
100 | |||
77 | extern int match_sid(struct cifs_sid *); | 101 | extern int match_sid(struct cifs_sid *); |
78 | extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *); | 102 | extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *); |
79 | 103 | ||