Bug 52051 - Samba printer driver issues because of upper- and lowercase driver files
Samba printer driver issues because of upper- and lowercase driver files
Status: CLOSED FIXED
Product: UCS
Classification: Unclassified
Component: Samba
UCS 4.4
Other Linux
: P5 normal (vote)
: UCS 5.0-3-errata
Assigned To: Felix Botner
Arvid Requate
https://bugzilla.samba.org/show_bug.c...
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2020-09-17 13:51 CEST by Christian Völker
Modified: 2023-03-01 14:55 CET (History)
7 users (show)

See Also:
What kind of report is it?: Bug Report
What type of bug is this?: 5: Major Usability: Impairs usability in key scenarios
Who will be affected by this bug?: 3: Will affect average number of installed domains
How will those affected feel about the bug?: 3: A User would likely not purchase the product
User Pain: 0.257
Enterprise Customer affected?:
School Customer affected?: Yes
ISV affected?:
Waiting Support: Yes
Flags outvoted (downgraded) after PO Review: Yes
Ticket number: 2020091721000367
Bug group (optional):
Max CVSS v3 score:


Attachments
Lexmark Driver (30.33 MB, application/x-ms-dos-executable)
2020-09-28 12:22 CEST, Christian Völker
Details
HP Driver (19.40 MB, application/x-ms-dos-executable)
2020-09-28 12:23 CEST, Christian Völker
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Christian Völker univentionstaff 2020-09-17 13:51:47 CEST
customer investigated and reported an issue with printer drivers which could indeed lead to several issues related to Windows printing:
===============================================================
Hello,

while investigating unexplained printer driver problems yesterday I noticed an interesting malfunction in Samba that could have been responsible for all kinds of printing problems for ages.

The scenario: A Windows printer driver, e.g. from Lexmark, is uploaded to the Samba server via the mechanisms integrated in Windows and ends up in the "print$" share.

A few years later it is necessary to upload a newer version of the driver, but the manufacturer has decided to specify the individual driver files in the INF file now completely in Uppercase, which is no problem in the Windows world, because "driver.dll" and "DRIVER.DLL" reference the same file there and cannot both exist in the same folder. But if the new driver is uploaded to the Samba server, the new files will not overwrite the old ones, but suddenly there is a "driver.dll" and a "DRIVER.DLL" in the print$ share. This seems to cause an undefined behavior when Windows accesses the file later - sometimes the old file is loaded, sometimes the new one, which leads to crashes of the printer driver due to version mismatches. Even if the driver is deleted later, the "duplicate" files remain in the share and become orphaned.

I suppose the problem has its origin in the fact that Windows does not copy the driver files directly into the destination folder "\print$\$Architecture\3\" when uploading the driver files, but into a randomly generated folder "\print$\$Architecture\{$RANDOMGUID}\". It then calls a specific function call on the server, which causes Samba to move the files from the temporary folder to the "\3" folder on the server side. Samba uses the target filenames exactly as they appear in the INF file (I checked this by modifying the INF file) - and probably doesn't care if there is already a file with the same name in the target folder.

Another interesting fact is that Samba apparently compares the versions of new and existing driver files on the server side, but is correctly case-insensitive: If a "driver.dll" in version "2.0.0.0" already exists and the client tries to upload a "DRIVER.DLL" in version "1.0.0.0", the latter will not be moved to the destination folder. So the resulting files in the "\3" folder also depend on the order in which you upload your printer drivers.

I had already tested whether it helps to work with the Samba parameters "case sensitive", "default case", "preserve case", etc. for the "print$" share, but these parameters only affect the files that Windows initially copies into the temporary folder. When finally moving them to their destination, Samba always uses exactly the file names from the INF file, as mentioned before.
=======================================================================
Comment 1 Ingo Steuwer univentionstaff 2020-09-21 09:41:35 CEST
From smb.conf man page:

       case sensitive = yes/no/auto
           controls whether filenames are case sensitive. If they aren't, Samba must do a filename search and match on passed names. The
           default setting of auto allows clients that support case sensitive filenames (Linux CIFSVFS and smbclient 3.0.5 and above
           currently) to tell the Samba server on a per-packet basis that they wish to access the file system in a case-sensitive manner
           (to support UNIX case sensitive semantics). No Windows or DOS system supports case-sensitive filename so setting this option to
           auto is that same as setting it to no for them. Default auto.

On my UCS Systems, "case sensitive" is not defined or is set to "No" for a few shares. From my understanding, the description of this bug conflicts with the behaviour documented by the samba team.

Was the configuration of the system where this bug occured the default configuration?

Can this bug be reproduced?


Remark: Windows 10 can be configured to be case sensitive for more than 2 years now, see for example https://www.windowscentral.com/how-enable-ntfs-treat-folders-case-sensitive-windows-10 - so this problem is going to be generic, not samba only.
Comment 2 Christian Völker univentionstaff 2020-09-21 11:24:11 CEST
First, the smb.con man pages states:
"No Windows or DOS system supports case-sensitive filename so setting this option to auto is that same as setting it to no for them. Default auto."

