Changeset 751 for trunk/server/source3/smbd/posix_acls.c
- Timestamp:
- Nov 29, 2012, 1:59:04 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server/source3/smbd/posix_acls.c
r745 r751 1131 1131 ****************************************************************************/ 1132 1132 1133 #define FILE_SPECIFIC_READ_BITS (FILE_READ_DATA|FILE_READ_EA |FILE_READ_ATTRIBUTES)1134 #define FILE_SPECIFIC_WRITE_BITS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA |FILE_WRITE_ATTRIBUTES)1133 #define FILE_SPECIFIC_READ_BITS (FILE_READ_DATA|FILE_READ_EA) 1134 #define FILE_SPECIFIC_WRITE_BITS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA) 1135 1135 #define FILE_SPECIFIC_EXECUTE_BITS (FILE_EXECUTE) 1136 1136 … … 1354 1354 ****************************************************************************/ 1355 1355 1356 static bool ensure_canon_entry_valid(connection_struct *conn, canon_ace **pp_ace, 1357 const struct share_params *params, 1358 const bool is_directory, 1359 const struct dom_sid *pfile_owner_sid, 1360 const struct dom_sid *pfile_grp_sid, 1361 const SMB_STRUCT_STAT *pst, 1362 bool setting_acl) 1356 static bool ensure_canon_entry_valid(connection_struct *conn, 1357 canon_ace **pp_ace, 1358 bool is_default_acl, 1359 const struct share_params *params, 1360 const bool is_directory, 1361 const struct dom_sid *pfile_owner_sid, 1362 const struct dom_sid *pfile_grp_sid, 1363 const SMB_STRUCT_STAT *pst, 1364 bool setting_acl) 1363 1365 { 1364 1366 canon_ace *pace; … … 1371 1373 if (pace->type == SMB_ACL_USER_OBJ) { 1372 1374 1373 if (setting_acl )1375 if (setting_acl && !is_default_acl) { 1374 1376 apply_default_perms(params, is_directory, pace, S_IRUSR); 1377 } 1375 1378 got_user = True; 1376 1379 … … 1381 1384 */ 1382 1385 1383 if (setting_acl )1386 if (setting_acl && !is_default_acl) { 1384 1387 apply_default_perms(params, is_directory, pace, S_IRGRP); 1388 } 1385 1389 got_grp = True; 1386 1390 … … 1391 1395 */ 1392 1396 1393 if (setting_acl )1397 if (setting_acl && !is_default_acl) { 1394 1398 apply_default_perms(params, is_directory, pace, S_IROTH); 1399 } 1395 1400 got_other = True; 1396 1401 pace_other = pace; 1402 1403 } else if (pace->type == SMB_ACL_USER || pace->type == SMB_ACL_GROUP) { 1404 1405 /* 1406 * Ensure create mask/force create mode is respected on set. 1407 */ 1408 1409 if (setting_acl && !is_default_acl) { 1410 apply_default_perms(params, is_directory, pace, S_IRGRP); 1411 } 1397 1412 } 1398 1413 } … … 1410 1425 pace->trustee = *pfile_owner_sid; 1411 1426 pace->attr = ALLOW_ACE; 1427 /* Start with existing permissions, principle of least 1428 surprises for the user. */ 1429 pace->perms = pst->st_ex_mode; 1412 1430 1413 1431 if (setting_acl) { 1414 1432 /* See if the owning user is in any of the other groups in 1415 the ACE . If so, OR in the permissions from that group. */1416 1417 bool group_matched = False; 1433 the ACE, or if there's a matching user entry. 1434 If so, OR in the permissions from that entry. */ 1435 1418 1436 canon_ace *pace_iter; 1419 1437 1420 1438 for (pace_iter = *pp_ace; pace_iter; pace_iter = pace_iter->next) { 1421 if (pace_iter->type == SMB_ACL_GROUP_OBJ || pace_iter->type == SMB_ACL_GROUP) { 1439 if (pace_iter->type == SMB_ACL_USER && 1440 pace_iter->unix_ug.uid == pace->unix_ug.uid) { 1441 pace->perms |= pace_iter->perms; 1442 } else if (pace_iter->type == SMB_ACL_GROUP_OBJ || pace_iter->type == SMB_ACL_GROUP) { 1422 1443 if (uid_entry_in_group(conn, pace, pace_iter)) { 1423 1444 pace->perms |= pace_iter->perms; 1424 group_matched = True;1425 1445 } 1426 1446 } 1427 1447 } 1428 1448 1429 /* If we only got an "everyone" perm, just use that. */1430 if (!group_matched) {1449 if (pace->perms == 0) { 1450 /* If we only got an "everyone" perm, just use that. */ 1431 1451 if (got_other) 1432 1452 pace->perms = pace_other->perms; 1433 else1434 pace->perms = 0; 1435 }1436 1437 apply_default_perms(params, is_directory, pace, S_IRUSR);1453 } 1454 1455 if (!is_default_acl) { 1456 apply_default_perms(params, is_directory, pace, S_IRUSR); 1457 } 1438 1458 } else { 1439 1459 pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR); … … 1461 1481 else 1462 1482 pace->perms = 0; 1463 apply_default_perms(params, is_directory, pace, S_IRGRP); 1483 if (!is_default_acl) { 1484 apply_default_perms(params, is_directory, pace, S_IRGRP); 1485 } 1464 1486 } else { 1465 1487 pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRGRP, S_IWGRP, S_IXGRP); … … 1483 1505 if (setting_acl) { 1484 1506 pace->perms = 0; 1485 apply_default_perms(params, is_directory, pace, S_IROTH); 1507 if (!is_default_acl) { 1508 apply_default_perms(params, is_directory, pace, S_IROTH); 1509 } 1486 1510 } else 1487 1511 pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IROTH, S_IWOTH, S_IXOTH); … … 1497 1521 If it does not have them, check if there are any entries where the trustee is the 1498 1522 file owner or the owning group, and map these to SMB_ACL_USER_OBJ and SMB_ACL_GROUP_OBJ. 1523 Note we must not do this to default directory ACLs. 1499 1524 ****************************************************************************/ 1500 1525 … … 1536 1561 if (!got_group_obj) 1537 1562 DEBUG(10,("check_owning_objs: ACL is missing an owning group entry.\n")); 1538 }1539 1540 /****************************************************************************1541 If an ACE entry is SMB_ACL_USER_OBJ and not CREATOR_OWNER, map to SMB_ACL_USER.1542 If an ACE entry is SMB_ACL_GROUP_OBJ and not CREATOR_GROUP, map to SMB_ACL_GROUP1543 ****************************************************************************/1544 1545 static bool dup_owning_ace(canon_ace *dir_ace, canon_ace *ace)1546 {1547 /* dir ace must be followings.1548 SMB_ACL_USER_OBJ : trustee(CREATOR_OWNER) -> Posix ACL d:u::perm1549 SMB_ACL_USER : not trustee -> Posix ACL u:user:perm1550 SMB_ACL_USER_OBJ : trustee -> convert to SMB_ACL_USER : trustee1551 Posix ACL u:trustee:perm1552 1553 SMB_ACL_GROUP_OBJ: trustee(CREATOR_GROUP) -> Posix ACL d:g::perm1554 SMB_ACL_GROUP : not trustee -> Posix ACL g:group:perm1555 SMB_ACL_GROUP_OBJ: trustee -> convert to SMB_ACL_GROUP : trustee1556 Posix ACL g:trustee:perm1557 */1558 1559 if (ace->type == SMB_ACL_USER_OBJ &&1560 !(dom_sid_equal(&ace->trustee, &global_sid_Creator_Owner))) {1561 canon_ace *dup_ace = dup_canon_ace(ace);1562 1563 if (dup_ace == NULL) {1564 return false;1565 }1566 dup_ace->type = SMB_ACL_USER;1567 DLIST_ADD_END(dir_ace, dup_ace, canon_ace *);1568 }1569 1570 if (ace->type == SMB_ACL_GROUP_OBJ &&1571 !(dom_sid_equal(&ace->trustee, &global_sid_Creator_Group))) {1572 canon_ace *dup_ace = dup_canon_ace(ace);1573 1574 if (dup_ace == NULL) {1575 return false;1576 }1577 dup_ace->type = SMB_ACL_GROUP;1578 DLIST_ADD_END(dir_ace, dup_ace, canon_ace *);1579 }1580 1581 return true;1582 1563 } 1583 1564 … … 1805 1786 (SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT)) { 1806 1787 1788 canon_ace *current_dir_ace = current_ace; 1807 1789 DLIST_ADD_END(dir_ace, current_ace, canon_ace *); 1808 1790 … … 1830 1812 dbgtext("create_canon_ace_lists: adding dir ACL:\n"); 1831 1813 print_canon_ace( current_ace, 0); 1832 }1833 1834 /*1835 * We have a lossy mapping: directory ACE entries1836 * CREATOR_OWNER ------\1837 * (map to) +---> SMB_ACL_USER_OBJ1838 * owning sid ------/1839 *1840 * CREATOR_GROUP ------\1841 * (map to) +---> SMB_ACL_GROUP_OBJ1842 * primary group sid --/1843 *1844 * on set. And on read of a directory ACL1845 *1846 * SMB_ACL_USER_OBJ ----> CREATOR_OWNER1847 * SMB_ACL_GROUP_OBJ ---> CREATOR_GROUP.1848 *1849 * Deal with this on set by duplicating1850 * owning sid and primary group sid ACE1851 * entries into the directory ACL.1852 * Fix from Tsukasa Hamano <hamano@osstech.co.jp>.1853 */1854 1855 if (!dup_owning_ace(dir_ace, current_ace)) {1856 DEBUG(0,("create_canon_ace_lists: malloc fail !\n"));1857 free_canon_ace_list(file_ace);1858 free_canon_ace_list(dir_ace);1859 return false;1860 1814 } 1861 1815 … … 1894 1848 current_ace = NULL; 1895 1849 } 1850 1851 /* 1852 * current_ace is now either owned by file_ace 1853 * or is NULL. We can safely operate on current_dir_ace 1854 * to treat mapping for default acl entries differently 1855 * than access acl entries. 1856 */ 1857 1858 if (current_dir_ace->owner_type == UID_ACE) { 1859 /* 1860 * We already decided above this is a uid, 1861 * for default acls ace's only CREATOR_OWNER 1862 * maps to ACL_USER_OBJ. All other uid 1863 * ace's are ACL_USER. 1864 */ 1865 if (dom_sid_equal(¤t_dir_ace->trustee, 1866 &global_sid_Creator_Owner)) { 1867 current_dir_ace->type = SMB_ACL_USER_OBJ; 1868 } else { 1869 current_dir_ace->type = SMB_ACL_USER; 1870 } 1871 } 1872 1873 if (current_dir_ace->owner_type == GID_ACE) { 1874 /* 1875 * We already decided above this is a gid, 1876 * for default acls ace's only CREATOR_GROUP 1877 * maps to ACL_GROUP_OBJ. All other uid 1878 * ace's are ACL_GROUP. 1879 */ 1880 if (dom_sid_equal(¤t_dir_ace->trustee, 1881 &global_sid_Creator_Group)) { 1882 current_dir_ace->type = SMB_ACL_GROUP_OBJ; 1883 } else { 1884 current_dir_ace->type = SMB_ACL_GROUP; 1885 } 1886 } 1896 1887 } 1897 1888 } … … 1955 1946 } else { 1956 1947 /* 1957 * Check if we have SMB_ACL_USER_OBJ and SMB_ACL_GROUP_OBJ entries in each 1958 * ACL. If we don't have them, check if any SMB_ACL_USER/SMB_ACL_GROUP 1959 * entries can be converted to *_OBJ. Usually we will already have these 1960 * entries in the Default ACL, and the Access ACL will not have them. 1948 * Check if we have SMB_ACL_USER_OBJ and SMB_ACL_GROUP_OBJ entries in 1949 * the file ACL. If we don't have them, check if any SMB_ACL_USER/SMB_ACL_GROUP 1950 * entries can be converted to *_OBJ. Don't do this for the default 1951 * ACL, we will create them separately for this if needed inside 1952 * ensure_canon_entry_valid(). 1961 1953 */ 1962 1954 if (file_ace) { 1963 1955 check_owning_objs(file_ace, pfile_owner_sid, pfile_grp_sid); 1964 }1965 if (dir_ace) {1966 check_owning_objs(dir_ace, pfile_owner_sid, pfile_grp_sid);1967 1956 } 1968 1957 } … … 2287 2276 2288 2277 /**************************************************************************** 2289 Create a default mode that will be used if a security descriptor entry has2290 no user/group/world entries.2291 ****************************************************************************/2292 2293 static mode_t create_default_mode(files_struct *fsp, bool interitable_mode)2294 {2295 int snum = SNUM(fsp->conn);2296 mode_t and_bits = (mode_t)0;2297 mode_t or_bits = (mode_t)0;2298 mode_t mode;2299 2300 if (interitable_mode) {2301 mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE,2302 fsp->fsp_name, NULL);2303 } else {2304 mode = S_IRUSR;2305 }2306 2307 if (fsp->is_directory)2308 mode |= (S_IWUSR|S_IXUSR);2309 2310 /*2311 * Now AND with the create mode/directory mode bits then OR with the2312 * force create mode/force directory mode bits.2313 */2314 2315 if (fsp->is_directory) {2316 and_bits = lp_dir_security_mask(snum);2317 or_bits = lp_force_dir_security_mode(snum);2318 } else {2319 and_bits = lp_security_mask(snum);2320 or_bits = lp_force_security_mode(snum);2321 }2322 2323 return ((mode & and_bits)|or_bits);2324 }2325 2326 /****************************************************************************2327 2278 Unpack a struct security_descriptor into two canonical ace lists. We don't depend on this 2328 2279 succeeding. … … 2338 2289 const struct security_descriptor *psd) 2339 2290 { 2340 SMB_STRUCT_STAT st;2341 2291 canon_ace *file_ace = NULL; 2342 2292 canon_ace *dir_ace = NULL; … … 2402 2352 print_canon_ace_list( "file ace - before valid", file_ace); 2403 2353 2404 st = *pst; 2405 2406 /* 2407 * A default 3 element mode entry for a file should be r-- --- ---. 2408 * A default 3 element mode entry for a directory should be rwx --- ---. 2409 */ 2410 2411 st.st_ex_mode = create_default_mode(fsp, False); 2412 2413 if (!ensure_canon_entry_valid(fsp->conn, &file_ace, fsp->conn->params, 2414 fsp->is_directory, pfile_owner_sid, pfile_grp_sid, &st, True)) { 2354 if (!ensure_canon_entry_valid(fsp->conn, &file_ace, false, fsp->conn->params, 2355 fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) { 2415 2356 free_canon_ace_list(file_ace); 2416 2357 free_canon_ace_list(dir_ace); … … 2420 2361 print_canon_ace_list( "dir ace - before valid", dir_ace); 2421 2362 2422 /* 2423 * A default inheritable 3 element mode entry for a directory should be the 2424 * mode Samba will use to create a file within. Ensure user rwx bits are set if 2425 * it's a directory. 2426 */ 2427 2428 st.st_ex_mode = create_default_mode(fsp, True); 2429 2430 if (dir_ace && !ensure_canon_entry_valid(fsp->conn, &dir_ace, fsp->conn->params, 2431 fsp->is_directory, pfile_owner_sid, pfile_grp_sid, &st, True)) { 2363 if (dir_ace && !ensure_canon_entry_valid(fsp->conn, &dir_ace, true, fsp->conn->params, 2364 fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) { 2432 2365 free_canon_ace_list(file_ace); 2433 2366 free_canon_ace_list(dir_ace); … … 2517 2450 canon_ace *next_ace = NULL; 2518 2451 int entry_id = SMB_ACL_FIRST_ENTRY; 2452 bool is_default_acl = (the_acl_type == SMB_ACL_TYPE_DEFAULT); 2519 2453 SMB_ACL_ENTRY_T entry; 2520 2454 size_t ace_count; … … 2604 2538 ace->unix_ug = unix_ug; 2605 2539 ace->owner_type = owner_type; 2606 ace->ace_flags = get_pai_flags(pal, ace, (the_acl_type == SMB_ACL_TYPE_DEFAULT));2540 ace->ace_flags = get_pai_flags(pal, ace, is_default_acl); 2607 2541 2608 2542 DLIST_ADD(l_head, ace); … … 2613 2547 */ 2614 2548 2615 if (!ensure_canon_entry_valid(conn, &l_head, conn->params,2549 if (!ensure_canon_entry_valid(conn, &l_head, is_default_acl, conn->params, 2616 2550 S_ISDIR(psbuf->st_ex_mode), powner, pgroup, 2617 2551 psbuf, False)) … … 2623 2557 */ 2624 2558 2625 DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", the_acl_type == SMB_ACL_TYPE_ACCESS ? "Access" : "Default"));2559 DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", is_default_acl ? "Default" : "Access")); 2626 2560 2627 2561 for ( ace_count = 0, ace = l_head; ace; ace = next_ace, ace_count++) {
Note:
See TracChangeset
for help on using the changeset viewer.