[CIFS] Support for CIFS ACLs (part 1)
Add code to be able to dump CIFS ACL information when Query Posix ACL with cifsacl mount parm enabled. Signed-off-by: Shirish Pargoankar <shirishp@us.ibm.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
		
							parent
							
								
									2224f4e5d5
								
							
						
					
					
						commit
						442aa310f3
					
				| @ -22,12 +22,42 @@ | ||||
| #ifndef _CIFSACL_H | ||||
| #define _CIFSACL_H | ||||
| 
 | ||||
| struct cifs_ntsd { | ||||
| 	__u16 revision; /* revision level */ | ||||
| 	__u16 type; | ||||
| 	__u32 osidoffset; | ||||
| 	__u32 gsidoffset; | ||||
| 	__u32 sacloffset; | ||||
| 	__u32 dacloffset; | ||||
| } __attribute__((packed)); | ||||
| 
 | ||||
| struct cifs_sid { | ||||
| 	__u8 revision; /* revision level */ | ||||
| 	__u8 num_subauths; | ||||
| 	__u8 num_auth; | ||||
| 	__u8 authority[6]; | ||||
| 	__u32 sub_auth[4]; | ||||
| 	/* next sub_auth if any ... */ | ||||
| 	__u32 rid; | ||||
| } __attribute__((packed)); | ||||
| 
 | ||||
| struct cifs_acl { | ||||
| 	__u16 revision; /* revision level */ | ||||
| 	__u16 size; | ||||
| 	__u32 num_aces; | ||||
| } __attribute__((packed)); | ||||
| 
 | ||||
| struct cifs_ntace { | ||||
| 	__u8 type; | ||||
| 	__u8 flags; | ||||
| 	__u16 size; | ||||
| 	__u32 access_req; | ||||
| } __attribute__((packed)); | ||||
| 
 | ||||
| struct cifs_ace { | ||||
| 	__u8 revision; /* revision level */ | ||||
| 	__u8 num_auth; | ||||
| 	__u8 authority[6]; | ||||
| 	__u32 sub_auth[4]; | ||||
| 	__u32 rid; | ||||
| } __attribute__((packed)); | ||||
| 
 | ||||
| /* everyone */ | ||||
|  | ||||
| @ -19,6 +19,7 @@ | ||||
| #include <linux/in.h> | ||||
| #include <linux/in6.h> | ||||
| #include "cifs_fs_sb.h" | ||||
| #include "cifsacl.h" | ||||
| /*
 | ||||
|  * The sizes of various internal tables and strings | ||||
|  */ | ||||
| @ -115,6 +116,17 @@ struct mac_key { | ||||
| 	} data; | ||||
| }; | ||||
| 
 | ||||
| struct cifs_cred { | ||||
| 	int uid; | ||||
| 	int gid; | ||||
| 	int mode; | ||||
| 	int cecount; | ||||
| 	struct cifs_sid osid; | ||||
| 	struct cifs_sid gsid; | ||||
| 	struct cifs_ntace *ntaces; | ||||
| 	struct cifs_ace *aces; | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  ***************************************************************** | ||||
|  * Except the CIFS PDUs themselves all the | ||||
|  | ||||
| @ -3048,17 +3048,110 @@ static const struct cifs_sid sid_everyone = | ||||
| static const struct cifs_sid sid_user = | ||||
| 		{1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; | ||||
| 
 | ||||
| /* Convert CIFS ACL to POSIX form */ | ||||
| static int parse_sec_desc(struct cifs_sid *psec_desc, int acl_len) | ||||
| static void parse_sid(struct cifs_sid * psid, char * end_of_acl) | ||||
| { | ||||
| 	return 0; | ||||
| 	/* BB need to add parm so we can store the SID BB */ | ||||
| 
 | ||||
| 	/* validate that we do not go past end of acl */ | ||||
| 	if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) { | ||||
| 		cERROR(1, ("ACL to small to parse SID")); | ||||
| 		return; | ||||
| 	} | ||||
| #ifdef CONFIG_CIFS_DEBUG2 | ||||
| 	cFYI(1, ("revision %d num_auth %d First subauth 0x%x", | ||||
| 		psid->revision, psid->num_auth, psid->sub_auth[0])); | ||||
| 
 | ||||
| 	/* BB add length check to make sure that we do not have huge num auths
 | ||||
| 	      and therefore go off the end */ | ||||
| 	cFYI(1, ("RID 0x%x", le32_to_cpu(psid->sub_auth[psid->num_auth]))); | ||||
| #endif | ||||
| 	return; | ||||
| } | ||||
| 
 | ||||
| /* Convert CIFS ACL to POSIX form */ | ||||
| static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len) | ||||
| { | ||||
| 	int i; | ||||
| 	int num_aces = 0; | ||||
| 	int acl_size; | ||||
| 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr; | ||||
| 	struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ | ||||
| 	struct cifs_ntace **ppntace; | ||||
| 	struct cifs_ace **ppace; | ||||
| 	char *acl_base; | ||||
| 	char *end_of_acl = ((char *)pntsd) + acl_len; | ||||
| 
 | ||||
| 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + | ||||
| 				cpu_to_le32(pntsd->osidoffset)); | ||||
| 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd + | ||||
| 				cpu_to_le32(pntsd->gsidoffset)); | ||||
| 	dacl_ptr = (struct cifs_acl *)((char *)pntsd + | ||||
| 				cpu_to_le32(pntsd->dacloffset)); | ||||
| #ifdef CONFIG_CIFS_DEBUG2 | ||||
| 	cFYI(1,("revision %d type 0x%x ooffset 0x%x goffset 0x%x " | ||||
| 		"sacloffset 0x%x dacloffset 0x%x", pntsd->revision, pntsd->type, | ||||
| 		pntsd->osidoffset, pntsd->gsidoffset, pntsd->sacloffset, | ||||
| 		pntsd->dacloffset)); | ||||
| #endif | ||||
| 	parse_sid(owner_sid_ptr, end_of_acl); | ||||
| 	parse_sid(group_sid_ptr, end_of_acl); | ||||
| 
 | ||||
