return;
}
+/*
+ * Fill in the special SID based on the mode. See
+ * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
+ */
+unsigned int setup_special_mode_ACE(struct cifs_ace *pntace, __u64 nmode)
+{
+ int i;
+ unsigned int ace_size = 28;
+
+ pntace->type = ACCESS_DENIED_ACE_TYPE;
+ pntace->flags = 0x0;
+ pntace->access_req = 0;
+ pntace->sid.num_subauth = 3;
+ pntace->sid.revision = 1;
+ for (i = 0; i < NUM_AUTHS; i++)
+ pntace->sid.authority[i] = sid_unix_NFS_mode.authority[i];
+
+ pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
+ pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
+ pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
+
+ /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
+ pntace->size = cpu_to_le16(ace_size);
+ return ace_size;
+}
static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid)
if (modefromsid) {
struct cifs_ace *pntace =
(struct cifs_ace *)((char *)pnndacl + size);
- int i;
- pntace->type = ACCESS_ALLOWED;
- pntace->flags = 0x0;
- pntace->access_req = 0;
- pntace->sid.num_subauth = 3;
- pntace->sid.revision = 1;
- for (i = 0; i < NUM_AUTHS; i++)
- pntace->sid.authority[i] =
- sid_unix_NFS_mode.authority[i];
- pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0];
- pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1];
- pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777);
-
- /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */
- pntace->size = cpu_to_le16(28);
- size += 28;
+ size += setup_special_mode_ACE(pntace, nmode);
num_aces++;
}
} __packed;
/* Meaning of 'Control' field flags */
-#define ACL_CONTROL_SR 0x0001 /* Self relative */
-#define ACL_CONTROL_RM 0x0002 /* Resource manager control bits */
-#define ACL_CONTROL_PS 0x0004 /* SACL protected from inherits */
-#define ACL_CONTROL_PD 0x0008 /* DACL protected from inherits */
-#define ACL_CONTROL_SI 0x0010 /* SACL Auto-Inherited */
-#define ACL_CONTROL_DI 0x0020 /* DACL Auto-Inherited */
-#define ACL_CONTROL_SC 0x0040 /* SACL computed through inheritance */
-#define ACL_CONTROL_DC 0x0080 /* DACL computed through inheritence */
-#define ACL_CONTROL_SS 0x0100 /* Create server ACL */
-#define ACL_CONTROL_DT 0x0200 /* DACL provided by trusteed source */
-#define ACL_CONTROL_SD 0x0400 /* SACL defaulted */
-#define ACL_CONTROL_SP 0x0800 /* SACL is present on object */
-#define ACL_CONTROL_DD 0x1000 /* DACL defaulted */
-#define ACL_CONTROL_DP 0x2000 /* DACL is present on object */
-#define ACL_CONTROL_GD 0x4000 /* Group was defaulted */
-#define ACL_CONTROL_OD 0x8000 /* User was defaulted */
+#define ACL_CONTROL_SR 0x8000 /* Self relative */
+#define ACL_CONTROL_RM 0x4000 /* Resource manager control bits */
+#define ACL_CONTROL_PS 0x2000 /* SACL protected from inherits */
+#define ACL_CONTROL_PD 0x1000 /* DACL protected from inherits */
+#define ACL_CONTROL_SI 0x0800 /* SACL Auto-Inherited */
+#define ACL_CONTROL_DI 0x0400 /* DACL Auto-Inherited */
+#define ACL_CONTROL_SC 0x0200 /* SACL computed through inheritance */
+#define ACL_CONTROL_DC 0x0100 /* DACL computed through inheritence */
+#define ACL_CONTROL_SS 0x0080 /* Create server ACL */
+#define ACL_CONTROL_DT 0x0040 /* DACL provided by trusted source */
+#define ACL_CONTROL_SD 0x0020 /* SACL defaulted */
+#define ACL_CONTROL_SP 0x0010 /* SACL is present on object */
+#define ACL_CONTROL_DD 0x0008 /* DACL defaulted */
+#define ACL_CONTROL_DP 0x0004 /* DACL is present on object */
+#define ACL_CONTROL_GD 0x0002 /* Group was defaulted */
+#define ACL_CONTROL_OD 0x0001 /* User was defaulted */
/* Meaning of AclRevision flags */
#define ACL_REVISION 0x02 /* See section 2.4.4.1 of MS-DTYP */
const struct cifs_fid *, u32 *);
extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
const char *, int);
+extern unsigned int setup_special_mode_ACE(struct cifs_ace *pace, __u64 nmode);
extern void dequeue_mid(struct mid_q_entry *mid, bool malformed);
extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
return 0;
}
+/* See MS-SMB2 2.2.13.2.2 and MS-DTYP 2.4.6 */
+static struct crt_sd_ctxt *
+create_sd_buf(umode_t mode, unsigned int *len)
+{
+ struct crt_sd_ctxt *buf;
+ struct cifs_ace *pace;
+ unsigned int sdlen, acelen;
+
+ *len = roundup(sizeof(struct crt_sd_ctxt) + sizeof(struct cifs_ace), 8);
+ buf = kzalloc(*len, GFP_KERNEL);
+ if (buf == NULL)
+ return buf;
+
+ sdlen = sizeof(struct smb3_sd) + sizeof(struct smb3_acl) +
+ sizeof(struct cifs_ace);
+
+ buf->ccontext.DataOffset = cpu_to_le16(offsetof
+ (struct crt_sd_ctxt, sd));
+ buf->ccontext.DataLength = cpu_to_le32(sdlen);
+ buf->ccontext.NameOffset = cpu_to_le16(offsetof
+ (struct crt_sd_ctxt, Name));
+ buf->ccontext.NameLength = cpu_to_le16(4);
+ /* SMB2_CREATE_SD_BUFFER_TOKEN is "SecD" */
+ buf->Name[0] = 'S';
+ buf->Name[1] = 'e';
+ buf->Name[2] = 'c';
+ buf->Name[3] = 'D';
+ buf->sd.Revision = 1; /* Must be one see MS-DTYP 2.4.6 */
+ /*
+ * ACL is "self relative" ie ACL is stored in contiguous block of memory
+ * and "DP" ie the DACL is present
+ */
+ buf->sd.Control = cpu_to_le16(ACL_CONTROL_SR | ACL_CONTROL_DP);
+
+ /* offset owner, group and Sbz1 and SACL are all zero */
+ buf->sd.OffsetDacl = cpu_to_le32(sizeof(struct smb3_sd));
+ buf->acl.AclRevision = ACL_REVISION; /* See 2.4.4.1 of MS-DTYP */
+
+ /* create one ACE to hold the mode embedded in reserved special SID */
+ pace = (struct cifs_ace *)(sizeof(struct crt_sd_ctxt) + (char *)buf);
+ acelen = setup_special_mode_ACE(pace, (__u64)mode);
+ buf->acl.AclSize = cpu_to_le16(sizeof(struct cifs_acl) + acelen);
+ buf->acl.AceCount = cpu_to_le16(1);
+ return buf;
+}
+
+static int
+add_sd_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode)
+{
+ struct smb2_create_req *req = iov[0].iov_base;
+ unsigned int num = *num_iovec;
+ unsigned int len = 0;
+
+ iov[num].iov_base = create_sd_buf(mode, &len);
+ if (iov[num].iov_base == NULL)
+ return -ENOMEM;
+ iov[num].iov_len = len;
+ if (!req->CreateContextsOffset)
+ req->CreateContextsOffset = cpu_to_le32(
+ sizeof(struct smb2_create_req) +
+ iov[num - 1].iov_len);
+ le32_add_cpu(&req->CreateContextsLength, len);
+ *num_iovec = num + 1;
+ return 0;
+}
+
static struct crt_query_id_ctxt *
create_query_id_buf(void)
{
return rc;
}
- if ((oparms->disposition == FILE_CREATE) &&
+ if ((oparms->disposition != FILE_OPEN) &&
(oparms->mode != ACL_NO_MODE)) {
if (n_iov > 2) {
struct create_context *ccontext =
cpu_to_le32(iov[n_iov-1].iov_len);
}
- /* rc = add_sd_context(iov, &n_iov, oparms->mode); */
+ cifs_dbg(FYI, "add sd with mode 0x%x\n", oparms->mode);
+ rc = add_sd_context(iov, &n_iov, oparms->mode);
if (rc)
return rc;
}
#define _SMB2PDU_H
#include <net/sock.h>
+#include <cifsacl.h>
/*
* Note that, due to trying to use names similar to the protocol specifications,
__u8 Name[8];
} __packed;
+struct crt_sd_ctxt {
+ struct create_context ccontext;
+ __u8 Name[8];
+ struct smb3_sd sd;
+ struct smb3_acl acl;
+ /* Followed by at least 4 ACEs */
+} __packed;
+
+
#define COPY_CHUNK_RES_KEY_SIZE 24
struct resume_key_req {
char ResumeKey[COPY_CHUNK_RES_KEY_SIZE];