Thursday, July 30, 2020

Variable expansion and searching for packages that contain a file using yum/dnf

I know some articles in this blog are rather clever, but this one is here to remind me (learn from my mistakes!) that understanding how a command thinks is important. I was having some issues with cryptsetup and was told (by Matthew Heon: let me make sure to recognize him for throwing a searchlight at my problem. Thanks!) I the file /usr/share/cracklib/pw_dict.pwd.gz was missing. Fine, this is a CentOS 8 docker container. I can use yum (until they remove it completely) or its replacement, dnf, to look for it. I will be using yum in this discussion knowing that they are interchangeable within the limits of this article.

If the file in in the directory /usr/share/cracklib, chances are it belongs to the cracklib package, so let's begin by seeing what we have matching that:

[root@moe /]# yum search cracklib
Failed to set locale, defaulting to C.UTF-8
========================== Name Exactly Matched: cracklib ==========================
cracklib.x86_64 : A password-checking library
cracklib.i686 : A password-checking library
========================= Name & Summary Matched: cracklib =========================
cracklib-dicts.x86_64 : The standard CrackLib dictionaries
[root@moe /]#

Oh, there are more than one, so we need to be more specific. That is a great job for the whatprovides option; it allows us to find all the packages that contain a given file.

[root@moe /]# yum whatprovides pw_dict.pwd.gz
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 0:00:27 ago on Tue Jul 28 20:32:27 2020.
Error: No Matches found
[root@moe /]#
I did learn that sometimes looking for a package by just providing the filename of a file that belongs to it does not work well, but if you make it look like you are giving a path will work. And this path can begin with a * so it can expand the path to any path in the system. So, let's try that and hope for the best:
[root@moe /]# yum whatprovides */pw_dict.pwd.gz
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 17:43:12 ago on Tue Jul 28 20:32:27 2020.
Error: No Matches found
[root@moe /]#
What is going on? Well, let's up on a limb: of the three cracklib-related files, cracklib-dicts seems to be the one with the most potential because the file we want is a dictionary. And then see what lurks in /usr/share/cracklib/:
[root@moe /]# yum install cracklib-dicts
[...]
[root@moe /]# ls /usr/share/cracklib/
cracklib-small.hwm  cracklib-small.pwi  pw_dict.hwm  pw_dict.pwi
cracklib-small.pwd  cracklib.magic      pw_dict.pwd
[root@moe /]#

A candle lights over my heard, indicating I was enlightened: it is called pw_dict.pwd, not pw_dict.pwd.gz! I did not account for it to be in a different format (gzipped in this case)! Well duh!

With that in mind, we should see if we could have saved some aggravation. We expanded the search path by entering */pw_dict.pwd.gz before; would that work for the filename? Let's find out:

[root@moe /]# yum whatprovides */pw_dict.pwd
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 17:43:45 ago on Tue Jul 28 20:32:27 2020.
cracklib-dicts-2.9.6-15.el8.x86_64 : The standard CrackLib dictionaries
Repo        : @System
Matched from:
Filename    : /usr/share/cracklib/pw_dict.pwd

cracklib-dicts-2.9.6-15.el8.x86_64 : The standard CrackLib dictionaries
Repo        : BaseOS
Matched from:
Filename    : /usr/share/cracklib/pw_dict.pwd

[root@moe /]# yum whatprovides pw_dict.*
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 17:46:32 ago on Tue Jul 28 20:32:27 2020.
Error: No Matches found
[root@moe /]#
[root@moe /]# yum whatprovides */pw_dict.*
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 17:44:42 ago on Tue Jul 28 20:32:27 2020.
cracklib-dicts-2.9.6-15.el8.x86_64 : The standard CrackLib dictionaries
Repo        : @System
Matched from:
Filename    : /usr/share/cracklib/pw_dict.hwm
Filename    : /usr/share/cracklib/pw_dict.pwd
Filename    : /usr/share/cracklib/pw_dict.pwi

cracklib-dicts-2.9.6-15.el8.x86_64 : The standard CrackLib dictionaries
Repo        : BaseOS
Matched from:
Filename    : /usr/share/cracklib/pw_dict.hwm
Filename    : /usr/share/cracklib/pw_dict.pwd
Filename    : /usr/share/cracklib/pw_dict.pwi

[root@moe /]# yum whatprovides */*_dict.pwd
Failed to set locale, defaulting to C.UTF-8
cracklib-dicts-2.9.6-15.el8.x86_64 : The standard CrackLib dictionaries
Repo        : BaseOS
Matched from:
Filename    : /usr/lib64/cracklib_dict.pwd
Filename    : /usr/share/cracklib/pw_dict.pwd

[root@moe /]#

Interesting that we really do not need to tack a * to the end of the search pattern. So, what we learned from this article is that if searching for a package a given file belongs to does not work, we can broaden the search by replacing part of the filename in question with a *. And that we do not need that if the bit of the filename we are taking is at the end.

Learning something useful in this blog: who would've thought?