r21063: All case statements are now NTSTATUS returning
authorJeremy Allison <jra@samba.org>
Tue, 30 Jan 2007 22:20:55 +0000 (22:20 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:17:32 +0000 (12:17 -0500)
functions. Now to factor out the post processing
and make all cases behave the same (no mixture
of "early returns" and "break"s.
Jeremy
(This used to be commit 7e17e54cb729e34c935927fe69a43690c7f446ae)

source3/smbd/trans2.c
source3/smbd/vfs.c

index 98ea6c111a4fda3be9e25e2c84af21bade666ffd..826ccd3f927c2fedc19062fa7be5a4e0aa8ca8e7 100644 (file)
@@ -4211,7 +4211,9 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
  Deal with SMB_INFO_STANDARD.
 ****************************************************************************/
 
-static NTSTATUS smb_set_info_standard(const char *pdata, int total_data, struct utimbuf *p_tvs)
+static NTSTATUS smb_set_info_standard(const char *pdata,
+                                       int total_data,
+                                       struct utimbuf *p_tvs)
 {
        if (total_data < 12) {
                return NT_STATUS_INVALID_PARAMETER;
@@ -4228,7 +4230,10 @@ static NTSTATUS smb_set_info_standard(const char *pdata, int total_data, struct
  Deal with SMB_SET_FILE_BASIC_INFO.
 ****************************************************************************/
 
-static NTSTATUS smb_set_file_basic_info(const char *pdata, int total_data, struct utimbuf *p_tvs, int *p_dosmode)
+static NTSTATUS smb_set_file_basic_info(const char *pdata,
+                                       int total_data,
+                                       struct utimbuf *p_tvs,
+                                       int *p_dosmode)
 {
        /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
        time_t write_time;
@@ -4273,7 +4278,6 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
                                        SMB_STRUCT_STAT *psbuf,
                                        SMB_OFF_T *p_size)
 {
-       int ret = -1;
        SMB_BIG_UINT allocation_size;
 
        if (total_data < 8) {
@@ -4298,6 +4302,7 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
        }
 
        if(allocation_size != get_file_size(*psbuf)) {
+               int ret = -1;
                SMB_STRUCT_STAT new_sbuf;
  
                DEBUG(10,("smb_set_file_allocation_info: file %s : setting new allocation size to %.0f\n",
@@ -4306,10 +4311,13 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
                if (fsp && fsp->fh->fd != -1) {
                        /* Open file. */
                        ret = vfs_allocate_file_space(fsp, allocation_size);
+                       if (ret == -1) {
+                               return map_nt_error_from_unix(errno);
+                       }
                        if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&new_sbuf) != 0) {
                                DEBUG(3,("smb_set_file_allocation_info: fstat of fnum %d failed (%s)\n",
                                                        fsp->fnum, strerror(errno)));
-                               ret = -1;
+                               return map_nt_error_from_unix(errno);
                        }
                } else {
                        /* Pathname or stat or directory file. */
@@ -4330,16 +4338,20 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
                                return status;
                        }
                        ret = vfs_allocate_file_space(new_fsp, allocation_size);
+                       if (ret == -1) {
+                               status = map_nt_error_from_unix(errno);
+                               close_file(new_fsp,NORMAL_CLOSE);
+                               return status;
+                       }
                        if (SMB_VFS_FSTAT(new_fsp,new_fsp->fh->fd,&new_sbuf) != 0) {
                                DEBUG(3,("smb_set_file_allocation_info: fstat of fnum %d failed (%s)\n",
                                                new_fsp->fnum, strerror(errno)));
-                               ret = -1;
+                               status = map_nt_error_from_unix(errno);
+                               close_file(new_fsp,NORMAL_CLOSE);
+                               return status;
                        }
                        close_file(new_fsp,NORMAL_CLOSE);
                }
-               if (ret == -1) {
-                       return NT_STATUS_DISK_FULL;
-               }
 
                /* Allocate can truncate size... */
                *p_size = get_file_size(new_sbuf);
@@ -4375,6 +4387,190 @@ static NTSTATUS smb_set_file_end_of_file_info(connection_struct *conn,
        return NT_STATUS_OK;
 }
 
+/****************************************************************************
+ Deal with SMB_SET_FILE_UNIX_BASIC.
+****************************************************************************/
+
+static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
+                                       const char *pdata,
+                                       int total_data,
+                                       files_struct *fsp,
+                                       const char *fname,
+                                       SMB_STRUCT_STAT *psbuf,
+                                       SMB_OFF_T *p_size,
+                                       struct utimbuf *p_tvs,
+                                       mode_t *p_unixmode,
+                                       int *p_dosmode)
+{
+       uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
+       gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
+       uint32 raw_unixmode;
+       BOOL delete_on_fail = False;
+       NTSTATUS status = NT_STATUS_OK;
+
+       if (total_data < 100) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       set_owner = VALID_STAT(*psbuf) ? psbuf->st_uid : (uid_t)SMB_UID_NO_CHANGE;
+       set_grp = VALID_STAT(*psbuf) ? psbuf->st_gid : (gid_t)SMB_GID_NO_CHANGE;
+
+       if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
+          IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
+               *p_size=IVAL(pdata,0); /* first 8 Bytes are size */
+#ifdef LARGE_SMB_OFF_T
+               *p_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
+#else /* LARGE_SMB_OFF_T */
+               if (IVAL(pdata,4) != 0) {
+                       /* more than 32 bits? */
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+#endif /* LARGE_SMB_OFF_T */
+       }
+
+       pdata+=24;          /* ctime & st_blocks are not changed */
+       p_tvs->actime = convert_timespec_to_time_t(interpret_long_date(pdata)); /* access_time */
+       p_tvs->modtime = convert_timespec_to_time_t(interpret_long_date(pdata+8)); /* modification_time */
+       pdata+=16;
+       set_owner = (uid_t)IVAL(pdata,0);
+       pdata += 8;
+       set_grp = (gid_t)IVAL(pdata,0);
+       pdata += 8;
+       raw_unixmode = IVAL(pdata,28);
+       *p_unixmode = unix_perms_from_wire(conn, psbuf, raw_unixmode);
+       *p_dosmode = 0; /* Ensure dos mode change doesn't override this. */
+
+       DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC: name = %s \
+size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
+               fname, (double)*p_size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
+
+       if (!VALID_STAT(*psbuf)) {
+
+               /*
+                * The only valid use of this is to create character and block
+                * devices, and named pipes. This is deprecated (IMHO) and 
+                * a new info level should be used for mknod. JRA.
+                */
+
+               uint32 file_type = IVAL(pdata,0);
+#if defined(HAVE_MAKEDEV)
+               uint32 dev_major = IVAL(pdata,4);
+               uint32 dev_minor = IVAL(pdata,12);
+#endif
+
+               SMB_DEV_T dev = (SMB_DEV_T)0;
+
+               if (raw_unixmode == SMB_MODE_NO_CHANGE) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+
+#if defined(HAVE_MAKEDEV)
+               dev = makedev(dev_major, dev_minor);
+#endif
+
+               switch (file_type) {
+#if defined(S_IFIFO)
+                       case UNIX_TYPE_FIFO:
+                               *p_unixmode |= S_IFIFO;
+                               break;
+#endif
+#if defined(S_IFSOCK)
+                       case UNIX_TYPE_SOCKET:
+                               *p_unixmode |= S_IFSOCK;
+                               break;
+#endif
+#if defined(S_IFCHR)
+                       case UNIX_TYPE_CHARDEV:
+                               *p_unixmode |= S_IFCHR;
+                               break;
+#endif
+#if defined(S_IFBLK)
+                       case UNIX_TYPE_BLKDEV:
+                               *p_unixmode |= S_IFBLK;
+                               break;
+#endif
+                       default:
+                               return NT_STATUS_INVALID_PARAMETER;
+               }
+
+               DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
+0%o for file %s\n", (double)dev, *p_unixmode, fname ));
+
+               /* Ok - do the mknod. */
+               if (SMB_VFS_MKNOD(conn, fname, *p_unixmode, dev) != 0) {
+                       return map_nt_error_from_unix(errno);
+               }
+
+               /* 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, *p_unixmode);
+               }
+
+               if (SMB_VFS_STAT(conn, fname, psbuf) != 0) {
+                       status = map_nt_error_from_unix(errno);
+                       SMB_VFS_UNLINK(conn,fname);
+                       return status;
+               }
+
+               /* Ensure we don't try and change anything else. */
+               raw_unixmode = SMB_MODE_NO_CHANGE;
+               *p_size = get_file_size(*psbuf);
+               p_tvs->modtime = psbuf->st_mtime;
+               p_tvs->actime = psbuf->st_atime;
+       }
+
+       /*
+        * Deal with the UNIX specific mode set.
+        */
+
+       if (raw_unixmode != SMB_MODE_NO_CHANGE) {
+               DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
+                       (unsigned int)*p_unixmode, fname ));
+               if (SMB_VFS_CHMOD(conn,fname,*p_unixmode) != 0) {
+                       return map_nt_error_from_unix(errno);
+               }
+       }
+
+       /*
+        * Deal with the UNIX specific uid set.
+        */
+
+       if ((set_owner != (uid_t)SMB_UID_NO_CHANGE) && (psbuf->st_uid != set_owner)) {
+               DEBUG(10,("smb_set_file_unix_basic: 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) {
+                       status = map_nt_error_from_unix(errno);
+                       if (delete_on_fail) {
+                               SMB_VFS_UNLINK(conn,fname);
+                       }
+                       return status;
+               }
+       }
+
+       /*
+        * Deal with the UNIX specific gid set.
+        */
+
+       if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) && (psbuf->st_gid != set_grp)) {
+               DEBUG(10,("smb_set_file_unix_basic: 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) {
+                       status = map_nt_error_from_unix(errno);
+                       if (delete_on_fail) {
+                               SMB_VFS_UNLINK(conn,fname);
+                       }
+                       return status;
+               }
+       }
+       return NT_STATUS_OK;
+}
 
 /****************************************************************************
  Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
@@ -4395,8 +4591,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
        pstring fname;
        int fd = -1;
        files_struct *fsp = NULL;
-       uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE;
-       gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE;
        mode_t unixmode = 0;
        NTSTATUS status = NT_STATUS_OK;
 
@@ -4520,9 +4714,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
        dosmode = dos_mode(conn,fname,&sbuf);
        unixmode = sbuf.st_mode;
 
-       set_owner = VALID_STAT(sbuf) ? sbuf.st_uid : (uid_t)SMB_UID_NO_CHANGE;
-       set_grp = VALID_STAT(sbuf) ? sbuf.st_gid : (gid_t)SMB_GID_NO_CHANGE;
-
        switch (info_level) {
 
                case SMB_INFO_STANDARD:
@@ -4654,170 +4845,22 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
 
                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);
-                       }
-
-                       if(IVAL(pdata, 0) != SMB_SIZE_NO_CHANGE_LO &&
-                          IVAL(pdata, 4) != SMB_SIZE_NO_CHANGE_HI) {
-                               size=IVAL(pdata,0); /* first 8 Bytes are size */
-#ifdef LARGE_SMB_OFF_T
-                               size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
-#else /* LARGE_SMB_OFF_T */
-                               if (IVAL(pdata,4) != 0) {
-                                       /* more than 32 bits? */
-                                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
-                               }
-#endif /* LARGE_SMB_OFF_T */
-                       }
-                       pdata+=24;          /* ctime & st_blocks are not changed */
-                       tvs.actime = convert_timespec_to_time_t(interpret_long_date(pdata)); /* access_time */
-                       tvs.modtime = convert_timespec_to_time_t(interpret_long_date(pdata+8)); /* modification_time */
-                       pdata+=16;
-                       set_owner = (uid_t)IVAL(pdata,0);
-                       pdata += 8;
-                       set_grp = (gid_t)IVAL(pdata,0);
-                       pdata += 8;
-                       raw_unixmode = IVAL(pdata,28);
-                       unixmode = unix_perms_from_wire(conn, &sbuf, raw_unixmode);
-                       dosmode = 0; /* Ensure dos mode change doesn't override this. */
-
-                       DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC: name = %s \
-size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
-                               fname, (double)size, (unsigned int)set_owner, (unsigned int)set_grp, (int)raw_unixmode));
-
-                       if (!VALID_STAT(sbuf)) {
-
-                               /*
-                                * The only valid use of this is to create character and block
-                                * devices, and named pipes. This is deprecated (IMHO) and 
-                                * a new info level should be used for mknod. JRA.
-                                */
-
-                               uint32 file_type = IVAL(pdata,0);
-#if defined(HAVE_MAKEDEV)
-                               uint32 dev_major = IVAL(pdata,4);
-                               uint32 dev_minor = IVAL(pdata,12);
-#endif
-
-                               SMB_DEV_T dev = (SMB_DEV_T)0;
-
-                               if (tran_call == TRANSACT2_SETFILEINFO)
-                                       return(ERROR_DOS(ERRDOS,ERRnoaccess));
-
-                               if (raw_unixmode == SMB_MODE_NO_CHANGE) {
-                                       return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
-                               }
-
-#if defined(HAVE_MAKEDEV)
-                               dev = makedev(dev_major, dev_minor);
-#endif
-
-                               switch (file_type) {
-#if defined(S_IFIFO)
-                                       case UNIX_TYPE_FIFO:
-                                               unixmode |= S_IFIFO;
-                                               break;
-#endif
-#if defined(S_IFSOCK)
-                                       case UNIX_TYPE_SOCKET:
-                                               unixmode |= S_IFSOCK;
-                                               break;
-#endif
-#if defined(S_IFCHR)
-                                       case UNIX_TYPE_CHARDEV:
-                                               unixmode |= S_IFCHR;
-                                               break;
-#endif
-#if defined(S_IFBLK)
-                                       case UNIX_TYPE_BLKDEV:
-                                               unixmode |= S_IFBLK;
-                                               break;
-#endif
-                                       default:
-                                               return(ERROR_DOS(ERRDOS,ERRnoaccess));
-                               }
-
-                               DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
-0%o for file %s\n", (double)dev, unixmode, fname ));
-
-                               /* Ok - do the mknod. */
-                               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);
-                               }
-
-                               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;
-                       }
-
-                       /*
-                        * Deal with the UNIX specific mode set.
-                        */
-
-                       if (raw_unixmode != SMB_MODE_NO_CHANGE) {
-                               DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC setting mode 0%o for file %s\n",
-                                       (unsigned int)unixmode, fname ));
-                               if (SMB_VFS_CHMOD(conn,fname,unixmode) != 0)
-                                       return(UNIXERROR(ERRDOS,ERRnoaccess));
-                       }
-
-                       /*
-                        * Deal with the UNIX specific uid set.
-                        */
-
-                       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 (delete_on_fail) {
-                                               int saved_errno = errno;
-                                               SMB_VFS_UNLINK(conn,fname);
-                                               errno = saved_errno;
-                                       }
-                                       return(UNIXERROR(ERRDOS,ERRnoaccess));
-                               }
+                       if (tran_call == TRANSACT2_SETFILEINFO) {
+                               return ERROR_NT(NT_STATUS_INVALID_LEVEL);
                        }
 
-                       /*
-                        * Deal with the UNIX specific gid set.
-                        */
-
-                       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 (delete_on_fail) {
-                                               int saved_errno = errno;
-                                               SMB_VFS_UNLINK(conn,fname);
-                                               errno = saved_errno;
-                                       }
-                                       return(UNIXERROR(ERRDOS,ERRnoaccess));
-                               }
+                       status = smb_set_file_unix_basic(conn,
+                                                       pdata,
+                                                       total_data,
+                                                       fsp,
+                                                       fname,
+                                                       &sbuf,
+                                                       &size,
+                                                       &tvs,
+                                                       &unixmode,
+                                                       &dosmode);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               return ERROR_NT(status);
                        }
                        break;
                }
index 47ac9ef4619f00508ee4889714d31abda92fad16..643c48cd27c1f963d7e2e2675e9ebe8f1a326e51 100644 (file)
@@ -454,6 +454,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_BIG_UINT len)
 
        if (((SMB_OFF_T)len) < 0) {
                DEBUG(0,("vfs_allocate_file_space: %s negative len requested.\n", fsp->fsp_name ));
+               errno = EINVAL;
                return -1;
        }