diff options
author | Gerald Carter <jerry@samba.org> | 2002-06-17 18:36:36 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2002-06-17 18:36:36 +0000 |
commit | 1e6e5b299c235b513095a76a4cd9fffc41e8fc9c (patch) | |
tree | 9f741529073ad411cc7328334e26d3e35b1d33f1 /source/smbd/posix_acls.c | |
parent | a11c5d7ad07d259d764aede4745d13f8163a8212 (diff) | |
download | samba-1e6e5b299c235b513095a76a4cd9fffc41e8fc9c.tar.gz samba-1e6e5b299c235b513095a76a4cd9fffc41e8fc9c.tar.xz samba-1e6e5b299c235b513095a76a4cd9fffc41e8fc9c.zip |
beginning to sync up for 2.2.5 release....
Diffstat (limited to 'source/smbd/posix_acls.c')
-rw-r--r-- | source/smbd/posix_acls.c | 170 |
1 files changed, 96 insertions, 74 deletions
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c index 6a0aa982b42..cbb28359f94 100644 --- a/source/smbd/posix_acls.c +++ b/source/smbd/posix_acls.c @@ -409,7 +409,7 @@ static mode_t map_nt_perms( SEC_ACCESS sec_access, int type) Unpack a SEC_DESC into a UNIX owner and group. ****************************************************************************/ -static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, SEC_DESC *psd) +static BOOL unpack_nt_owners( int snum, SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, SEC_DESC *psd) { DOM_SID owner_sid; DOM_SID grp_sid; @@ -440,15 +440,15 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp, if (security_info_sent & OWNER_SECURITY_INFORMATION) { sid_copy(&owner_sid, psd->owner_sid); if (!sid_to_uid( &owner_sid, puser, &sid_type)) { -#if ACL_FORCE_UNMAPPABLE - /* this allows take ownership to work reasonably */ - extern struct current_user current_user; - *puser = current_user.uid; -#else - DEBUG(3,("unpack_nt_owners: unable to validate owner sid for %s.\n", - sid_string_static(&owner_sid))); - return False; -#endif + if (lp_force_unknown_acl_user(snum)) { + /* this allows take ownership to work reasonably */ + extern struct current_user current_user; + *puser = current_user.uid; + } else { + DEBUG(3,("unpack_nt_owners: unable to validate owner sid for %s.\n", + sid_string_static(&owner_sid))); + return False; + } } } @@ -460,14 +460,14 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp, if (security_info_sent & GROUP_SECURITY_INFORMATION) { sid_copy(&grp_sid, psd->grp_sid); if (!sid_to_gid( &grp_sid, pgrp, &sid_type)) { -#if ACL_FORCE_UNMAPPABLE - /* this allows take group ownership to work reasonably */ - extern struct current_user current_user; - *pgrp = current_user.gid; -#else - DEBUG(3,("unpack_nt_owners: unable to validate group sid.\n")); - return False; -#endif + if (lp_force_unknown_acl_user(snum)) { + /* this allows take group ownership to work reasonably */ + extern struct current_user current_user; + *pgrp = current_user.gid; + } else { + DEBUG(3,("unpack_nt_owners: unable to validate group sid.\n")); + return False; + } } } @@ -480,7 +480,7 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp, Ensure the enforced permissions for this share apply. ****************************************************************************/ -static mode_t apply_default_perms(files_struct *fsp, mode_t perms, mode_t type) +static void apply_default_perms(files_struct *fsp, canon_ace *pace, mode_t type) { int snum = SNUM(fsp->conn); mode_t and_bits = (mode_t)0; @@ -499,6 +499,10 @@ static mode_t apply_default_perms(files_struct *fsp, mode_t perms, mode_t type) /* Now bounce them into the S_USR space. */ switch(type) { case S_IRUSR: + /* Ensure owner has read access. */ + pace->perms |= S_IRUSR; + if (fsp->is_directory) + pace->perms |= (S_IWUSR|S_IXUSR); and_bits = unix_perms_to_acl_perms(and_bits, S_IRUSR, S_IWUSR, S_IXUSR); or_bits = unix_perms_to_acl_perms(or_bits, S_IRUSR, S_IWUSR, S_IXUSR); break; @@ -512,7 +516,34 @@ static mode_t apply_default_perms(files_struct *fsp, mode_t perms, mode_t type) break; } - return ((perms & and_bits)|or_bits); + pace->perms = ((pace->perms & and_bits)|or_bits); +} + +/**************************************************************************** + Check if a given uid/SID is in a group gid/SID. This is probably very + expensive and will need optimisation. A *lot* of optimisation :-). JRA. +****************************************************************************/ + +static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace ) +{ + extern DOM_SID global_sid_World; + fstring u_name; + fstring g_name; + + /* "Everyone" always matches every uid. */ + + if (sid_equal(&group_ace->trustee, &global_sid_World)) + return True; + + fstrcpy(u_name, uidtoname(uid_ace->unix_ug.uid)); + fstrcpy(g_name, gidtoname(group_ace->unix_ug.gid)); + + /* + * Due to the winbind interfaces we need to do this via names, + * not uids/gids. + */ + + return user_in_group_list(u_name, g_name ); } /**************************************************************************** @@ -537,24 +568,16 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace, BOOL got_user = False; BOOL got_grp = False; BOOL got_other = False; + canon_ace *pace_other = NULL; + canon_ace *pace_group = NULL; for (pace = *pp_ace; pace; pace = pace->next) { if (pace->type == SMB_ACL_USER_OBJ) { - if (setting_acl) { - /* Ensure owner has read access. */ - pace->perms |= S_IRUSR; - if (fsp->is_directory) - pace->perms |= (S_IWUSR|S_IXUSR); - - /* - * Ensure create mask/force create mode is respected on set. - */ - - pace->perms = apply_default_perms(fsp, pace->perms, S_IRUSR); - } - + if (setting_acl) + apply_default_perms(fsp, pace, S_IRUSR); got_user = True; + } else if (pace->type == SMB_ACL_GROUP_OBJ) { /* @@ -562,8 +585,10 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace, */ if (setting_acl) - pace->perms = apply_default_perms(fsp, pace->perms, S_IRGRP); + apply_default_perms(fsp, pace, S_IRGRP); got_grp = True; + pace_group = pace; + } else if (pace->type == SMB_ACL_OTHER) { /* @@ -571,8 +596,9 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace, */ if (setting_acl) - pace->perms = apply_default_perms(fsp, pace->perms, S_IROTH); + apply_default_perms(fsp, pace, S_IROTH); got_other = True; + pace_other = pace; } } @@ -587,9 +613,21 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace, pace->owner_type = UID_ACE; pace->unix_ug.uid = pst->st_uid; pace->trustee = *pfile_owner_sid; - pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRUSR, S_IWUSR, S_IXUSR); pace->attr = ALLOW_ACE; + if (setting_acl) { + /* If we only got an "everyone" perm, just use that. */ + if (!got_grp && got_other) + pace->perms = pace_other->perms; + else if (got_grp && uid_entry_in_group(pace, pace_group)) + pace->perms = pace_group->perms; + else + pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRUSR, S_IWUSR, S_IXUSR); + apply_default_perms(fsp, pace, S_IRUSR); + } else { + pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRUSR, S_IWUSR, S_IXUSR); + } + DLIST_ADD(*pp_ace, pace); } @@ -604,8 +642,17 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace, pace->owner_type = GID_ACE; pace->unix_ug.uid = pst->st_gid; pace->trustee = *pfile_grp_sid; - pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRGRP, S_IWGRP, S_IXGRP); pace->attr = ALLOW_ACE; + if (setting_acl) { + /* If we only got an "everyone" perm, just use that. */ + if (got_other) + pace->perms = pace_other->perms; + else + pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRGRP, S_IWGRP, S_IXGRP); + apply_default_perms(fsp, pace, S_IRGRP); + } else { + pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRGRP, S_IWGRP, S_IXGRP); + } DLIST_ADD(*pp_ace, pace); } @@ -621,8 +668,9 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace, pace->owner_type = WORLD_ACE; pace->unix_ug.world = -1; pace->trustee = global_sid_World; - pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IROTH, S_IWOTH, S_IXOTH); pace->attr = ALLOW_ACE; + pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IROTH, S_IWOTH, S_IXOTH); + apply_default_perms(fsp, pace, S_IROTH); DLIST_ADD(*pp_ace, pace); } @@ -932,33 +980,6 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name )); } /**************************************************************************** - Check if a given uid/SID is in a group gid/SID. This is probably very - expensive and will need optimisation. A *lot* of optimisation :-). JRA. -****************************************************************************/ - -static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace ) -{ - extern DOM_SID global_sid_World; - fstring u_name; - fstring g_name; - - /* "Everyone" always matches every uid. */ - - if (sid_equal(&group_ace->trustee, &global_sid_World)) - return True; - - fstrcpy(u_name, uidtoname(uid_ace->unix_ug.uid)); - fstrcpy(g_name, gidtoname(group_ace->unix_ug.gid)); - - /* - * Due to the winbind interfaces we need to do this via names, - * not uids/gids. - */ - - return user_in_group_list(u_name, g_name ); -} - -/**************************************************************************** ASCII art time again... JRA :-). We have 3 cases to process when moving from an NT ACL to a POSIX ACL. Firstly, @@ -2026,28 +2047,28 @@ static int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_ /* try the direct way first */ ret = vfs_chown(conn, fname, uid, gid); - if (ret == 0) return 0; + if (ret == 0) + return 0; if(!CAN_WRITE(conn) || !lp_dos_filemode(SNUM(conn))) return -1; - if (vfs_stat(conn,fname,&st)) { + if (vfs_stat(conn,fname,&st)) return -1; - } fsp = open_file_fchmod(conn,fname,&st); - if (!fsp) { + if (!fsp) return -1; - } /* only allow chown to the current user. This is more secure, and also copes with the case where the SID in a take ownership ACL is a local SID on the users workstation */ uid = current_user.uid; - + become_root(); - ret = vfswrap_fchown(fsp, fsp->fd, uid, gid); + /* Keep the current file gid the same. */ + ret = vfswrap_fchown(fsp, fsp->fd, uid, (gid_t)-1); unbecome_root(); close_file_fchmod(fsp); @@ -2099,7 +2120,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) * Unpack the user/group/world id's. */ - if (!unpack_nt_owners( &sbuf, &user, &grp, security_info_sent, psd)) + if (!unpack_nt_owners( SNUM(conn), &sbuf, &user, &grp, security_info_sent, psd)) return False; /* @@ -2367,6 +2388,7 @@ BOOL directory_has_default_acl(connection_struct *conn, const char *fname) if (dir_acl != NULL && (conn->vfs_ops.sys_acl_get_entry(conn, dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1)) has_acl = True; - conn->vfs_ops.sys_acl_free_acl(conn, dir_acl); + if (dir_acl) + conn->vfs_ops.sys_acl_free_acl(conn, dir_acl); return has_acl; } |