The branch, master has been updated
       via  2493bfa84e4 s3:include: Fix the smbc_fgetxattr() documentation in 
libsmbclient
       via  1b5e40ef37e s3:libsmb: Call the correct function in smbc_fgetxattr()
       via  8c276ff55ef libsmbclient: Fix negotiating posix_extensions
       via  e6e1cd75350 s4:torture: Implement posix extension tests for 
libsmbclient
       via  3a5826d2fac selftest: Add some hardlinks for testing SMB3 posix 
extensions
      from  249e77e24d8 bootstrap: Update Fedora to version 43

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 2493bfa84e48badb9e7e8460e16aea68f90f431b
Author: Andreas Schneider <[email protected]>
Date:   Thu Nov 27 17:07:02 2025 +0100

    s3:include: Fix the smbc_fgetxattr() documentation in libsmbclient
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15960
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>
    
    Autobuild-User(master): Andreas Schneider <[email protected]>
    Autobuild-Date(master): Tue Dec  9 19:33:22 UTC 2025 on atb-devel-224

commit 1b5e40ef37eacaf2598401b43c1e9944e88a2308
Author: Andreas Schneider <[email protected]>
Date:   Tue Nov 25 17:21:49 2025 +0100

    s3:libsmb: Call the correct function in smbc_fgetxattr()
    
    Looks like nobody ever tested this.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15960
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 8c276ff55efd3577e2a141613190231eefb8063f
Author: Andreas Schneider <[email protected]>
Date:   Tue Nov 25 19:06:48 2025 +0100

    libsmbclient: Fix negotiating posix_extensions
    
    Without this, smbc_setOptionPosixExtensions() does nothing.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15960
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit e6e1cd753509698766de46df29c490fae5fcde9d
Author: Andreas Schneider <[email protected]>
Date:   Thu Nov 27 16:02:57 2025 +0100

    s4:torture: Implement posix extension tests for libsmbclient
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15960
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 3a5826d2facf140e610ca08cc80340c7aa5cf96a
Author: Andreas Schneider <[email protected]>
Date:   Thu Nov 27 16:33:28 2025 +0100

    selftest: Add some hardlinks for testing SMB3 posix extensions
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15960
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 selftest/target/Samba3.pm                   |   8 ++
 source3/include/libsmbclient.h              |  28 +++-
 source3/libsmb/libsmb_compat.c              |   5 +-
 source3/libsmb/libsmb_server.c              |  57 +++-----
 source4/selftest/tests.py                   |   2 +
 source4/torture/libsmbclient/libsmbclient.c | 206 ++++++++++++++++++++++++++++
 6 files changed, 266 insertions(+), 40 deletions(-)


Changeset truncated at 500 lines:

diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index ee1d8802223..dc6f7314a5d 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -2881,6 +2881,14 @@ sub provision($$)
        ##
        symlink "$widelinks_shrdir", "$widelinks_shrdir/dot";
 
+       ##
+       ## Create test file with hardlinks for posix extensions testing with
+       ## [smb3_posix_share]
+       ##
+       create_file_chmod("$shrdir/posix_test_original.txt", 0644) or return 
undef;
+       link "$shrdir/posix_test_original.txt", 
"$shrdir/posix_test_hardlink1.txt";
+       link "$shrdir/posix_test_original.txt", 
"$shrdir/posix_test_hardlink2.txt";
+
        my $conffile="$libdir/server.conf";
        my $dfqconffile="$libdir/dfq.conf";
        my $errorinjectconf="$libdir/error_inject.conf";
diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h
index 948eba3361a..e3a2094754e 100644
--- a/source3/include/libsmbclient.h
+++ b/source3/include/libsmbclient.h
@@ -2477,6 +2477,31 @@ int smbc_lgetxattr(const char *url,
  *                  to names.  Without the plus sign, SIDs are not mapped;
  *                  rather they are simply converted to a string format.
  *
+ *                  When POSIX extensions are enabled (via
+ *                  smbc_setOptionPosixExtensions()), the following additional
+ *                  attribute names are available:
+ *
+ *                     posix.attr.enabled
+ *                        Returns "1" if POSIX extensions are active on the
+ *                        server connection, "0" otherwise. The value buffer
+ *                        must be at least 2 bytes to include the null
+ *                        terminator. The returned size is 1 (excluding the
+ *                        null terminator).
+ *                        This is only a check on internal structures, it
+ *                        doesn't produce any network traffic.
+ *
+ *                     smb311_posix.statinfo
+ *                        Returns POSIX stat information via a network call to
+ *                        the server. The value buffer must be at least
+ *                        sizeof(struct stat) + 4 bytes. The buffer contains a
+ *                        struct stat followed by 4 bytes of DOS attributes.
+ *                        The returned size is sizeof(struct stat), which
+ *                        should be used as the offset to read the DOS
+ *                        attributes from the buffer. This provides e.g the
+ *                        correct uid/gid on the server and hardlink counts
+ *                        (st_nlink) and other POSIX metadata not available
+ *                        through standard stat calls.
+ *
  * @param value     A pointer to a buffer in which the value of the specified
  *                  attribute will be placed (unless size is zero).
  *
@@ -2485,7 +2510,8 @@ int smbc_lgetxattr(const char *url,
  *                  required to hold the attribute value will be returned,
  *                  but nothing will be placed into the value buffer.
  *
- * @return          0 on success, < 0 on error with errno set:
+ * @return          On success, the number of bytes of the extended attribute
+ *                  returned. On error, -1 is returned with errno set:
  *                  - EINVAL  The client library is not properly initialized
  *                            or one of the parameters is not of a correct
  *                            form
diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c
index 465bb3c70ee..2a064ec0938 100644
--- a/source3/libsmb/libsmb_compat.c
+++ b/source3/libsmb/libsmb_compat.c
@@ -482,9 +482,8 @@ smbc_fgetxattr(int fd,
                errno = EBADF;
                return -1;
        }
-        return smbc_getFunctionGetxattr(statcont)(statcont,
-                                                  file->fname, name,
-                                                  value, size);
+       return smbc_getFunctionFGetxattr(statcont)
+               (statcont, file, name, value, size);
 }
 
 int
diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c
index f9b52e1f05a..7b1def05f0b 100644
--- a/source3/libsmb/libsmb_server.c
+++ b/source3/libsmb/libsmb_server.c
@@ -547,6 +547,10 @@ SMBC_server_internal(TALLOC_CTX *ctx,
                signing_state = SMB_SIGNING_REQUIRED;
        }
 
+       if (context->internal->posix_extensions) {
+               flags |= CLI_FULL_CONNECTION_REQUEST_POSIX;
+       }
+
        if (nts.num_transports != 0 && ots.num_transports != 0) {
                if (share == NULL || *share == '\0' || is_ipc) {
                        /*
@@ -554,15 +558,15 @@ SMBC_server_internal(TALLOC_CTX *ctx,
                         */
                        ts = &ots;
 
-                       status = cli_connect_nb(NULL,
-                                               server_n,
-                                               NULL,
-                                               &nts,
-                                               0x20,
-                                               smbc_getNetbiosName(context),
-                                               signing_state,
-                                               flags,
-                                               &c);
+                       status = cli_start_connection(
+                               context->internal->mem_ctx,
+                               &c,
+                               smbc_getNetbiosName(context),
+                               server_n,
+                               NULL, /* dest_ss */
+                               &nts, /* transports */
+                               signing_state,
+                               flags);
                }
        }
 
@@ -570,15 +574,14 @@ SMBC_server_internal(TALLOC_CTX *ctx,
                /*
                 * No IPC$ or 139 did not work
                 */
-               status = cli_connect_nb(NULL,
-                                       server_n,
-                                       NULL,
-                                       ts,
-                                       0x20,
-                                       smbc_getNetbiosName(context),
-                                       signing_state,
-                                       flags,
-                                       &c);
+               status = cli_start_connection(context->internal->mem_ctx,
+                                             &c,
+                                             smbc_getNetbiosName(context),
+                                             server_n,
+                                             NULL, /* dest_ss */
+                                             ts, /* transports */
+                                             signing_state,
+                                             flags);
        }
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -592,24 +595,6 @@ SMBC_server_internal(TALLOC_CTX *ctx,
 
        cli_set_timeout(c, smbc_getTimeout(context));
 
-       status = smbXcli_negprot(c->conn,
-                                c->timeout,
-                                lp_client_min_protocol(),
-                                lp_client_max_protocol(),
-                                NULL,
-                                NULL,
-                                NULL);
-       if (!NT_STATUS_IS_OK(status)) {
-               cli_shutdown(c);
-               errno = map_errno_from_nt_status(status);
-               return NULL;
-       }
-
-       if (smbXcli_conn_protocol(c->conn) >= PROTOCOL_SMB2_02) {
-               /* Ensure we ask for some initial credits. */
-               smb2cli_conn_set_max_credits(c->conn, DEFAULT_SMB2_MAX_CREDITS);
-       }
-
        username_used = *pp_username;
        password_used = *pp_password;
 
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 0035c9509bb..92cf9cdea0d 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -449,6 +449,8 @@ for t in libsmbclient:
         url = "smb://$USERNAME:$PASSWORD@$SERVER"
     if t == "libsmbclient.utimes":
         url += "/utimes.txt"
+    if t == "libsmbclient.posix_extensions" or t == 
"libsmbclient.posix_hardlinks":
+        url = "smb://$USERNAME:$PASSWORD@$SERVER/smb3_posix_share"
 
     libsmbclient_testargs = [
         '//$SERVER/tmp',
diff --git a/source4/torture/libsmbclient/libsmbclient.c 
b/source4/torture/libsmbclient/libsmbclient.c
index 72af8fc01c9..7cb964bb625 100644
--- a/source4/torture/libsmbclient/libsmbclient.c
+++ b/source4/torture/libsmbclient/libsmbclient.c
@@ -1578,6 +1578,208 @@ static bool torture_libsmbclient_getxattr(struct 
torture_context *tctx)
        return ok;
 }
 
+static bool torture_libsmbclient_init_posix_context(struct torture_context 
*tctx,
+                                                    SMBCCTX **ctx_p)
+{
+       SMBCCTX *ctx = NULL;
+       SMBCCTX *p = NULL;
+       bool ok = true;
+
+       ctx = smbc_new_context();
+       torture_assert_not_null_goto(
+               tctx, ctx, ok, out, "Failed to create new context");
+
+       torture_comment(tctx, "Enabling POSIX extensions\n");
+       smbc_setOptionPosixExtensions(ctx, true);
+
+       p = smbc_init_context(ctx);
+       torture_assert_not_null_goto(tctx,
+                                    p,
+                                    ok,
+                                    out,
+                                    "Failed to initialize context");
+
+       smbc_setFunctionAuthData(ctx, auth_callback);
+       smbc_set_context(ctx);
+
+       *ctx_p = ctx;
+
+out:
+       if (!ok) {
+               smbc_free_context(ctx, true);
+       }
+
+       return ok;
+}
+
+static bool torture_libsmbclient_posix_extensions(struct torture_context *tctx)
+{
+       const char *smburl = torture_setting_string(tctx, "smburl", NULL);
+       int fhandle = -1;
+       SMBCCTX *ctx = NULL;
+       char *posix_name = NULL;
+       char buf[2] = {'\0'};
+       bool ok = false;
+       int ret = -1;
+
+       if (smburl == NULL) {
+               torture_fail(tctx,
+                            "option --option=torture:smburl="
+                            "smb://user:password@server missing\n");
+       }
+
+       torture_assert_goto(tctx,
+                           torture_libsmbclient_init_posix_context(tctx, &ctx),
+                           ok,
+                           done,
+                           "Failed to init POSIX context");
+
+       posix_name = talloc_asprintf(tctx,
+                                    "%s/posix_test_original.txt",
+                                    smburl);
+       torture_assert_not_null_goto(tctx,
+                                    posix_name,
+                                    ok,
+                                    done,
+                                    "talloc_asprintf failed\n");
+
+       /* Open the test file */
+       fhandle = smbc_open(posix_name, O_RDONLY, 0);
+       torture_assert_goto(tctx,
+                           fhandle >= 0,
+                           ok,
+                           done,
+                           talloc_asprintf(tctx,
+                                           "failed to open file '%s': %s",
+                                           posix_name,
+                                           strerror(errno)));
+
+       /*
+        * Check if we got POSIX extensions by reading the
+        * "posix.attr.enabled" extended attribute.
+        * This should return "1" if POSIX extensions are active.
+        */
+       torture_comment(tctx, "Checking for POSIX extensions\n");
+       ret = smbc_fgetxattr(fhandle, "posix.attr.enabled", buf, sizeof(buf));
+
+       torture_assert_int_equal_goto(
+               tctx,
+               ret,
+               1,
+               ok,
+               done,
+               "smbc_fgetxattr(posix.attr.enabled) failed");
+
+       torture_assert_str_equal_goto(
+               tctx, buf, "1", ok, done, "POSIX extensions not enabled.");
+       torture_comment(tctx, "POSIX extensions are enabled!\n");
+
+       ok = true;
+
+done:
+       if (fhandle >= 0) {
+               smbc_close(fhandle);
+       }
+       if (ctx != NULL) {
+               smbc_free_context(ctx, 1);
+       }
+
+       return ok;
+}
+
+static bool torture_libsmbclient_posix_hardlinks(struct torture_context *tctx)
+{
+       const char *smburl = torture_setting_string(tctx, "smburl", NULL);
+       int fhandle = -1;
+       SMBCCTX *ctx = NULL;
+       char *posix_name = NULL;
+       char buf[sizeof(struct stat) + 4]; /* +4 bytes for DOS attributes */
+       struct stat st_posix;
+       bool ok = false;
+       int ret = -1;
+
+       if (smburl == NULL) {
+               torture_fail(tctx,
+                            "option --option=torture:smburl="
+                            "smb://user:password@server missing\n");
+       }
+
+       torture_assert_goto(tctx,
+                           torture_libsmbclient_init_posix_context(tctx, &ctx),
+                           ok,
+                           done,
+                           "Failed to init POSIX context");
+
+       posix_name = talloc_asprintf(tctx,
+                                    "%s/posix_test_original.txt",
+                                    smburl);
+       torture_assert_not_null_goto(tctx,
+                                    posix_name,
+                                    ok,
+                                    done,
+                                    "talloc_asprintf failed\n");
+
+       /* Open the file with hardlinks */
+       fhandle = smbc_open(posix_name, O_RDONLY, 0);
+       torture_assert_goto(tctx,
+                           fhandle >= 0,
+                           ok,
+                           done,
+                           talloc_asprintf(tctx,
+                                           "failed to open file '%s': %s",
+                                           posix_name,
+                                           strerror(errno)));
+
+       /*
+        * Get POSIX stat information including hardlink count
+        */
+       torture_comment(tctx, "Getting POSIX stat info for hardlink test\n");
+       ret = smbc_fgetxattr(fhandle,
+                            "smb311_posix.statinfo",
+                            buf,
+                            sizeof(buf));
+
+       torture_assert_int_equal_goto(
+               tctx,
+               ret,
+               sizeof(struct stat),
+               ok,
+               done,
+               talloc_asprintf(tctx,
+                               "smbc_fgetxattr(smb311_posix.statinfo) "
+                               "returned %d, expected %zu",
+                               ret,
+                               sizeof(struct stat)));
+
+       memcpy(&st_posix, buf, sizeof(struct stat));
+
+       torture_comment(tctx,
+                       "File has %lu hardlinks\n",
+                       (unsigned long)st_posix.st_nlink);
+
+       torture_assert_int_equal_goto(
+               tctx,
+               st_posix.st_nlink,
+               3,
+               ok,
+               done,
+               talloc_asprintf(tctx,
+                               "Expected 3 hardlinks, got %lu",
+                               (unsigned long)st_posix.st_nlink));
+
+       ok = true;
+
+done:
+       if (fhandle >= 0) {
+               smbc_close(fhandle);
+       }
+       if (ctx != NULL) {
+               smbc_free_context(ctx, 1);
+       }
+
+       return ok;
+}
+
 NTSTATUS torture_libsmbclient_init(TALLOC_CTX *ctx)
 {
        struct torture_suite *suite;
@@ -1608,6 +1810,10 @@ NTSTATUS torture_libsmbclient_init(TALLOC_CTX *ctx)
                torture_libsmbclient_getatr);
        torture_suite_add_simple_test(suite, "getxattr",
                torture_libsmbclient_getxattr);
+       torture_suite_add_simple_test(suite, "posix_extensions",
+               torture_libsmbclient_posix_extensions);
+       torture_suite_add_simple_test(suite, "posix_hardlinks",
+               torture_libsmbclient_posix_hardlinks);
 
        suite->description = talloc_strdup(suite, "libsmbclient interface 
tests");
 


-- 
Samba Shared Repository

Reply via email to