@@ -2317,28 +2317,73 @@ add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp)
2317
2317
return 0 ;
2318
2318
}
2319
2319
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
+
2320
2342
/* See MS-SMB2 2.2.13.2.2 and MS-DTYP 2.4.6 */
2321
2343
static 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 )
2323
2345
{
2324
2346
struct crt_sd_ctxt * buf ;
2325
2347
struct cifs_ace * pace ;
2326
2348
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
+ }
2327
2361
2328
- * len = roundup (sizeof (struct crt_sd_ctxt ) + sizeof (struct cifs_ace ) * 2 ,
2329
- 8 );
2330
2362
buf = kzalloc (* len , GFP_KERNEL );
2331
2363
if (buf == NULL )
2332
2364
return buf ;
2333
2365
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
+
2334
2375
sdlen = sizeof (struct smb3_sd ) + sizeof (struct smb3_acl ) +
2335
2376
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
+ }
2336
2382
2337
2383
buf -> ccontext .DataOffset = cpu_to_le16 (offsetof
2338
2384
(struct crt_sd_ctxt , sd ));
2339
2385
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 ));
2342
2387
buf -> ccontext .NameLength = cpu_to_le16 (4 );
2343
2388
/* SMB2_CREATE_SD_BUFFER_TOKEN is "SecD" */
2344
2389
buf -> Name [0 ] = 'S' ;
@@ -2359,23 +2404,34 @@ create_sd_buf(umode_t mode, unsigned int *len)
2359
2404
/* create one ACE to hold the mode embedded in reserved special SID */
2360
2405
pace = (struct cifs_ace * )(sizeof (struct crt_sd_ctxt ) + (char * )buf );
2361
2406
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
+
2362
2417
/* and one more ACE to allow access for authenticated users */
2363
2418
pace = (struct cifs_ace * )(acelen + (sizeof (struct crt_sd_ctxt ) +
2364
2419
(char * )buf ));
2365
2420
acelen += setup_authusers_ACE (pace );
2421
+
2366
2422
buf -> acl .AclSize = cpu_to_le16 (sizeof (struct cifs_acl ) + acelen );
2367
- buf -> acl . AceCount = cpu_to_le16 ( 2 );
2423
+
2368
2424
return buf ;
2369
2425
}
2370
2426
2371
2427
static 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 )
2373
2429
{
2374
2430
struct smb2_create_req * req = iov [0 ].iov_base ;
2375
2431
unsigned int num = * num_iovec ;
2376
2432
unsigned int len = 0 ;
2377
2433
2378
- iov [num ].iov_base = create_sd_buf (mode , & len );
2434
+ iov [num ].iov_base = create_sd_buf (mode , set_owner , & len );
2379
2435
if (iov [num ].iov_base == NULL )
2380
2436
return - ENOMEM ;
2381
2437
iov [num ].iov_len = len ;
@@ -2764,21 +2820,35 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
2764
2820
return rc ;
2765
2821
}
2766
2822
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 ;
2776
2833
}
2777
2834
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
+ }
2782
2852
}
2783
2853
2784
2854
if (n_iov > 2 ) {
0 commit comments