So there is no need to change this flag for Samba/UCS as the customer mostly uses Windows client machines and tested as described different settings and none changed the behavior.


Second, regarding the provided link. This applies only if the optional LinuxSubSystem feature on Windows is enabled. Which is usually not. And if it is enabled you are allowed to change the behavior for local paths but not for connected shares and especially not for a share named "print$".

Additionally (from https://devblogs.microsoft.com/commandline/per-directory-case-sensitivity-and-wsl/):
"Note that the per-directory case sensitivity flag is not inherited; directories created in a case sensitive directory are not automatically case sensitive themselves. You must explicitly mark each directory as case sensitive. Changing the flag requires “write attributes” permission to the directory."

So there is no way to make windows taking care of cases while installing printer drivers. This is because the destination folder is created on the fly and therefore doe not inherit an theoretically set "case sensitive" flag.


Nevermind, the behavior is as described. There will be multiple files in the directory with different cases and it can not be told which file Windows takes to install the printer. Leading in different driver versions causing issues.
Comment 3 Ingo Steuwer univentionstaff 2020-09-21 12:54:37 CEST
Thank you for the additional information. Can you also answer my questions?

> Was the configuration of the system where this bug occured the default 
> configuration?
>
> Can this bug be reproduced?
Comment 4 Arvid Requate univentionstaff 2020-09-21 13:27:50 CEST
We would need the exact driver and vendor to reproduce.
Comment 5 Christian Völker univentionstaff 2020-09-28 12:22:01 CEST
Comment from customer:

====================
Laden Sie mal den „HP Universal Treiber“ und den „Lexmark Universal Treiber“ auf einen Samba-Server hoch. Beide enthalten ein paar gemeinsame (offenbar von Windows geborgte) DLLs, u.a. die „unidrv.dll“. Bei HP wird sie klein geschrieben, bei Lexmark groß…

====================
Upload the "HP Universal Driver" and the "Lexmark Universal Driver" to a Samba server. Both contain a few common DLLs (apparently borrowed from Windows), including the "unidrv.dll". At HP it is written in lower case, at Lexmark it is written in capital letters...
====================

Both drivers attached.
Comment 6 Christian Völker univentionstaff 2020-09-28 12:22:38 CEST
Created attachment 10501 [details]
Lexmark Driver
Comment 7 Christian Völker univentionstaff 2020-09-28 12:23:02 CEST
Created attachment 10502 [details]
HP Driver
Comment 10 Ingo Steuwer univentionstaff 2020-11-01 21:45:03 CET
Am I right that a workround once this ugly problem has been identified exists?
Comment 11 Christian Völker univentionstaff 2020-11-02 08:08:49 CET
I am not aware of a workaround. What should it be?
Comment 12 Arvid Requate univentionstaff 2020-11-02 19:27:33 CET
Maybe we can experiment with "preserve case = no" for the print$ share.
Comment 13 Arvid Requate univentionstaff 2020-11-02 19:36:16 CET
Samba had case issues in the print$ share directories, maybe we can learn something from that, e.g. https://bugzilla.samba.org/show_bug.cgi?id=6669
Comment 14 Markus Dählmann 2020-11-05 10:42:42 CET
The problem can most likely not be mitigated with Samba's case sensitivity options. As soon as Samba has decided to move a driver file from the temporary location to the final location in the print$ share, it uses the exact file name as specified in the .inf file. If that happens to be "driver.dll" and "DRIVER.DLL" already exists there, both files will remain, causing trouble.
Comment 15 Ingo Steuwer univentionstaff 2020-11-06 13:54:06 CET
(In reply to Christian Völker from comment #11)
> I am not aware of a workaround. What should it be?

my understand was that there is a way to correct upper and lower case following the .ini file. Am I wrong?
Comment 16 Christian Völker univentionstaff 2020-11-30 12:23:27 CET
(In reply to Ingo Steuwer from comment #15)
> (In reply to Christian Völker from comment #11)
> > I am not aware of a workaround. What should it be?
> 
> my understand was that there is a way to correct upper and lower case
> following the .ini file. Am I wrong?

No, there is not. 
Again, the explanation of the issue here:

In driver version 1 we have the file written as "PRINTER.DLL".
In driver version 2 we have it as "printer.dll"

Windows preserves the capitalization but the file system does not differ. So in a Windows-only environment the following will happen:
1. PRINTER.DLL is copied to temp directory
2. Windows moves PRINTER.DLL to final destination
3. new version installed; printer.dll copied to temp dir
4. file printer.dll moved to final dest overwriting the PRINTER.DLL as is appears to be a file system call which does not differ capitalized names.
5. Only a single file "printer.dll" exists and can be accessed by clients.
6. Clients accessing the printer.dll or PrInTeR.DlL PRINTER.dll will get the printer.dll as Windows is not case sensitive.

In Samba environment it looks like this (1-3 the same):
1. PRINTER.DLL is copied to temp directory
2. Samba moves PRINTER.DLL to final destination
3. new version installed; printer.dll copied to temp dir
4. file printer.dll moved to final dest - by NOT overwriting the PRINTER.DLL as is handled by the file system as different file
5. Two files in directory named printer.dll and PRINTER.DLL
6. Clients will always get the file with first match in the linux filesystem structure. If "PRINTER.DLL" is "higher" than "printer.dll" it will bring "PRINTER.DLL". If the directory entry of "PRINTER.DLL" is lower it will deliver printer.dll


Yes, it might help to modify the .inf file but this would result in a huge work:
1. Identify dll versions on all configured printers and remove outdated ones from final destination manually (is there a way to identify dll file versions?)
OR
Remove all printers and Re-Install ALL printers from scratch
2. For ALL further updates, manually edit the driver .inf files to match the existing driver file.

I would say this is not a suitable workaround...
Comment 17 Ingo Steuwer univentionstaff 2020-11-30 20:35:42 CET
Thank you for the clarification, that helped a lot.

What I'm now wondering: what is the desired behaviour?

In both examples (windows behaviour and Samba behaviour) in the end a randomly choosen printer.dll is delivered to the client: either the one from the driver installed latest (Windows) or the one found earlier in the directory structure (Linux). None of them sounds reliable to me.

How does Windows ensure that the printer.dll related to the needed driver is delivered to the client?
Comment 18 Christian Völker univentionstaff 2020-11-30 22:37:39 CET
> In both examples (windows behaviour and Samba behaviour) in the end a
> randomly choosen printer.dll is delivered to the client: 

No, it is not. In Windows there is only a single file. As the previous gets overwritten because Windows does not care about upper or lower. Therefore it is always the latest (and correct) one.


> How does Windows ensure that the printer.dll related to the needed driver is
> delivered to the client?

See above. There is only a single file as the filesystem does not keep multiple ones.
Comment 19 Markus Dählmann 2020-12-01 09:41:34 CET
Of course having all printer driver related files in one single directory is not ideal to begin with, especially when multiple printer drivers ship with different versions of the same file (e.g. "unires.dll"). It's an NT4 legacy contruct and probably just assumed that always keeping the newest version of such a shared file doesn't break anything. But in a Samba environment, due to this bug, it's possible that a client gets an older version of a file, that will crash the driver. This specifically happened in our environment with the newest Lexmark Universal driver, because there were 10 years older versions of DLL files from the HP Universal Driver present as well.

But I guess that's why Microsoft decided to introduce package-aware drivers and the MS-PAR protocol back in Windows Vista, which I really want to see supported by Samba as soon as possible. That is being worked on, just not with high priority, it seems: https://bugzilla.redhat.com/show_bug.cgi?id=1369515
Comment 20 Arvid Requate univentionstaff 2020-12-01 18:05:06 CET
As Christian wrote:

> See above. There is only a single file as the filesystem does not keep multiple ones.

We need to find out why Samba decides to store both files instead of just keeping one,
regardless what the manpage claims or promises.
Comment 21 Christian Völker univentionstaff 2020-12-02 09:16:52 CET
(In reply to Arvid Requate from comment #20)

> We need to find out why Samba decides to store both files instead of just
> keeping one, regardless what the manpage claims or promises.

Up to you. I guess it just uses the default Linux file systems calls. And they differ between upper and lower case.
Comment 22 Felix Botner univentionstaff 2023-02-24 13:36:45 CET
* fixed by overwriting existing driver files regardless of case
  Package: samba
  Version: 2:4.16.8-1A~5.0.0.202302241311
  Branch: ucs_5.0-0
  Scope: errata5.0-3

* samba.yaml

* added test 
  Package: ucs-test
  Version: 10.0.10-13A~5.0.0.202302241333
  Branch: ucs_5.0-0
  Scope: errata5.0-3
Comment 23 Arvid Requate univentionstaff 2023-02-27 23:38:33 CET
* Functional test: OK

[2023/02/27 22:54:48,  5, pid=2030, effective(0, 5000), real(0, 0)] ../../source3/printing/nt_printing.c:499(handle_pe_file)
  handle_pe_file: PE file [x64/3/unidrv.dll] Version = 00000003:3fab018c (0.3.16299.396)

[2023/02/27 22:54:48,  5, pid=2030, effective(0, 5000), real(0, 0)] ../../source3/printing/nt_printing.c:499(handle_pe_file)
  handle_pe_file: PE file [x64/{E5138BBB-E51F-411A-B690-A2C89F1DE4AD}/unidrv.dll] Version = 00000003:3fab0192 (0.3.16299.402)

[2023/02/27 22:54:48, 10, pid=2030, effective(0, 5000), real(0, 0)] ../../source3/smbd/filename.c:1370(unix_convert)
  unix_convert: Conversion finished [x64/3/unidrv.dll] -> [x64/3/UNIDRV.DLL]
[2023/02/27 22:54:48, 10, pid=2030, effective(0, 5000), real(0, 0)] ../../source3/printing/nt_printing.c:1458(move_driver_file_to_download_area)
  move_driver_file_to_download_area: copying 'x64/{E5138BBB-E51F-411A-B690-A2C89F1DE4AD}/unidrv.dll' to 'x64/3/UNIDRV.DLL'


* Test case OK: ucs-test/53_samba-common/39_upload_printer_driver_case
* 52a228554b | wording adjustment in advisory