diff options
author | Jeff Layton <jlayton@redhat.com> | 2012-12-10 06:10:44 -0500 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-12-11 12:48:49 -0500 |
commit | 193cdd8a293007d1a1ad252cf66b2dc5b793d2d0 (patch) | |
tree | 2bfefe36dd1c6ca0d42fc35b00bf323b8d41e5b3 /fs/cifs | |
parent | 6d8b59d712e95d257ee16f80b579677e5e1bf33c (diff) |
cifs: fix SID binary to string conversion
The authority fields are supposed to be represented by a single 48-bit
value. It's also supposed to represent the value as hex if it's equal to
or greater than 2^32. This is documented in MS-DTYP, section 2.4.2.1.
Also, fix up the max string length to account for this fix.
Acked-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifsacl.c | 25 | ||||
-rw-r--r-- | fs/cifs/cifsacl.h | 8 |
2 files changed, 24 insertions, 9 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 8dd9212ffef5..75c1ee699143 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -94,6 +94,7 @@ sid_to_key_str(struct cifs_sid *sidptr, unsigned int type) | |||
94 | int i, len; | 94 | int i, len; |
95 | unsigned int saval; | 95 | unsigned int saval; |
96 | char *sidstr, *strptr; | 96 | char *sidstr, *strptr; |
97 | unsigned long long id_auth_val; | ||
97 | 98 | ||
98 | /* 3 bytes for prefix */ | 99 | /* 3 bytes for prefix */ |
99 | sidstr = kmalloc(3 + SID_STRING_BASE_SIZE + | 100 | sidstr = kmalloc(3 + SID_STRING_BASE_SIZE + |
@@ -107,12 +108,24 @@ sid_to_key_str(struct cifs_sid *sidptr, unsigned int type) | |||
107 | sidptr->revision); | 108 | sidptr->revision); |
108 | strptr += len; | 109 | strptr += len; |
109 | 110 | ||
110 | for (i = 0; i < NUM_AUTHS; ++i) { | 111 | /* The authority field is a single 48-bit number */ |
111 | if (sidptr->authority[i]) { | 112 | id_auth_val = (unsigned long long)sidptr->authority[5]; |
112 | len = sprintf(strptr, "-%hhu", sidptr->authority[i]); | 113 | id_auth_val |= (unsigned long long)sidptr->authority[4] << 8; |
113 | strptr += len; | 114 | id_auth_val |= (unsigned long long)sidptr->authority[3] << 16; |
114 | } | 115 | id_auth_val |= (unsigned long long)sidptr->authority[2] << 24; |
115 | } | 116 | id_auth_val |= (unsigned long long)sidptr->authority[1] << 32; |
117 | id_auth_val |= (unsigned long long)sidptr->authority[0] << 48; | ||
118 | |||
119 | /* | ||
120 | * MS-DTYP states that if the authority is >= 2^32, then it should be | ||
121 | * expressed as a hex value. | ||
122 | */ | ||
123 | if (id_auth_val <= UINT_MAX) | ||
124 | len = sprintf(strptr, "-%llu", id_auth_val); | ||
125 | else | ||
126 | len = sprintf(strptr, "-0x%llx", id_auth_val); | ||
127 | |||
128 | strptr += len; | ||
116 | 129 | ||
117 | for (i = 0; i < sidptr->num_subauth; ++i) { | 130 | for (i = 0; i < sidptr->num_subauth; ++i) { |
118 | saval = le32_to_cpu(sidptr->sub_auth[i]); | 131 | saval = le32_to_cpu(sidptr->sub_auth[i]); |
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h index a445405f80d0..4f3884835267 100644 --- a/fs/cifs/cifsacl.h +++ b/fs/cifs/cifsacl.h | |||
@@ -55,12 +55,14 @@ | |||
55 | * u8: max 3 bytes in decimal | 55 | * u8: max 3 bytes in decimal |
56 | * u32: max 10 bytes in decimal | 56 | * u32: max 10 bytes in decimal |
57 | * | 57 | * |
58 | * "S-" + 3 bytes for version field + 4 bytes for each authority field (3 bytes | 58 | * "S-" + 3 bytes for version field + 15 for authority field + NULL terminator |
59 | * per number + 1 for '-') + NULL terminator. | 59 | * |
60 | * For authority field, max is when all 6 values are non-zero and it must be | ||
61 | * represented in hex. So "-0x" + 12 hex digits. | ||
60 | * | 62 | * |
61 | * Add 11 bytes for each subauthority field (10 bytes each + 1 for '-') | 63 | * Add 11 bytes for each subauthority field (10 bytes each + 1 for '-') |
62 | */ | 64 | */ |
63 | #define SID_STRING_BASE_SIZE (2 + 3 + (4 * NUM_AUTHS) + 1) | 65 | #define SID_STRING_BASE_SIZE (2 + 3 + 15 + 1) |
64 | #define SID_STRING_SUBAUTH_SIZE (11) /* size of a single subauth string */ | 66 | #define SID_STRING_SUBAUTH_SIZE (11) /* size of a single subauth string */ |
65 | 67 | ||
66 | struct cifs_ntsd { | 68 | struct cifs_ntsd { |