]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Consolidate [smb|smb2]_file_link_information code
authorVolker Lendecke <vl@samba.org>
Mon, 15 Sep 2025 18:50:00 +0000 (11:50 -0700)
committerRalph Boehme <slow@samba.org>
Tue, 21 Oct 2025 17:33:29 +0000 (17:33 +0000)
Those two functions were the same except for pulling the dst name.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/smb2_trans2.c

index c35a2122bbe605fb92ab2a695e842892ea3df833..3577563850f2a85ef7c4843c557615b6f8f5c8ca 100644 (file)
@@ -4404,12 +4404,12 @@ static NTSTATUS smb2_file_rename_information(connection_struct *conn,
        return status;
 }
 
-static NTSTATUS smb2_file_link_information(connection_struct *conn,
-                                           struct smb_request *req,
-                                           const char *pdata,
-                                           int total_data,
-                                           files_struct *fsp,
-                                           struct smb_filename *smb_fname_src)
+static NTSTATUS smb_file_link_information(connection_struct *conn,
+                                         struct smb_request *req,
+                                         const char *pdata,
+                                         int total_data,
+                                         files_struct *fsp,
+                                         struct smb_filename *smb_fname_src)
 {
        bool overwrite;
        uint32_t len;
@@ -4419,7 +4419,7 @@ static NTSTATUS smb2_file_link_information(connection_struct *conn,
        struct smb_filename *smb_fname_dst_rel = NULL;
        NTSTATUS status = NT_STATUS_OK;
        uint32_t ucf_flags = ucf_flags_from_smb_request(req);
-       size_t ret;
+       NTTIME dst_twrp = 0;
        TALLOC_CTX *ctx = talloc_tos();
 
        if (!fsp) {
@@ -4437,125 +4437,55 @@ static NTSTATUS smb2_file_link_information(connection_struct *conn,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       ret = srvstr_pull_talloc(ctx,
-                                pdata,
-                                req->flags2,
-                                &newname,
-                                &pdata[20],
-                                 len,
-                                STR_TERMINATE);
-
-        if (ret == (size_t)-1 || newname == NULL) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       status = check_path_syntax(newname,
-                       fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       /* hardlink paths are never DFS. */
-       req->flags2 &= ~FLAGS2_DFS_PATHNAMES;
-       ucf_flags &= ~UCF_DFS_PATHNAME;
-
-       DBG_DEBUG("got name |%s|\n", newname);
-
-       status = filename_convert_dirfsp_rel(ctx,
-                                            conn,
-                                            conn->cwd_fsp,
-                                            newname,
-                                            ucf_flags,
-                                            0, /* No TWRP. */
-                                            &dst_dirfsp,
-                                            &smb_fname_dst,
-                                            &smb_fname_dst_rel);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       if (fsp_is_alternate_stream(fsp)) {
-               /* No hardlink on streams. */
-               return NT_STATUS_NOT_SUPPORTED;
-       }
-
-       DBG_DEBUG("SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
-                 fsp_fnum_dbg(fsp),
-                 fsp_str_dbg(fsp),
-                 smb_fname_str_dbg(smb_fname_dst));
-
-       status = hardlink_internals(ctx,
-                                   conn,
-                                   req,
-                                   overwrite,
-                                   fsp->fsp_name,
-                                   dst_dirfsp,
-                                   smb_fname_dst,
-                                   smb_fname_dst_rel);
-
-       TALLOC_FREE(smb_fname_dst);
-       return status;
-}
-
-static NTSTATUS smb_file_link_information(connection_struct *conn,
-                                           struct smb_request *req,
-                                           const char *pdata,
-                                           int total_data,
-                                           files_struct *fsp,
-                                           struct smb_filename *smb_fname_src)
-{
-       bool overwrite;
-       uint32_t len;
-       char *newname = NULL;
-       struct files_struct *dst_dirfsp = NULL;
-       struct smb_filename *smb_fname_dst = NULL;
-       struct smb_filename *smb_fname_dst_rel = NULL;
-       NTSTATUS status = NT_STATUS_OK;
-       uint32_t ucf_flags = ucf_flags_from_smb_request(req);
-       NTTIME dst_twrp = 0;
-       TALLOC_CTX *ctx = talloc_tos();
-
-       if (!fsp) {
-               return NT_STATUS_INVALID_HANDLE;
-       }
-
-       if (total_data < 20) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
+       if (conn_using_smb2(conn->sconn)) {
+               int ret;
 
-       overwrite = (CVAL(pdata,0) ? true : false);
-       len = IVAL(pdata,16);
+               ret = srvstr_pull_talloc(ctx,
+                                        pdata,
+                                        req->flags2,
+                                        &newname,
+                                        &pdata[20],
+                                        len,
+                                        STR_TERMINATE);
 
-       if (len > (total_data - 20) || (len == 0)) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
+               if (ret == (size_t)-1 || newname == NULL) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
 
-       if (smb_fname_src->flags & SMB_FILENAME_POSIX_PATH) {
-               srvstr_get_path_posix(ctx,
-                               pdata,
-                               req->flags2,
-                               &newname,
-                               &pdata[20],
-                               len,
-                               STR_TERMINATE,
-                               &status);
-               ucf_flags |= UCF_POSIX_PATHNAMES;
+               status = check_path_syntax(newname,
+                                          fsp->fsp_name->flags &
+                                                  SMB_FILENAME_POSIX_PATH);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
        } else {
-               srvstr_get_path(ctx,
-                               pdata,
-                               req->flags2,
-                               &newname,
-                               &pdata[20],
-                               len,
-                               STR_TERMINATE,
-                               &status);
-       }
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
+               if (smb_fname_src->flags & SMB_FILENAME_POSIX_PATH) {
+                       srvstr_get_path_posix(ctx,
+                                             pdata,
+                                             req->flags2,
+                                             &newname,
+                                             &pdata[20],
+                                             len,
+                                             STR_TERMINATE,
+                                             &status);
+                       ucf_flags |= UCF_POSIX_PATHNAMES;
+               } else {
+                       srvstr_get_path(ctx,
+                                       pdata,
+                                       req->flags2,
+                                       &newname,
+                                       &pdata[20],
+                                       len,
+                                       STR_TERMINATE,
+                                       &status);
+               }
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
 
-       if (ucf_flags & UCF_GMT_PATHNAME) {
-               extract_snapshot_token(newname, &dst_twrp);
+               if (ucf_flags & UCF_GMT_PATHNAME) {
+                       extract_snapshot_token(newname, &dst_twrp);
+               }
        }
 
        /* hardlink paths are never DFS. */
@@ -5201,21 +5131,9 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
 
                case SMB_FILE_LINK_INFORMATION:
                {
-                       if (conn_using_smb2(conn->sconn)) {
-                               status = smb2_file_link_information(conn,
-                                                       req,
-                                                       pdata,
-                                                       total_data,
-                                                       fsp,
-                                                       smb_fname);
-                       } else {
-                               status = smb_file_link_information(conn,
-                                                       req,
-                                                       pdata,
-                                                       total_data,
-                                                       fsp,
-                                                       smb_fname);
-                       }
+                       status = smb_file_link_information(
+                               conn, req, pdata, total_data, fsp, smb_fname);
+
                        break;
                }