diff options
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r-- | fs/cifs/cifssmb.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 618542b8ce0b..9409524e4bf8 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -3156,6 +3156,71 @@ qsec_out: | |||
3156 | /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ | 3156 | /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ |
3157 | return rc; | 3157 | return rc; |
3158 | } | 3158 | } |
3159 | |||
3160 | int | ||
3161 | CIFSSMBSetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | ||
3162 | struct cifs_ntsd *pntsd, __u32 acllen) | ||
3163 | { | ||
3164 | __u16 byte_count, param_count, data_count, param_offset, data_offset; | ||
3165 | int rc = 0; | ||
3166 | int bytes_returned = 0; | ||
3167 | SET_SEC_DESC_REQ *pSMB = NULL; | ||
3168 | NTRANSACT_RSP *pSMBr = NULL; | ||
3169 | |||
3170 | setCifsAclRetry: | ||
3171 | rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, | ||
3172 | (void **) &pSMBr); | ||
3173 | if (rc) | ||
3174 | return (rc); | ||
3175 | |||
3176 | pSMB->MaxSetupCount = 0; | ||
3177 | pSMB->Reserved = 0; | ||
3178 | |||
3179 | param_count = 8; | ||
3180 | param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4; | ||
3181 | data_count = acllen; | ||
3182 | data_offset = param_offset + param_count; | ||
3183 | byte_count = 3 /* pad */ + param_count; | ||
3184 | |||
3185 | pSMB->DataCount = cpu_to_le32(data_count); | ||
3186 | pSMB->TotalDataCount = pSMB->DataCount; | ||
3187 | pSMB->MaxParameterCount = cpu_to_le32(4); | ||
3188 | pSMB->MaxDataCount = cpu_to_le32(16384); | ||
3189 | pSMB->ParameterCount = cpu_to_le32(param_count); | ||
3190 | pSMB->ParameterOffset = cpu_to_le32(param_offset); | ||
3191 | pSMB->TotalParameterCount = pSMB->ParameterCount; | ||
3192 | pSMB->DataOffset = cpu_to_le32(data_offset); | ||
3193 | pSMB->SetupCount = 0; | ||
3194 | pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC); | ||
3195 | pSMB->ByteCount = cpu_to_le16(byte_count+data_count); | ||
3196 | |||
3197 | pSMB->Fid = fid; /* file handle always le */ | ||
3198 | pSMB->Reserved2 = 0; | ||
3199 | pSMB->AclFlags = cpu_to_le32(CIFS_ACL_DACL); | ||
3200 | |||
3201 | if (pntsd && acllen) { | ||
3202 | memcpy((char *) &pSMBr->hdr.Protocol + data_offset, | ||
3203 | (char *) pntsd, | ||
3204 | acllen); | ||
3205 | pSMB->hdr.smb_buf_length += (byte_count + data_count); | ||
3206 | |||
3207 | } else | ||
3208 | pSMB->hdr.smb_buf_length += byte_count; | ||
3209 | |||
3210 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | ||
3211 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | ||
3212 | |||
3213 | cFYI(1, ("SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc)); | ||
3214 | if (rc) | ||
3215 | cFYI(1, ("Set CIFS ACL returned %d", rc)); | ||
3216 | cifs_buf_release(pSMB); | ||
3217 | |||
3218 | if (rc == -EAGAIN) | ||
3219 | goto setCifsAclRetry; | ||
3220 | |||
3221 | return (rc); | ||
3222 | } | ||
3223 | |||
3159 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 3224 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
3160 | 3225 | ||
3161 | /* Legacy Query Path Information call for lookup to old servers such | 3226 | /* Legacy Query Path Information call for lookup to old servers such |