@@ -2317,28 +2317,73 @@ add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp)
23172317 return 0 ;
23182318}
23192319
2320+ /* See See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx */
2321+ static void setup_owner_group_sids (char * buf )
2322+ {
2323+ struct owner_group_sids * sids = (struct owner_group_sids * )buf ;
2324+
2325+ /* Populate the user ownership fields S-1-5-88-1 */
2326+ sids -> owner .Revision = 1 ;
2327+ sids -> owner .NumAuth = 3 ;
2328+ sids -> owner .Authority [5 ] = 5 ;
2329+ sids -> owner .SubAuthorities [0 ] = cpu_to_le32 (88 );
2330+ sids -> owner .SubAuthorities [1 ] = cpu_to_le32 (1 );
2331+ sids -> owner .SubAuthorities [2 ] = cpu_to_le32 (current_fsuid ().val );
2332+
2333+ /* Populate the group ownership fields S-1-5-88-2 */
2334+ sids -> group .Revision = 1 ;
2335+ sids -> group .NumAuth = 3 ;
2336+ sids -> group .Authority [5 ] = 5 ;
2337+ sids -> group .SubAuthorities [0 ] = cpu_to_le32 (88 );
2338+ sids -> group .SubAuthorities [1 ] = cpu_to_le32 (2 );
2339+ sids -> group .SubAuthorities [2 ] = cpu_to_le32 (current_fsgid ().val );
2340+ }
2341+
23202342/* See MS-SMB2 2.2.13.2.2 and MS-DTYP 2.4.6 */
23212343static struct crt_sd_ctxt *
2322- create_sd_buf (umode_t mode , unsigned int * len )
2344+ create_sd_buf (umode_t mode , bool set_owner , unsigned int * len )
23232345{
23242346 struct crt_sd_ctxt * buf ;
23252347 struct cifs_ace * pace ;
23262348 unsigned int sdlen , acelen ;
2349+ unsigned int owner_offset = 0 ;
2350+ unsigned int group_offset = 0 ;
2351+
2352+ * len = roundup (sizeof (struct crt_sd_ctxt ) + (sizeof (struct cifs_ace ) * 2 ), 8 );
2353+
2354+ if (set_owner ) {
2355+ /* offset fields are from beginning of security descriptor not of create context */
2356+ owner_offset = sizeof (struct smb3_acl ) + (sizeof (struct cifs_ace ) * 2 );
2357+
2358+ /* sizeof(struct owner_group_sids) is already multiple of 8 so no need to round */
2359+ * len += sizeof (struct owner_group_sids );
2360+ }
23272361
2328- * len = roundup (sizeof (struct crt_sd_ctxt ) + sizeof (struct cifs_ace ) * 2 ,
2329- 8 );
23302362 buf = kzalloc (* len , GFP_KERNEL );
23312363 if (buf == NULL )
23322364 return buf ;
23332365
2366+ if (set_owner ) {
2367+ buf -> sd .OffsetOwner = cpu_to_le32 (owner_offset );
2368+ group_offset = owner_offset + sizeof (struct owner_sid );
2369+ buf -> sd .OffsetGroup = cpu_to_le32 (group_offset );
2370+ } else {
2371+ buf -> sd .OffsetOwner = 0 ;
2372+ buf -> sd .OffsetGroup = 0 ;
2373+ }
2374+
23342375 sdlen = sizeof (struct smb3_sd ) + sizeof (struct smb3_acl ) +
23352376 2 * sizeof (struct cifs_ace );
2377+ if (set_owner ) {
2378+ sdlen += sizeof (struct owner_group_sids );
2379+ setup_owner_group_sids (owner_offset + sizeof (struct create_context ) + 8 /* name */
2380+ + (char * )buf );
2381+ }
23362382
23372383 buf -> ccontext .DataOffset = cpu_to_le16 (offsetof
23382384 (struct crt_sd_ctxt , sd ));
23392385 buf -> ccontext .DataLength = cpu_to_le32 (sdlen );
2340- buf -> ccontext .NameOffset = cpu_to_le16 (offsetof
2341- (struct crt_sd_ctxt , Name ));
2386+ buf -> ccontext .NameOffset = cpu_to_le16 (offsetof(struct crt_sd_ctxt , Name ));
23422387 buf -> ccontext .NameLength = cpu_to_le16 (4 );
23432388 /* SMB2_CREATE_SD_BUFFER_TOKEN is "SecD" */
23442389 buf -> Name [0 ] = 'S' ;
@@ -2359,23 +2404,34 @@ create_sd_buf(umode_t mode, unsigned int *len)
23592404 /* create one ACE to hold the mode embedded in reserved special SID */
23602405 pace = (struct cifs_ace * )(sizeof (struct crt_sd_ctxt ) + (char * )buf );
23612406 acelen = setup_special_mode_ACE (pace , (__u64 )mode );
2407+
2408+ if (set_owner ) {
2409+ /* we do not need to reallocate buffer to add the two more ACEs. plenty of space */
2410+ pace = (struct cifs_ace * )(acelen + (sizeof (struct crt_sd_ctxt ) + (char * )buf ));
2411+ acelen += setup_special_user_owner_ACE (pace );
2412+ /* it does not appear necessary to add an ACE for the NFS group SID */
2413+ buf -> acl .AceCount = cpu_to_le16 (3 );
2414+ } else
2415+ buf -> acl .AceCount = cpu_to_le16 (2 );
2416+
23622417 /* and one more ACE to allow access for authenticated users */
23632418 pace = (struct cifs_ace * )(acelen + (sizeof (struct crt_sd_ctxt ) +
23642419 (char * )buf ));
23652420 acelen += setup_authusers_ACE (pace );
2421+
23662422 buf -> acl .AclSize = cpu_to_le16 (sizeof (struct cifs_acl ) + acelen );
2367- buf -> acl . AceCount = cpu_to_le16 ( 2 );
2423+
23682424 return buf ;
23692425}
23702426
23712427static int
2372- add_sd_context (struct kvec * iov , unsigned int * num_iovec , umode_t mode )
2428+ add_sd_context (struct kvec * iov , unsigned int * num_iovec , umode_t mode , bool set_owner )
23732429{
23742430 struct smb2_create_req * req = iov [0 ].iov_base ;
23752431 unsigned int num = * num_iovec ;
23762432 unsigned int len = 0 ;
23772433
2378- iov [num ].iov_base = create_sd_buf (mode , & len );
2434+ iov [num ].iov_base = create_sd_buf (mode , set_owner , & len );
23792435 if (iov [num ].iov_base == NULL )
23802436 return - ENOMEM ;
23812437 iov [num ].iov_len = len ;
@@ -2764,21 +2820,35 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
27642820 return rc ;
27652821 }
27662822
2767- if ((oparms -> disposition != FILE_OPEN ) &&
2768- (oparms -> cifs_sb ) &&
2769- (oparms -> cifs_sb -> mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID ) &&
2770- (oparms -> mode != ACL_NO_MODE )) {
2771- if (n_iov > 2 ) {
2772- struct create_context * ccontext =
2773- (struct create_context * )iov [n_iov - 1 ].iov_base ;
2774- ccontext -> Next =
2775- cpu_to_le32 (iov [n_iov - 1 ].iov_len );
2823+ if ((oparms -> disposition != FILE_OPEN ) && (oparms -> cifs_sb )) {
2824+ bool set_mode ;
2825+ bool set_owner ;
2826+
2827+ if ((oparms -> cifs_sb -> mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID ) &&
2828+ (oparms -> mode != ACL_NO_MODE ))
2829+ set_mode = true;
2830+ else {
2831+ set_mode = false;
2832+ oparms -> mode = ACL_NO_MODE ;
27762833 }
27772834
2778- cifs_dbg (FYI , "add sd with mode 0x%x\n" , oparms -> mode );
2779- rc = add_sd_context (iov , & n_iov , oparms -> mode );
2780- if (rc )
2781- return rc ;
2835+ if (oparms -> cifs_sb -> mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL )
2836+ set_owner = true;
2837+ else
2838+ set_owner = false;
2839+
2840+ if (set_owner | set_mode ) {
2841+ if (n_iov > 2 ) {
2842+ struct create_context * ccontext =
2843+ (struct create_context * )iov [n_iov - 1 ].iov_base ;
2844+ ccontext -> Next = cpu_to_le32 (iov [n_iov - 1 ].iov_len );
2845+ }
2846+
2847+ cifs_dbg (FYI , "add sd with mode 0x%x\n" , oparms -> mode );
2848+ rc = add_sd_context (iov , & n_iov , oparms -> mode , set_owner );
2849+ if (rc )
2850+ return rc ;
2851+ }
27822852 }
27832853
27842854 if (n_iov > 2 ) {
0 commit comments