s3:smbspool_krb5_wrapper: ignore unknown values of AUTH_INFO_REQUIRED
authorMikhail Novosyolov <m.novosyolov@rosalinux.ru>
Sat, 2 Nov 2019 22:28:13 +0000 (01:28 +0300)
committerGünther Deschner <gd@samba.org>
Mon, 9 Dec 2019 12:48:45 +0000 (12:48 +0000)
To make smbspool_krb5_wrapper usable as a default destination for symlink
/usr/lib/cups/backend/smb in Linux ditros, it has to be well-prepared
for any possible values of AUTH_INFO_REQUIRED set by cupsd and correctly
pass printing tasks to smbspool if it sees that Kerberos authentication
is not needed.

Discussed here: https://lists.samba.org/archive/samba-technical/2019-October/134470.html

Signed-off-by: Mikhail Novosyolov <m.novosyolov@rosalinux.ru>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
source3/client/smbspool_krb5_wrapper.c
source3/script/tests/test_smbspool.sh

index 85b0d0952a9d190b4e1eb8cac104c21af557c3e3..9290893163da8ba9f43094b1bfb3b436f94ce0d9 100644 (file)
@@ -145,36 +145,56 @@ int main(int argc, char *argv[])
                snprintf(device_uri, sizeof(device_uri), "%s", env);
        }
 
-       /* Check if AuthInfoRequired is set to negotiate */
+       /* We must handle the following values of AUTH_INFO_REQUIRED:
+        *  none: Anonymous/guest printing
+        *  username,password: A username (of the form "username" or "DOMAIN\username")
+        *                     and password are required
+        *  negotiate: Kerberos authentication
+        *  NULL (not set): will never happen when called from cupsd
+        * https://www.cups.org/doc/spec-ipp.html#auth-info-required
+        * https://github.com/apple/cups/issues/5674
+        */
        env = getenv("AUTH_INFO_REQUIRED");
 
         /* If not set, then just call smbspool. */
        if (env == NULL || env[0] == 0) {
                CUPS_SMB_DEBUG("AUTH_INFO_REQUIRED is not set - "
-                              "execute smbspool");
+                              "executing smbspool");
+               /* Pass this printing task to smbspool without Kerberos auth */
                goto smbspool;
        } else {
                CUPS_SMB_DEBUG("AUTH_INFO_REQUIRED=%s", env);
 
+               /* First test the value of AUTH_INFO_REQUIRED
+                * against known possible values
+                */
                cmp = strcmp(env, "none");
                if (cmp == 0) {
                        CUPS_SMB_DEBUG("Authenticate using none (anonymous) - "
-                                      "execute smbspool");
+                                      "executing smbspool");
                        goto smbspool;
                }
 
                cmp = strcmp(env, "username,password");
                if (cmp == 0) {
                        CUPS_SMB_DEBUG("Authenticate using username/password - "
-                                      "execute smbspool");
+                                      "executing smbspool");
                        goto smbspool;
                }
 
+               /* Now, if 'goto smbspool' still has not happened,
+                * there are only two variants left:
+                * 1) AUTH_INFO_REQUIRED is "negotiate" and then
+                *    we have to continue working
+                * 2) or it is something not known to us, then Kerberos
+                *    authentication is not required, so just also pass
+                *    this task to smbspool
+                */
                cmp = strcmp(env, "negotiate");
                if (cmp != 0) {
-                       CUPS_SMB_ERROR("Authentication unsupported");
-                       fprintf(stderr, "ATTR: auth-info-required=negotiate\n");
-                       return CUPS_BACKEND_AUTH_REQUIRED;
+                       CUPS_SMB_DEBUG("Value of AUTH_INFO_REQUIRED is not known "
+                                      "to smbspool_krb5_wrapper, executing smbspool");
+                       goto smbspool;
                }
 
                snprintf(auth_info_required,
index 01d72101615b2325165830ac6a6a05ce6e02537f..ae4ac989e55c7f1c26e4727873bd1af534be7496 100755 (executable)
@@ -66,6 +66,31 @@ test_smbspool_authinforequired_none()
        return 0
 }
 
+test_smbspool_authinforequired_unknown()
+{
+       cmd='$samba_smbspool_krb5 smb://$SERVER_IP/print4 200 $USERNAME "Testprint" 1 "options" $SRCDIR/testdata/printing/example.ps 2>&1'
+
+       # smbspool_krb5_wrapper must ignore AUTH_INFO_REQUIRED unknown to him and pass the task to smbspool
+       # smbspool must fail with NT_STATUS_ACCESS_DENIED (22)
+       # "jjf4wgmsbc0" is just a random string
+       AUTH_INFO_REQUIRED="jjf4wgmsbc0"
+       export AUTH_INFO_REQUIRED
+       eval echo "$cmd"
+       out=$(eval $cmd)
+       ret=$?
+       unset AUTH_INFO_REQUIRED
+
+       case "$ret" in
+               2 ) return 0 ;;
+               * )
+                       echo "ret=$ret"
+                       echo "$out"
+                       echo "failed to test $smbspool_krb5 against unknown value of AUTH_INFO_REQUIRED"
+                       return 1
+               ;;
+       esac
+}
+
 #
 # The test enviornment uses 'vlp' (virtual lp) as the printing backend.
 #
@@ -187,6 +212,10 @@ testit "smbspool_krb5_wrapper AuthInfoRequired=none" \
        test_smbspool_authinforequired_none || \
        failed=$(expr $failed + 1)
 
+testit "smbspool_krb5_wrapper AuthInfoRequired=(sth unknown)" \
+       test_smbspool_authinforequired_unknown || \
+       failed=$(expr $failed + 1)
+
 testit "smbspool print example.ps" \
        $samba_smbspool smb://$USERNAME:$PASSWORD@$SERVER_IP/print1 200 $USERNAME "Testprint" 1 "options" $SRCDIR/testdata/printing/example.ps || \
        failed=$(expr $failed + 1)