diff options
-rw-r--r-- | fs/cifs/cifsacl.h | 34 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 12 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 101 | ||||
-rw-r--r-- | fs/cifs/connect.c | 4 |
4 files changed, 143 insertions, 8 deletions
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h index 5eff35d6e564..97d03dc8169c 100644 --- a/fs/cifs/cifsacl.h +++ b/fs/cifs/cifsacl.h | |||
@@ -22,12 +22,42 @@ | |||
22 | #ifndef _CIFSACL_H | 22 | #ifndef _CIFSACL_H |
23 | #define _CIFSACL_H | 23 | #define _CIFSACL_H |
24 | 24 | ||
25 | struct cifs_ntsd { | ||
26 | __u16 revision; /* revision level */ | ||
27 | __u16 type; | ||
28 | __u32 osidoffset; | ||
29 | __u32 gsidoffset; | ||
30 | __u32 sacloffset; | ||
31 | __u32 dacloffset; | ||
32 | } __attribute__((packed)); | ||
33 | |||
25 | struct cifs_sid { | 34 | struct cifs_sid { |
26 | __u8 revision; /* revision level */ | 35 | __u8 revision; /* revision level */ |
27 | __u8 num_subauths; | 36 | __u8 num_auth; |
37 | __u8 authority[6]; | ||
38 | __u32 sub_auth[4]; | ||
39 | __u32 rid; | ||
40 | } __attribute__((packed)); | ||
41 | |||
42 | struct cifs_acl { | ||
43 | __u16 revision; /* revision level */ | ||
44 | __u16 size; | ||
45 | __u32 num_aces; | ||
46 | } __attribute__((packed)); | ||
47 | |||
48 | struct cifs_ntace { | ||
49 | __u8 type; | ||
50 | __u8 flags; | ||
51 | __u16 size; | ||
52 | __u32 access_req; | ||
53 | } __attribute__((packed)); | ||
54 | |||
55 | struct cifs_ace { | ||
56 | __u8 revision; /* revision level */ | ||
57 | __u8 num_auth; | ||
28 | __u8 authority[6]; | 58 | __u8 authority[6]; |
29 | __u32 sub_auth[4]; | 59 | __u32 sub_auth[4]; |
30 | /* next sub_auth if any ... */ | 60 | __u32 rid; |
31 | } __attribute__((packed)); | 61 | } __attribute__((packed)); |
32 | 62 | ||
33 | /* everyone */ | 63 | /* everyone */ |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index b98742fc3b5a..bb468de4f474 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/in.h> | 19 | #include <linux/in.h> |
20 | #include <linux/in6.h> | 20 | #include <linux/in6.h> |
21 | #include "cifs_fs_sb.h" | 21 | #include "cifs_fs_sb.h" |
22 | #include "cifsacl.h" | ||
22 | /* | 23 | /* |
23 | * The sizes of various internal tables and strings | 24 | * The sizes of various internal tables and strings |
24 | */ | 25 | */ |
@@ -115,6 +116,17 @@ struct mac_key { | |||
115 | } data; | 116 | } data; |
116 | }; | 117 | }; |
117 | 118 | ||
119 | struct cifs_cred { | ||
120 | int uid; | ||
121 | int gid; | ||
122 | int mode; | ||
123 | int cecount; | ||
124 | struct cifs_sid osid; | ||
125 | struct cifs_sid gsid; | ||
126 | struct cifs_ntace *ntaces; | ||
127 | struct cifs_ace *aces; | ||
128 | }; | ||
129 | |||
118 | /* | 130 | /* |
119 | ***************************************************************** | 131 | ***************************************************************** |
120 | * Except the CIFS PDUs themselves all the | 132 | * Except the CIFS PDUs themselves all the |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index f33c89c36039..46c2bb455124 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -3048,17 +3048,110 @@ static const struct cifs_sid sid_everyone = | |||
3048 | static const struct cifs_sid sid_user = | 3048 | static const struct cifs_sid sid_user = |
3049 | {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; | 3049 | {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; |
3050 | 3050 | ||
3051 | static void parse_sid(struct cifs_sid * psid, char * end_of_acl) | ||
3052 | { | ||
3053 | /* BB need to add parm so we can store the SID BB */ | ||
3054 | |||
3055 | /* validate that we do not go past end of acl */ | ||
3056 | if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) { | ||
3057 | cERROR(1, ("ACL to small to parse SID")); | ||
3058 | return; | ||
3059 | } | ||
3060 | #ifdef CONFIG_CIFS_DEBUG2 | ||
3061 | cFYI(1, ("revision %d num_auth %d First subauth 0x%x", | ||
3062 | psid->revision, psid->num_auth, psid->sub_auth[0])); | ||
3063 | |||
3064 | /* BB add length check to make sure that we do not have huge num auths | ||
3065 | and therefore go off the end */ | ||
3066 | cFYI(1, ("RID 0x%x", le32_to_cpu(psid->sub_auth[psid->num_auth]))); | ||
3067 | #endif | ||
3068 | return; | ||
3069 | } | ||
3070 | |||
3051 | /* Convert CIFS ACL to POSIX form */ | 3071 | /* Convert CIFS ACL to POSIX form */ |
3052 | static int parse_sec_desc(struct cifs_sid *psec_desc, int acl_len) | 3072 | static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len) |
3053 | { | 3073 | { |
3054 | return 0; | 3074 | int i; |
3075 | int num_aces = 0; | ||
3076 | int acl_size; | ||
3077 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; | ||
3078 | struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ | ||
3079 | struct cifs_ntace **ppntace; | ||
3080 | struct cifs_ace **ppace; | ||
3081 | char *acl_base; | ||
3082 | char *end_of_acl = ((char *)pntsd) + acl_len; | ||
3083 | |||
3084 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + | ||
3085 | cpu_to_le32(pntsd->osidoffset)); | ||
3086 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + | ||
3087 | cpu_to_le32(pntsd->gsidoffset)); | ||
3088 | dacl_ptr = (struct cifs_acl *)((char *)pntsd + | ||
3089 | cpu_to_le32(pntsd->dacloffset)); | ||
3090 | #ifdef CONFIG_CIFS_DEBUG2 | ||
3091 | cFYI(1,("revision %d type 0x%x ooffset 0x%x goffset 0x%x " | ||
3092 | "sacloffset 0x%x dacloffset 0x%x", pntsd->revision, pntsd->type, | ||
3093 | pntsd->osidoffset, pntsd->gsidoffset, pntsd->sacloffset, | ||
3094 | pntsd->dacloffset)); | ||
3095 | #endif | ||
3096 | parse_sid(owner_sid_ptr, end_of_acl); | ||
3097 | parse_sid(group_sid_ptr, end_of_acl); | ||
3098 | |||
3099 | /* cifscred->uid = owner_sid_ptr->rid; | ||
3100 | cifscred->gid = group_sid_ptr->rid; | ||
3101 | memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, | ||
3102 | sizeof (struct cifs_sid)); | ||
3103 | memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, | ||
3104 | sizeof (struct cifs_sid)); */ | ||
3105 | |||
3106 | num_aces = cpu_to_le32(dacl_ptr->num_aces); | ||
3107 | cFYI(1, ("num aces %d", num_aces)); | ||
3108 | if (num_aces > 0) { | ||
3109 | ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *), | ||
3110 | GFP_KERNEL); | ||
3111 | ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), | ||
3112 | GFP_KERNEL); | ||
3113 | |||
3114 | /* cifscred->cecount = dacl_ptr->num_aces; | ||
3115 | cifscred->ntaces = kmalloc(num_aces * | ||
3116 | sizeof(struct cifs_ntace *), GFP_KERNEL); | ||
3117 | cifscred->aces = kmalloc(num_aces * | ||
3118 | sizeof(struct cifs_ace *), GFP_KERNEL);*/ | ||
3119 | |||
3120 | acl_base = (char *)dacl_ptr; | ||
3121 | acl_size = sizeof(struct cifs_acl); | ||
3122 | |||
3123 | for (i = 0; i < num_aces; ++i) { | ||
3124 | ppntace[i] = (struct cifs_ntace *) | ||
3125 | (acl_base + acl_size); | ||
3126 | ppace[i] = (struct cifs_ace *) | ||
3127 | ((char *)ppntace[i] + | ||
3128 | sizeof(struct cifs_ntace)); | ||
3129 | |||
3130 | /* memcpy((void *)(&(cifscred->ntaces[i])), | ||
3131 | (void *)ntace_ptrptr[i], | ||
3132 | sizeof(struct cifs_ntace)); | ||
3133 | memcpy((void *)(&(cifscred->aces[i])), | ||
3134 | (void *)ace_ptrptr[i], | ||
3135 | sizeof(struct cifs_ace)); */ | ||
3136 | |||
3137 | acl_base = (char *)ppntace[i]; | ||
3138 | acl_size = cpu_to_le32(ppntace[i]->size); | ||
3139 | #ifdef CONFIG_CIFS_DEBUG2 | ||
3140 | cFYI(1, ("ACE revision:%d", ppace[i]->revision)); | ||
3141 | } | ||
3142 | #endif | ||
3143 | kfree(ppace); | ||
3144 | kfree(ppntace); | ||
3145 | } | ||
3146 | |||
3147 | return (0); | ||
3055 | } | 3148 | } |
3056 | 3149 | ||
3057 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ | 3150 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ |
3058 | int | 3151 | int |
3059 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | 3152 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, |
3060 | /* BB fix up return info */ char *acl_inf, const int buflen, | 3153 | /* BB fix up return info */ char *acl_inf, const int buflen, |
3061 | const int acl_type /* ACCESS/DEFAULT not sure implication */) | 3154 | const int acl_type) |
3062 | { | 3155 | { |
3063 | int rc = 0; | 3156 | int rc = 0; |
3064 | int buf_type = 0; | 3157 | int buf_type = 0; |
@@ -3088,7 +3181,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
3088 | if (rc) { | 3181 | if (rc) { |
3089 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); | 3182 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); |
3090 | } else { /* decode response */ | 3183 | } else { /* decode response */ |
3091 | struct cifs_sid *psec_desc; | 3184 | struct cifs_ntsd *psec_desc; |
3092 | __le32 * parm; | 3185 | __le32 * parm; |
3093 | int parm_len; | 3186 | int parm_len; |
3094 | int data_len; | 3187 | int data_len; |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 5c3cc6487e59..e43cb880f54a 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1742,9 +1742,9 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, | |||
1742 | cFYI(1, ("very large write cap")); | 1742 | cFYI(1, ("very large write cap")); |
1743 | #endif /* CIFS_DEBUG2 */ | 1743 | #endif /* CIFS_DEBUG2 */ |
1744 | if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { | 1744 | if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { |
1745 | if (vol_info == NULL) | 1745 | if (vol_info == NULL) { |
1746 | cFYI(1, ("resetting capabilities failed")); | 1746 | cFYI(1, ("resetting capabilities failed")); |
1747 | else | 1747 | } else |
1748 | cERROR(1, ("Negotiating Unix capabilities " | 1748 | cERROR(1, ("Negotiating Unix capabilities " |
1749 | "with the server failed. Consider " | 1749 | "with the server failed. Consider " |
1750 | "mounting with the Unix Extensions\n" | 1750 | "mounting with the Unix Extensions\n" |