Prefix VFS API macros with SMB_ for consistency and to avoid problems with VFS_ macro...
[tprouty/samba.git] / source / smbd / reply.c
index 71e880476cf69583ad7a37c1cffade7a2dfd46d2..7a0cc0287a1a2ceb44c3bd3d48a00eb8c9d80000 100644 (file)
@@ -87,8 +87,8 @@ int reply_special(char *inbuf,char *outbuf)
                        name2[15] = 0;
                }
 
-               set_local_machine_name(name1);
-               set_remote_machine_name(name2);
+               set_local_machine_name(name1, True);
+               set_remote_machine_name(name2, True);
 
                DEBUG(2,("netbios connect: local=%s remote=%s\n",
                        get_local_machine_name(), get_remote_machine_name() ));
@@ -161,7 +161,7 @@ int reply_tcon(connection_struct *conn,
        *service_buf = *password = *dev = 0;
 
        p = smb_buf(inbuf)+1;
-       p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service), STR_TERMINATE) + 1;
+       p += srvstr_pull_buf(inbuf, service_buf, p, sizeof(service_buf), STR_TERMINATE) + 1;
        pwlen = srvstr_pull_buf(inbuf, password, p, sizeof(password), STR_TERMINATE) + 1;
        p += pwlen;
        p += srvstr_pull_buf(inbuf, dev, p, sizeof(dev), STR_TERMINATE) + 1;
