Bug 15490 - Samba 4.15 -> 4.17 upgrade breaks printing due to false IPv6 detection
Summary: Samba 4.15 -> 4.17 upgrade breaks printing due to false IPv6 detection
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: Build (show other bugs)
Version: unspecified
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Samba QA Contact
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-10-09 03:14 UTC by John Wehle
Modified: 2023-10-09 03:14 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John Wehle 2023-10-09 03:14:12 UTC
Compiled 4.17.11 on a FreeBSD system that happens to have an OS built for only IPv4.  File shares work fine, however printing stopped working after the upgrade.

Tracing through things we get to:

  source3/rpc_server/spoolss/srv_spoolss_nt.c _spoolss_OpenPrinterEx

which fails when executing print_access_check.  The log says:

  ../../source3/rpc_client/cli_pipe.c:3105(rpc_pipe_open_local_np)
    rpc_pipe_open_local_np: local_np_connect for winreg and user NT AUTHORITY\SYSTEM failed: Invalid argument

  ../../source3/rpc_server/rpc_ncacn_np.c:133(rpcint_binding_handle)
    rpcint_binding_handle: rpc_pipe_open_local_np failed: NT_STATUS_INVALID_PARAMETER
 ../../source3/rpc_server/spoolss/srv_spoolss_util.c:57(winreg_printer_binding_handle)
    winreg_printer_binding_handle: Could not connect to winreg pipe: NT_STATUS_INVALID_PARAMETER

  ../../source3/rpc_server/spoolss/srv_spoolss_nt.c:1902(_spoolss_OpenPrinterEx)
    access DENIED for printer open

The call graph looks something like:

  _spoolss_OpenPrinterEx
     print_access_check
        ...
           winreg_printer_binding_handle
              ...
                 local_np_connect
                    ...
                       tsocket_address_inet_from_strings(
                         state->npa_req, "ip", NULL, 0, &addr)

resulting in tsocket_address_inet_from_strings executing:

  ret = getaddrinfo("::", "0", &hints, &result);

which fails with EAI_NONAME that is then mapped to EINVAL.

Now the "::" comes from:

    if (!addr) {
  #ifdef HAVE_IPV6
      addr = "::";
  #else
      addr = "0.0.0.0";
  #endif
    }

bin/config.log shows:

  Checking for HAVE_IPV6
  ...
  #include <stdio.h>
  ...
  #include <sys/socket.h>
  #include <netdb.h>
  #include <netinet/in.h>
  #include <net/if.h>
  int main(void) {
     struct sockaddr_storage sa_store;
     struct addrinfo *ai = NULL;
     struct in6_addr in6addr;
     int idx = if_nametoindex("iface1");
     int s = socket(AF_INET6, SOCK_STREAM, 0);
     int ret = getaddrinfo(NULL, NULL, NULL, &ai);
     if (ret != 0) {
         const char *es = gai_strerror(ret);
     }
     freeaddrinfo(ai);
     {
        int val = 1;
        #ifdef HAVE_LINUX_IPV6_V6ONLY_26
        #define IPV6_V6ONLY 26
        #endif
        ret = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
                         (const void *)&val, sizeof(val));
     }
     ; return 0; }
   ...
  ok

Note that the test program doesn't check if the socket or setsockopt call succeeds.

On my system it suffices to simply comment out the entire lib/replace/wscript IPv6 conf.CHECK_CODE block and rebuild.  The resulting samba is able to print fine.  Presumably someone more fluent with conf.CHECK_CODE can update the test so that the check does the right thing on IPv4 platforms.