Ignore:
Timestamp:
Nov 29, 2012, 1:59:04 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.9

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/server/source3/smbd/posix_acls.c

    r745 r751  
    11311131****************************************************************************/
    11321132
    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)
    11351135#define FILE_SPECIFIC_EXECUTE_BITS (FILE_EXECUTE)
    11361136
     
    13541354****************************************************************************/
    13551355
    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)
     1356static 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)
    13631365{
    13641366        canon_ace *pace;
     
    13711373                if (pace->type == SMB_ACL_USER_OBJ) {
    13721374
    1373                         if (setting_acl)
     1375                        if (setting_acl && !is_default_acl) {
    13741376                                apply_default_perms(params, is_directory, pace, S_IRUSR);
     1377                        }
    13751378                        got_user = True;
    13761379
     
    13811384                         */
    13821385
    1383                         if (setting_acl)
     1386                        if (setting_acl && !is_default_acl) {
    13841387                                apply_default_perms(params, is_directory, pace, S_IRGRP);
     1388                        }
    13851389                        got_grp = True;
    13861390
     
    13911395                         */
    13921396
    1393                         if (setting_acl)
     1397                        if (setting_acl && !is_default_acl) {
    13941398                                apply_default_perms(params, is_directory, pace, S_IROTH);
     1399                        }
    13951400                        got_other = True;
    13961401                        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                        }
    13971412                }
    13981413        }
     
    14101425                pace->trustee = *pfile_owner_sid;
    14111426                pace->attr = ALLOW_ACE;
     1427                /* Start with existing permissions, principle of least
     1428                   surprises for the user. */
     1429                pace->perms = pst->st_ex_mode;
    14121430
    14131431                if (setting_acl) {
    14141432                        /* 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
    14181436                        canon_ace *pace_iter;
    14191437
    14201438                        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) {
    14221443                                        if (uid_entry_in_group(conn, pace, pace_iter)) {
    14231444                                                pace->perms |= pace_iter->perms;
    1424                                                 group_matched = True;
    14251445                                        }
    14261446                                }
    14271447                        }
    14281448
    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. */
    14311451                                if (got_other)
    14321452                                        pace->perms = pace_other->perms;
    1433                                 else
    1434                                         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                        }
    14381458                } else {
    14391459                        pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR);
     
    14611481                        else
    14621482                                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                        }
    14641486                } else {
    14651487                        pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRGRP, S_IWGRP, S_IXGRP);
     
    14831505                if (setting_acl) {
    14841506                        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                        }
    14861510                } else
    14871511                        pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IROTH, S_IWOTH, S_IXOTH);
     
    14971521 If it does not have them, check if there are any entries where the trustee is the
    14981522 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.
    14991524****************************************************************************/
    15001525
     
    15361561        if (!got_group_obj)
    15371562                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_GROUP
    1543 ****************************************************************************/
    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::perm
    1549            SMB_ACL_USER     : not trustee    -> Posix ACL u:user:perm
    1550            SMB_ACL_USER_OBJ : trustee -> convert to SMB_ACL_USER : trustee
    1551            Posix ACL u:trustee:perm
    1552 
    1553            SMB_ACL_GROUP_OBJ: trustee(CREATOR_GROUP) -> Posix ACL d:g::perm
    1554            SMB_ACL_GROUP    : not trustee   -> Posix ACL g:group:perm
    1555            SMB_ACL_GROUP_OBJ: trustee -> convert to SMB_ACL_GROUP : trustee
    1556            Posix ACL g:trustee:perm
    1557         */
    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;
    15821563}
    15831564
     
    18051786                                (SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT)) {
    18061787
     1788                                canon_ace *current_dir_ace = current_ace;
    18071789                                DLIST_ADD_END(dir_ace, current_ace, canon_ace *);
    18081790
     
    18301812                                        dbgtext("create_canon_ace_lists: adding dir ACL:\n");
    18311813                                        print_canon_ace( current_ace, 0);
    1832                                 }
    1833 
    1834                                 /*
    1835                                  * We have a lossy mapping: directory ACE entries
    1836                                  * CREATOR_OWNER ------\
    1837                                  *     (map to)         +---> SMB_ACL_USER_OBJ
    1838                                  * owning sid    ------/
    1839                                  *
    1840                                  * CREATOR_GROUP ------\
    1841                                  *     (map to)         +---> SMB_ACL_GROUP_OBJ
    1842                                  * primary group sid --/
    1843                                  *
    1844                                  * on set. And on read of a directory ACL
    1845                                  *
    1846                                  * SMB_ACL_USER_OBJ ----> CREATOR_OWNER
    1847                                  * SMB_ACL_GROUP_OBJ ---> CREATOR_GROUP.
    1848                                  *
    1849                                  * Deal with this on set by duplicating
    1850                                  * owning sid and primary group sid ACE
    1851                                  * 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;
    18601814                                }
    18611815
     
    18941848                                        current_ace = NULL;
    18951849                                }
     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(&current_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(&current_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                                }
    18961887                        }
    18971888                }
     
    19551946        } else {
    19561947                /*
    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().
    19611953                 */
    19621954                if (file_ace) {
    19631955                        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);
    19671956                }
    19681957        }
     
    22872276
    22882277/****************************************************************************
    2289  Create a default mode that will be used if a security descriptor entry has
    2290  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 the
    2312          * 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 /****************************************************************************
    23272278 Unpack a struct security_descriptor into two canonical ace lists. We don't depend on this
    23282279 succeeding.
     
    23382289                                const struct security_descriptor *psd)
    23392290{
    2340         SMB_STRUCT_STAT st;
    23412291        canon_ace *file_ace = NULL;
    23422292        canon_ace *dir_ace = NULL;
     
    24022352        print_canon_ace_list( "file ace - before valid", file_ace);
    24032353
    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)) {
    24152356                free_canon_ace_list(file_ace);
    24162357                free_canon_ace_list(dir_ace);
     
    24202361        print_canon_ace_list( "dir ace - before valid", dir_ace);
    24212362
    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)) {
    24322365                free_canon_ace_list(file_ace);
    24332366                free_canon_ace_list(dir_ace);
     
    25172450        canon_ace *next_ace = NULL;
    25182451        int entry_id = SMB_ACL_FIRST_ENTRY;
     2452        bool is_default_acl = (the_acl_type == SMB_ACL_TYPE_DEFAULT);
    25192453        SMB_ACL_ENTRY_T entry;
    25202454        size_t ace_count;
     
    26042538                ace->unix_ug = unix_ug;
    26052539                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);
    26072541
    26082542                DLIST_ADD(l_head, ace);
     
    26132547         */
    26142548
    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,
    26162550                                      S_ISDIR(psbuf->st_ex_mode), powner, pgroup,
    26172551                                      psbuf, False))
     
    26232557         */
    26242558
    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"));
    26262560
    26272561        for ( ace_count = 0, ace = l_head; ace; ace = next_ace, ace_count++) {
Note: See TracChangeset for help on using the changeset viewer.