[PATH 3/4] Automating usage of smbspool_krb5_wrapper

Mikhail Novosyolov m.novosyolov at rosalinux.ru
Thu Dec 5 21:32:00 UTC 2019


>From b2581f0ecc1253fa4d805b962ac8c7191f92e278 Mon Sep 17 00:00:00 2001
From: Mikhail Novosyolov <m.novosyolov at rosalinux.ru>
Date: Sun, 3 Nov 2019 01:28:13 +0300
Subject: [PATCH 3/4] s3:smbspool_krb5_wrapper: ignore unknown values of
 AUTH_INFO_REQUIRED

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 at rosalinux.ru>
---
 source3/client/smbspool_krb5_wrapper.c | 34 ++++++++++++++++++++------
 source3/script/tests/test_smbspool.sh  | 28 +++++++++++++++++++++
 2 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/source3/client/smbspool_krb5_wrapper.c b/source3/client/smbspool_krb5_wrapper.c
index bd6319ca9c3..a2851d7fbc1 100644
--- a/source3/client/smbspool_krb5_wrapper.c
+++ b/source3/client/smbspool_krb5_wrapper.c
@@ -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 == "none" || 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,
diff --git a/source3/script/tests/test_smbspool.sh b/source3/script/tests/test_smbspool.sh
index 01d72101615..c32ace6682e 100755
--- a/source3/script/tests/test_smbspool.sh
+++ b/source3/script/tests/test_smbspool.sh
@@ -66,6 +66,30 @@ 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
+        22 ) return 0 ;;
+        * )
+            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 +211,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)
-- 
2.20.1






More information about the samba-technical mailing list