Author: jra Date: 2007-01-27 02:33:21 +0000 (Sat, 27 Jan 2007) New Revision: 21035
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=21035 Log: Remove unneeded checks on incoming uid/gid for mknod (fifo) unix extensions code. Problem discovered by Anders Karlsson <[EMAIL PROTECTED]>. Jeremy. Modified: branches/SAMBA_3_0/source/smbd/trans2.c branches/SAMBA_3_0_24/source/smbd/trans2.c Changeset: Modified: branches/SAMBA_3_0/source/smbd/trans2.c =================================================================== --- branches/SAMBA_3_0/source/smbd/trans2.c 2007-01-26 22:52:55 UTC (rev 21034) +++ branches/SAMBA_3_0/source/smbd/trans2.c 2007-01-27 02:33:21 UTC (rev 21035) @@ -4200,6 +4200,7 @@ case SMB_SET_FILE_UNIX_BASIC: { uint32 raw_unixmode; + BOOL delete_on_fail = False; if (total_data < 100) { return ERROR_NT(NT_STATUS_INVALID_PARAMETER); @@ -4247,8 +4248,6 @@ uint32 dev_minor = IVAL(pdata,12); #endif - uid_t myuid = geteuid(); - gid_t mygid = getegid(); SMB_DEV_T dev = (SMB_DEV_T)0; if (tran_call == TRANSACT2_SETFILEINFO) @@ -4262,13 +4261,6 @@ dev = makedev(dev_major, dev_minor); #endif - /* We can only create as the owner/group we are. */ - - if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE)) - return(ERROR_DOS(ERRDOS,ERRnoaccess)); - if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE)) - return(ERROR_DOS(ERRDOS,ERRnoaccess)); - switch (file_type) { #if defined(S_IFIFO) case UNIX_TYPE_FIFO: @@ -4298,18 +4290,34 @@ 0%o for file %s\n", (double)dev, unixmode, fname )); /* Ok - do the mknod. */ - if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0) + if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0) { return(UNIXERROR(ERRDOS,ERRnoaccess)); + } + /* If any of the other "set" calls fail we + * don't want to end up with a half-constructed mknod. + */ + + delete_on_fail = True; + if (lp_inherit_perms(SNUM(conn))) { inherit_access_acl( conn, parent_dirname(fname), fname, unixmode); } - SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); - return(-1); + if (SMB_VFS_STAT(conn, fname, &sbuf) != 0) { + int saved_errno = errno; + SMB_VFS_UNLINK(conn,fname); + errno = saved_errno; + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } + + /* Ensure we don't try and change anything else. */ + raw_unixmode = SMB_MODE_NO_CHANGE; + size = get_file_size(sbuf); + tvs.modtime = sbuf.st_mtime; + tvs.actime = sbuf.st_atime; } /* @@ -4330,8 +4338,14 @@ if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) { DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n", (unsigned int)set_owner, fname )); - if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0) + if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0) { + if (delete_on_fail) { + int saved_errno = errno; + SMB_VFS_UNLINK(conn,fname); + errno = saved_errno; + } return(UNIXERROR(ERRDOS,ERRnoaccess)); + } } /* @@ -4341,8 +4355,14 @@ if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) { DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n", (unsigned int)set_owner, fname )); - if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0) + if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0) { + if (delete_on_fail) { + int saved_errno = errno; + SMB_VFS_UNLINK(conn,fname); + errno = saved_errno; + } return(UNIXERROR(ERRDOS,ERRnoaccess)); + } } break; } Modified: branches/SAMBA_3_0_24/source/smbd/trans2.c =================================================================== --- branches/SAMBA_3_0_24/source/smbd/trans2.c 2007-01-26 22:52:55 UTC (rev 21034) +++ branches/SAMBA_3_0_24/source/smbd/trans2.c 2007-01-27 02:33:21 UTC (rev 21035) @@ -4200,6 +4200,7 @@ case SMB_SET_FILE_UNIX_BASIC: { uint32 raw_unixmode; + BOOL delete_on_fail = False; if (total_data < 100) { return ERROR_NT(NT_STATUS_INVALID_PARAMETER); @@ -4247,8 +4248,6 @@ uint32 dev_minor = IVAL(pdata,12); #endif - uid_t myuid = geteuid(); - gid_t mygid = getegid(); SMB_DEV_T dev = (SMB_DEV_T)0; if (tran_call == TRANSACT2_SETFILEINFO) @@ -4262,13 +4261,6 @@ dev = makedev(dev_major, dev_minor); #endif - /* We can only create as the owner/group we are. */ - - if ((set_owner != myuid) && (set_owner != (uid_t)SMB_UID_NO_CHANGE)) - return(ERROR_DOS(ERRDOS,ERRnoaccess)); - if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE)) - return(ERROR_DOS(ERRDOS,ERRnoaccess)); - switch (file_type) { #if defined(S_IFIFO) case UNIX_TYPE_FIFO: @@ -4298,18 +4290,34 @@ 0%o for file %s\n", (double)dev, unixmode, fname )); /* Ok - do the mknod. */ - if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0) + if (SMB_VFS_MKNOD(conn,fname, unixmode, dev) != 0) { return(UNIXERROR(ERRDOS,ERRnoaccess)); + } + /* If any of the other "set" calls fail we + * don't want to end up with a half-constructed mknod. + */ + + delete_on_fail = True; + if (lp_inherit_perms(SNUM(conn))) { inherit_access_acl( conn, parent_dirname(fname), fname, unixmode); } - SSVAL(params,0,0); - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes); - return(-1); + if (SMB_VFS_STAT(conn, fname, &sbuf) != 0) { + int saved_errno = errno; + SMB_VFS_UNLINK(conn,fname); + errno = saved_errno; + return(UNIXERROR(ERRDOS,ERRnoaccess)); + } + + /* Ensure we don't try and change anything else. */ + raw_unixmode = SMB_MODE_NO_CHANGE; + size = get_file_size(sbuf); + tvs.modtime = sbuf.st_mtime; + tvs.actime = sbuf.st_atime; } /* @@ -4330,8 +4338,14 @@ if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (sbuf.st_uid != set_owner)) { DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing owner %u for file %s\n", (unsigned int)set_owner, fname )); - if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0) + if (SMB_VFS_CHOWN(conn,fname,set_owner, (gid_t)-1) != 0) { + if (delete_on_fail) { + int saved_errno = errno; + SMB_VFS_UNLINK(conn,fname); + errno = saved_errno; + } return(UNIXERROR(ERRDOS,ERRnoaccess)); + } } /* @@ -4341,8 +4355,14 @@ if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (sbuf.st_gid != set_grp)) { DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC changing group %u for file %s\n", (unsigned int)set_owner, fname )); - if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0) + if (SMB_VFS_CHOWN(conn,fname,(uid_t)-1, set_grp) != 0) { + if (delete_on_fail) { + int saved_errno = errno; + SMB_VFS_UNLINK(conn,fname); + errno = saved_errno; + } return(UNIXERROR(ERRDOS,ERRnoaccess)); + } } break; }