Fix bug 7104 - "wide links" and "unix extensions" are incompatible.
[samba.git] / source3 / smbd / trans2.c
index 9c69b3bf2cb9699dcf0e9c0daa9534970b60b901..28862d1f4e8d78de92d71543895c192437117071 100644 (file)
@@ -1012,7 +1012,7 @@ static void call_trans2open(connection_struct *conn,
        pname = &params[28];
 
        if (IS_IPC(conn)) {
-               reply_doserror(req, ERRSRV, ERRaccess);
+               reply_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED);
                goto out;
        }
 
@@ -1055,7 +1055,7 @@ static void call_trans2open(connection_struct *conn,
                                         &access_mask, &share_mode,
                                         &create_disposition,
                                         &create_options)) {
-               reply_doserror(req, ERRDOS, ERRbadaccess);
+               reply_nterror(req, NT_STATUS_ACCESS_DENIED);
                goto out;
        }
 
@@ -1121,7 +1121,7 @@ static void call_trans2open(connection_struct *conn,
        inode = smb_fname->st.st_ex_ino;
        if (fattr & aDIR) {
                close_file(req, fsp, ERROR_CLOSE);
-               reply_doserror(req, ERRDOS,ERRnoaccess);
+               reply_nterror(req, NT_STATUS_ACCESS_DENIED);
                goto out;
        }
 
@@ -1484,7 +1484,6 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
        char *nameptr;
        char *last_entry_ptr;
        bool was_8_3;
-       uint32_t nt_extmode; /* Used for NT connections instead of mode */
        off_t off;
        off_t pad = 0;
 
@@ -1535,8 +1534,6 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
        pad = 0;
        off = 0;
 
-       nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
-
        switch (info_level) {
        case SMB_FIND_INFO_STANDARD:
                DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
@@ -1684,7 +1681,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
                SOFF_T(p,0,file_size); p += 8;
                SOFF_T(p,0,allocation_size); p += 8;
-               SIVAL(p,0,nt_extmode); p += 4;
+               SIVAL(p,0,mode); p += 4;
                q = p; p += 4; /* q is placeholder for name length. */
                {
                        unsigned int ea_size = estimate_ea_size(conn, NULL,
@@ -1750,7 +1747,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
                SOFF_T(p,0,file_size); p += 8;
                SOFF_T(p,0,allocation_size); p += 8;
-               SIVAL(p,0,nt_extmode); p += 4;
+               SIVAL(p,0,mode); p += 4;
                len = srvstr_push(base_data, flags2,
                                  p + 4, fname, PTR_DIFF(end_data, p+4),
                                  STR_TERMINATE_ASCII);
@@ -1786,7 +1783,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
                SOFF_T(p,0,file_size); p += 8;
                SOFF_T(p,0,allocation_size); p += 8;
-               SIVAL(p,0,nt_extmode); p += 4;
+               SIVAL(p,0,mode); p += 4;
                q = p; p += 4; /* q is placeholder for name length. */
                {
                        unsigned int ea_size = estimate_ea_size(conn, NULL,
@@ -1861,7 +1858,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
                SOFF_T(p,0,file_size); p += 8;
                SOFF_T(p,0,allocation_size); p += 8;
-               SIVAL(p,0,nt_extmode); p += 4;
+               SIVAL(p,0,mode); p += 4;
                q = p; p += 4; /* q is placeholder for name length. */
                {
                        unsigned int ea_size = estimate_ea_size(conn, NULL,
@@ -1908,7 +1905,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                put_long_date_timespec(conn->ts_res,p,cdate_ts); p += 8;
                SOFF_T(p,0,file_size); p += 8;
                SOFF_T(p,0,allocation_size); p += 8;
-               SIVAL(p,0,nt_extmode); p += 4;
+               SIVAL(p,0,mode); p += 4;
                q = p; p += 4; /* q is placeholder for name length */
                {
                        unsigned int ea_size = estimate_ea_size(conn, NULL,
@@ -2337,7 +2334,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                }
 
                if (!lp_ea_support(SNUM(conn))) {
-                       reply_doserror(req, ERRDOS, ERReasnotsupported);
+                       reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
                        goto out;
                }
 
@@ -2465,7 +2462,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
        if(numentries == 0) {
                dptr_close(sconn, &dptr_num);
                if (get_Protocol() < PROTOCOL_NT1) {
-                       reply_doserror(req, ERRDOS, ERRnofiles);
+                       reply_force_doserror(req, ERRDOS, ERRnofiles);
                        goto out;
                } else {
                        reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
@@ -2652,7 +2649,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                }
 
                if (!lp_ea_support(SNUM(conn))) {
-                       reply_doserror(req, ERRDOS, ERReasnotsupported);
+                       reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
                        return;
                }
 
@@ -2685,7 +2682,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
 
        /* Check that the dptr is valid */
        if(!(dirptr = dptr_fetch_lanman2(sconn, dptr_num))) {
-               reply_doserror(req, ERRDOS, ERRnofiles);
+               reply_nterror(req, STATUS_NO_MORE_FILES);
                return;
        }
 
@@ -2694,7 +2691,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
        /* Get the wildcard mask from the dptr */
        if((p = dptr_wcard(sconn, dptr_num))== NULL) {
                DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
-               reply_doserror(req, ERRDOS, ERRnofiles);
+               reply_nterror(req, STATUS_NO_MORE_FILES);
                return;
        }
 
@@ -4187,8 +4184,6 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
        } else {
                mode = dos_mode(conn, smb_fname);
        }
-       if (!mode)
-               mode = FILE_ATTRIBUTE_NORMAL;
 
        nlink = psbuf->st_ex_nlink;
 
@@ -5236,8 +5231,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
                        }
 
                        if (!lp_ea_support(SNUM(conn))) {
-                               reply_doserror(req, ERRDOS,
-                                              ERReasnotsupported);
+                               reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
                                return;
                        }
 
@@ -5737,10 +5731,11 @@ static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
                (unsigned int)dosmode,
                (unsigned int)delete_on_close ));
 
-       status = can_set_delete_on_close(fsp, delete_on_close, dosmode);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
+       if (delete_on_close) {
+               status = can_set_delete_on_close(fsp, dosmode);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
        }
 
        /* The set is across all open files on this dev/inode pair. */
@@ -5841,42 +5836,6 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       /* !widelinks forces the target path to be within the share. */
-       /* This means we can interpret the target as a pathname. */
-       if (!lp_widelinks(SNUM(conn))) {
-               char *rel_name = NULL;
-               char *last_dirp = NULL;
-
-               if (*link_target == '/') {
-                       /* No absolute paths allowed. */
-                       return NT_STATUS_ACCESS_DENIED;
-               }
-               rel_name = talloc_strdup(ctx,newname);
-               if (!rel_name) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-               last_dirp = strrchr_m(rel_name, '/');
-               if (last_dirp) {
-                       last_dirp[1] = '\0';
-               } else {
-                       rel_name = talloc_strdup(ctx,"./");
-                       if (!rel_name) {
-                               return NT_STATUS_NO_MEMORY;
-                       }
-               }
-               rel_name = talloc_asprintf_append(rel_name,
-                               "%s",
-                               link_target);
-               if (!rel_name) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               status = check_name(conn, rel_name);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return status;
-               }
-       }
-
        DEBUG(10,("smb_set_file_unix_link: SMB_SET_FILE_UNIX_LINK doing symlink %s -> %s\n",
                        newname, link_target ));
 
@@ -7668,7 +7627,8 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                                                    max_data_bytes);
                                return;
                        } else {
-                               reply_doserror(req, ERRDOS, ERRbadpath);
+                               reply_nterror(req,
+                                       NT_STATUS_OBJECT_PATH_NOT_FOUND);
                                return;
                        }
                } else {
@@ -7808,7 +7768,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
        TALLOC_CTX *ctx = talloc_tos();
 
        if (!CAN_WRITE(conn)) {
-               reply_doserror(req, ERRSRV, ERRaccess);
+               reply_nterror(req, NT_STATUS_ACCESS_DENIED);
                return;
        }
 
@@ -8027,7 +7987,7 @@ static void call_trans2getdfsreferral(connection_struct *conn,
        max_referral_level = SVAL(params,0);
 
        if(!lp_host_msdfs()) {
-               reply_doserror(req, ERRDOS, ERRbadfunc);
+               reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
                return;
        }
 
@@ -8069,7 +8029,7 @@ static void call_trans2ioctl(connection_struct *conn,
        /* check for an invalid fid before proceeding */
 
        if (!fsp) {
-               reply_doserror(req, ERRDOS, ERRbadfid);
+               reply_nterror(req, NT_STATUS_INVALID_HANDLE);
                return;
        }
 
@@ -8098,7 +8058,7 @@ static void call_trans2ioctl(connection_struct *conn,
        }
 
        DEBUG(2,("Unknown TRANS2_IOCTL\n"));
-       reply_doserror(req, ERRSRV, ERRerror);
+       reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
 }
 
 /****************************************************************************
@@ -8324,7 +8284,7 @@ static void handle_trans2(connection_struct *conn, struct smb_request *req,
        default:
                /* Error in request */
                DEBUG(2,("Unknown request %d in trans2 call\n", state->call));
-               reply_doserror(req, ERRSRV,ERRerror);
+               reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
        }
 }
 
@@ -8376,7 +8336,7 @@ void reply_trans2(struct smb_request *req)
                case TRANSACT2_SETFSINFO:
                        break;
                default:
-                       reply_doserror(req, ERRSRV, ERRaccess);
+                       reply_nterror(req, NT_STATUS_ACCESS_DENIED);
                        END_PROFILE(SMBtrans2);
                        return;
                }