| /*	cifscred->uid = owner_sid_ptr->rid;
 | ||||
| 	cifscred->gid = group_sid_ptr->rid; | ||||
| 	memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, | ||||
| 			sizeof (struct cifs_sid)); | ||||
| 	memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, | ||||
| 			sizeof (struct cifs_sid)); */ | ||||
| 
 | ||||
| 	num_aces = cpu_to_le32(dacl_ptr->num_aces); | ||||
| 	cFYI(1, ("num aces %d", num_aces)); | ||||
| 	if (num_aces  > 0) { | ||||
| 		ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *), | ||||
| 				GFP_KERNEL); | ||||
| 		ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), | ||||
| 				GFP_KERNEL); | ||||
| 
 | ||||
| /*		cifscred->cecount = dacl_ptr->num_aces;
 | ||||
| 		cifscred->ntaces = kmalloc(num_aces * | ||||
| 				sizeof(struct cifs_ntace *), GFP_KERNEL); | ||||
| 		cifscred->aces = kmalloc(num_aces * | ||||
| 				sizeof(struct cifs_ace *), GFP_KERNEL);*/ | ||||
| 
 | ||||
| 		acl_base = (char *)dacl_ptr; | ||||
| 		acl_size = sizeof(struct cifs_acl); | ||||
| 
 | ||||
| 		for (i = 0; i < num_aces; ++i) { | ||||
| 			ppntace[i] = (struct cifs_ntace *) | ||||
| 						(acl_base + acl_size); | ||||
| 			ppace[i] = (struct cifs_ace *) | ||||
| 					((char *)ppntace[i] + | ||||
| 					sizeof(struct cifs_ntace)); | ||||
| 
 | ||||
| /*			memcpy((void *)(&(cifscred->ntaces[i])),
 | ||||
| 				(void *)ntace_ptrptr[i], | ||||
| 				sizeof(struct cifs_ntace)); | ||||
| 			memcpy((void *)(&(cifscred->aces[i])), | ||||
| 				(void *)ace_ptrptr[i], | ||||
| 				sizeof(struct cifs_ace)); */ | ||||
| 
 | ||||
| 			acl_base = (char *)ppntace[i]; | ||||
| 			acl_size = cpu_to_le32(ppntace[i]->size); | ||||
| #ifdef CONFIG_CIFS_DEBUG2 | ||||
| 			cFYI(1, ("ACE revision:%d", ppace[i]->revision)); | ||||
| 		} | ||||
| #endif | ||||
| 		kfree(ppace); | ||||
| 		kfree(ppntace); | ||||
| 	} | ||||
| 
 | ||||
| 	return (0); | ||||
| } | ||||
| 
 | ||||
| /* Get Security Descriptor (by handle) from remote server for a file or dir */ | ||||
| int | ||||
| CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | ||||
| 		/* BB fix up return info */ char *acl_inf, const int buflen, | ||||
| 		  const int acl_type /* ACCESS/DEFAULT not sure implication */) | ||||
| 		  const int acl_type) | ||||
| { | ||||
| 	int rc = 0; | ||||
| 	int buf_type = 0; | ||||
| @ -3088,7 +3181,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | ||||
| 	if (rc) { | ||||
| 		cFYI(1, ("Send error in QuerySecDesc = %d", rc)); | ||||
| 	} else {                /* decode response */ | ||||
| 		struct cifs_sid *psec_desc; | ||||
| 		struct cifs_ntsd *psec_desc; | ||||
| 		__le32 * parm; | ||||
| 		int parm_len; | ||||
| 		int data_len; | ||||
|  | ||||
| @ -1742,9 +1742,9 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, | ||||
| 			cFYI(1, ("very large write cap")); | ||||
| #endif /* CIFS_DEBUG2 */ | ||||
| 		if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { | ||||
| 			if (vol_info == NULL) | ||||
| 			if (vol_info == NULL) { | ||||
| 				cFYI(1, ("resetting capabilities failed")); | ||||
| 			else | ||||
| 			} else | ||||
| 				cERROR(1, ("Negotiating Unix capabilities " | ||||
| 					   "with the server failed.  Consider " | ||||
| 					   "mounting with the Unix Extensions\n" | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user