@@ -204,16 +204,21 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
 {
        fstring service;
        DATA_BLOB password;
-       pstring devicename;
+
+       /* what the cleint thinks the device is */
+       fstring client_devicetype;
+       /* what the server tells the client the share represents */
+       const char *server_devicetype;
        NTSTATUS nt_status;
        uint16 vuid = SVAL(inbuf,smb_uid);
        int passlen = SVAL(inbuf,smb_vwv3);
        pstring path;
        char *p, *q;
        extern BOOL global_encrypted_passwords_negotiated;
+       
        START_PROFILE(SMBtconX);        
 
-       *service = *devicename = 0;
+       *service = *client_devicetype = 0;
 
        /* we might have to close an old one */
        if ((SVAL(inbuf,smb_vwv2) & 0x1) && conn) {
@@ -250,11 +255,11 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
        else
                fstrcpy(service,path);
                
-       p += srvstr_pull(inbuf, devicename, p, sizeof(devicename), 6, STR_ASCII);
+       p += srvstr_pull(inbuf, client_devicetype, p, sizeof(client_devicetype), 6, STR_ASCII);
 
-       DEBUG(4,("Got device type %s\n",devicename));
+       DEBUG(4,("Client requested device type [%s] for share [%s]\n", client_devicetype, service));
 
-       conn = make_connection(service,password,devicename,vuid,&nt_status);
+       conn = make_connection(service,password,client_devicetype,vuid,&nt_status);
        
        data_blob_clear_free(&password);
 
@@ -263,22 +268,29 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
                return ERROR_NT(nt_status);
        }
 
+       if ( IS_IPC(conn) )
+               server_devicetype = "IPC";
+       else if ( IS_PRINT(conn) )
+               server_devicetype = "LPT1:";
+       else 
+               server_devicetype = "A:";
+
        if (Protocol < PROTOCOL_NT1) {
                set_message(outbuf,2,0,True);
                p = smb_buf(outbuf);
-               p += srvstr_push(outbuf, p, devicename, -1, 
+               p += srvstr_push(outbuf, p, server_devicetype, -1, 
                                 STR_TERMINATE|STR_ASCII);
                set_message_end(outbuf,p);
        } else {
                /* NT sets the fstype of IPC$ to the null string */
-               const char *fsname = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
-
+               const char *fstype = IS_IPC(conn) ? "" : lp_fstype(SNUM(conn));
+               
                set_message(outbuf,3,0,True);
 
                p = smb_buf(outbuf);
-               p += srvstr_push(outbuf, p, devicename, -1, 
+               p += srvstr_push(outbuf, p, server_devicetype, -1, 
                                 STR_TERMINATE|STR_ASCII);
-               p += srvstr_push(outbuf, p, fsname, -1, 
+               p += srvstr_push(outbuf, p, fstype, -1, 
                                 STR_TERMINATE);
                
                set_message_end(outbuf,p);
@@ -387,8 +399,9 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
        mode = SVAL(inbuf,smb_vwv0);
 
        if (check_name(name,conn)) {
-               if (VALID_STAT(sbuf) || vfs_stat(conn,name,&sbuf) == 0)
-                       ok = S_ISDIR(sbuf.st_mode);
+               if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,name,&sbuf) == 0)
+                       if (!(ok = S_ISDIR(sbuf.st_mode)))
+                               errno = ENOTDIR;
        }
 
        if (!ok) {
@@ -445,7 +458,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
        } else {
                unix_convert(fname,conn,0,&bad_path,&sbuf);
                if (check_name(fname,conn)) {
-                       if (VALID_STAT(sbuf) || vfs_stat(conn,fname,&sbuf) == 0) {
+                       if (VALID_STAT(sbuf) || SMB_VFS_STAT(conn,fname,&sbuf) == 0) {
                                mode = dos_mode(conn,fname,&sbuf);
                                size = sbuf.st_size;
                                mtime = sbuf.st_mtime;
@@ -540,7 +553,7 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
        SMB_BIG_UINT dfree,dsize,bsize;
        START_PROFILE(SMBdskattr);
 
-       conn->vfs_ops.disk_free(conn,".",True,&bsize,&dfree,&dsize);
+       SMB_VFS_DISK_FREE(conn,".",True,&bsize,&dfree,&dsize);
   
        outsize = set_message(outbuf,5,0,True);
        
@@ -1115,7 +1128,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                return(UNIXERROR(ERRDOS,ERRnoaccess));
        }
 
-       vfs_stat(conn,fname,&sbuf);
+       SMB_VFS_STAT(conn,fname,&sbuf);
 
        /* Open file in dos compatibility share mode. */
        /* We should fail if file does not exist. */
@@ -1214,7 +1227,7 @@ static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype)
        if (!CAN_WRITE(conn))
                return NT_STATUS_MEDIA_WRITE_PROTECTED;
 
-       if (conn->vfs_ops.lstat(conn,fname,&sbuf) != 0)
+       if (SMB_VFS_LSTAT(conn,fname,&sbuf) != 0)
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 
        fmode = dos_mode(conn,fname,&sbuf);
@@ -1300,12 +1313,12 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
                error = can_delete(directory,conn,dirtype);
                if (!NT_STATUS_IS_OK(error)) return error;
 
-               if (vfs_unlink(conn,directory) == 0) {
+               if (SMB_VFS_UNLINK(conn,directory) == 0) {
                        count++;
                }
        } else {
                void *dirptr = NULL;
-               char *dname;
+               const char *dname;
                
                if (check_name(directory,conn))
                        dirptr = OpenDir(conn, directory, True);
@@ -1330,7 +1343,7 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
                                slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
                                error = can_delete(fname,conn,dirtype);
                                if (!NT_STATUS_IS_OK(error)) continue;
-                               if (vfs_unlink(conn,fname) == 0) count++;
+                               if (SMB_VFS_UNLINK(conn,fname) == 0) count++;
                                DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
                        }
                        CloseDir(dirptr);
@@ -1416,7 +1429,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
                header.length = 4;
                header.free = NULL;
 
-               if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
+               if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
                        /*
                         * Special hack for broken Linux with no 64 bit clean sendfile. If we
                         * return ENOSYS then pretend we just got a normal read.
@@ -1451,6 +1464,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
 
 int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
 {
+       extern struct current_user current_user;
        ssize_t maxcount,mincount;
        size_t nread = 0;
        SMB_OFF_T startpos;
@@ -1540,7 +1554,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
   
                if (size < sizeneeded) {
                        SMB_STRUCT_STAT st;
-                       if (vfs_fstat(fsp,fsp->fd,&st) == 0)
+                       if (SMB_VFS_FSTAT(fsp,fsp->fd,&st) == 0)
                                size = st.st_size;
                        if (!fsp->can_write) 
                                fsp->size = size;
@@ -1709,7 +1723,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
                SMB_STRUCT_STAT sbuf;
                DATA_BLOB header;
 
-               if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1)
+               if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1)
                        return(UNIXERROR(ERRDOS,ERRnoaccess));
 
                if (startpos > sbuf.st_size)
@@ -1736,7 +1750,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
                header.length = data - outbuf;
                header.free = NULL;
 
-               if ( conn->vfs_ops.sendfile( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
+               if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
                        /*
                         * Special hack for broken Linux with no 64 bit clean sendfile. If we
                         * return ENOSYS then pretend we just got a normal read.
@@ -2248,7 +2262,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
                        break;
        }
 
-       if((res = conn->vfs_ops.lseek(fsp,fsp->fd,startpos,umode)) == -1) {
+       if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) {
                /*
                 * Check for the special case where a seek before the start
                 * of the file sets the offset to zero. Added in the CIFS spec,
@@ -2260,7 +2274,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
 
                        if(umode == SEEK_CUR) {
 
-                               if((current_pos = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1) {
+                               if((current_pos = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_CUR)) == -1) {
                                        END_PROFILE(SMBlseek);
                                        return(UNIXERROR(ERRDOS,ERRnoaccess));
                                }
@@ -2271,7 +2285,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
 
                                SMB_STRUCT_STAT sbuf;
 
-                               if(vfs_fstat(fsp,fsp->fd, &sbuf) == -1) {
+                               if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) {
                                        END_PROFILE(SMBlseek);
                                        return(UNIXERROR(ERRDOS,ERRnoaccess));
                                }
@@ -2280,7 +2294,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
                        }
  
                        if(current_pos < 0)
-                               res = conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_SET);
+                               res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET);
                }
 
                if(res == -1) {
@@ -2348,6 +2362,7 @@ int reply_exit(connection_struct *conn,
 int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
                 int dum_buffsize)
 {
+       extern struct current_user current_user;
        int outsize = 0;
        time_t mtime;
        int32 eclass = 0, err = 0;
@@ -2368,7 +2383,7 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
         * We can only use CHECK_FSP if we know it's not a directory.
         */
 
-       if(!fsp || (fsp->conn != conn)) {
+       if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
                END_PROFILE(SMBclose);
                return ERROR_DOS(ERRDOS,ERRbadfid);
        }
@@ -2815,7 +2830,7 @@ NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
        unix_convert(directory,conn,0,&bad_path,&sbuf);
        
        if (check_name(directory, conn))
-               ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
+               ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
        
        if (ret == -1) {
                NTSTATUS nterr = set_bad_path_error(errno, bad_path);
@@ -2861,7 +2876,7 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
 static BOOL recursive_rmdir(connection_struct *conn, char *directory)
 {
-       char *dname = NULL;
+       const char *dname = NULL;
        BOOL ret = False;
        void *dirptr = OpenDir(conn, directory, False);
 
@@ -2886,7 +2901,7 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
                pstrcat(fullname, "/");
                pstrcat(fullname, dname);
 
-               if(conn->vfs_ops.lstat(conn,fullname, &st) != 0) {
+               if(SMB_VFS_LSTAT(conn,fullname, &st) != 0) {
                        ret = True;
                        break;
                }
@@ -2896,11 +2911,11 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
                                ret = True;
                                break;
                        }
-                       if(vfs_rmdir(conn,fullname) != 0) {
+                       if(SMB_VFS_RMDIR(conn,fullname) != 0) {
                                ret = True;
                                break;
                        }
-               } else if(vfs_unlink(conn,fullname) != 0) {
+               } else if(SMB_VFS_UNLINK(conn,fullname) != 0) {
                        ret = True;
                        break;
                }
@@ -2917,7 +2932,7 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
 {
        BOOL ok;
 
-       ok = (vfs_rmdir(conn,directory) == 0);
+       ok = (SMB_VFS_RMDIR(conn,directory) == 0);
        if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
                /* 
                 * Check to see if the only thing in this directory are
@@ -2926,7 +2941,7 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
                 * do a recursive delete) then fail the rmdir.
                 */
                BOOL all_veto_files = True;
-               char *dname;
+               const char *dname;
                void *dirptr = OpenDir(conn, directory, False);
 
                if(dirptr != NULL) {
@@ -2959,21 +2974,21 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
                                        pstrcat(fullname, "/");
                                        pstrcat(fullname, dname);
                      
-                                       if(conn->vfs_ops.lstat(conn,fullname, &st) != 0)
+                                       if(SMB_VFS_LSTAT(conn,fullname, &st) != 0)
                                                break;
                                        if(st.st_mode & S_IFDIR) {
                                                if(lp_recursive_veto_delete(SNUM(conn))) {
                                                        if(recursive_rmdir(conn, fullname) != 0)
                                                                break;
                                                }
-                                               if(vfs_rmdir(conn,fullname) != 0)
+                                               if(SMB_VFS_RMDIR(conn,fullname) != 0)
                                                        break;
-                                       } else if(vfs_unlink(conn,fullname) != 0)
+                                       } else if(SMB_VFS_UNLINK(conn,fullname) != 0)
                                                break;
                                }
                                CloseDir(dirptr);
                                /* Retry the rmdir */
-                               ok = (vfs_rmdir(conn,directory) == 0);
+                               ok = (SMB_VFS_RMDIR(conn,directory) == 0);
                        } else {
                                CloseDir(dirptr);
                        }
@@ -3030,20 +3045,22 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
  Resolve wildcards in a filename rename.
 ********************************************************************/
 
-static BOOL resolve_wildcards(char *name1,char *name2)
+static BOOL resolve_wildcards(const char *name1, char *name2)
 {
        fstring root1,root2;
        fstring ext1,ext2;
-       char *p,*p2;
+       char *p,*p2, *pname1, *pname2;
+       int available_space;
+       
 
-       name1 = strrchr_m(name1,'/');
-       name2 = strrchr_m(name2,'/');
+       pname1 = strrchr_m(name1,'/');
+       pname2 = strrchr_m(name2,'/');
 
-       if (!name1 || !name2)
+       if (!pname1 || !pname2)
                return(False);
   
-       fstrcpy(root1,name1);
-       fstrcpy(root2,name2);
+       fstrcpy(root1,pname1);
+       fstrcpy(root2,pname2);
        p = strrchr_m(root1,'.');
        if (p) {
                *p = 0;
@@ -3085,10 +3102,12 @@ static BOOL resolve_wildcards(char *name1,char *name2)
                        p++;
        }
 
-       pstrcpy(name2,root2);
+       available_space = sizeof(pstring) - PTR_DIFF(pname2, name2);
+       
        if (ext2[0]) {
-               pstrcat(name2,".");
-               pstrcat(name2,ext2);
+               snprintf(pname2, available_space - 1, "%s.%s", root2, ext2);
+       } else {
+               pstrcpy_base(pname2, root2, name2);
        }
 
        return(True);
@@ -3265,7 +3284,7 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
                        return NT_STATUS_OBJECT_NAME_COLLISION;
                }
 
-               if(conn->vfs_ops.rename(conn,directory, newname) == 0) {
+               if(SMB_VFS_RENAME(conn,directory, newname) == 0) {
                        DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
                                directory,newname));
                        return NT_STATUS_OK;    
@@ -3285,7 +3304,7 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
                 * Wildcards - process each file that matches.
                 */
                void *dirptr = NULL;
-               char *dname;
+               const char *dname;
                pstring destname;
                
                if (check_name(directory,conn))
@@ -3332,7 +3351,7 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
                                        continue;
                                }
                                
-                               if (!conn->vfs_ops.rename(conn,fname,destname))
+                               if (!SMB_VFS_RENAME(conn,fname,destname))
                                        count++;
                                DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
                        }
@@ -3426,7 +3445,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
        if (!target_is_directory && count)
                ofun = FILE_EXISTS_OPEN;
 
-       if (vfs_stat(conn,dest,&sbuf2) == -1)
+       if (SMB_VFS_STAT(conn,dest,&sbuf2) == -1)
                ZERO_STRUCTP(&sbuf2);
 
        fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
@@ -3438,7 +3457,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
        }
 
        if ((ofun&3) == 1) {
-               if(conn->vfs_ops.lseek(fsp2,fsp2->fd,0,SEEK_END) == -1) {
+               if(SMB_VFS_LSEEK(fsp2,fsp2->fd,0,SEEK_END) == -1) {
                        DEBUG(0,("copy_file: error - vfs lseek returned error %s\n", strerror(errno) ));
                        /*
                         * Stop the copy from occurring.
@@ -3574,7 +3593,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
                }
        } else {
                void *dirptr = NULL;
-               char *dname;
+               const char *dname;
                pstring destname;
 
                if (check_name(directory,conn))