-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OSError: Could not find KfW installation #290
Comments
Any hope for getting this issue fixed? |
The code for the lookup is at https://github.com/pythongssapi/python-gssapi/blob/main/gssapi/_win_config.py, you are more than welcome to try and fix it and submit a PR. It already tries to check |
I have the same problem, it's strange, my kafka client doesn't have any authentication enabled, using kafka-python keeps reporting errors, OSError: Could not find KfW installation,, looked at it is gssapi throwing, I don't understand, why is this, can someone fix it |
This is very unreasonable. I did not use Kerberos related protocols, but just imported gssapi, and an error was thrown during the initialization process.Hope someone can fix it |
If kinit is not found so what? Let it fail on gssapi.Credentials(). Why raise the OS Error on line 85 of _win_config.py? python-gssapi/gssapi/_win_config.py Line 85 in 5c316ec
Otherwise your users have to go through hoops like this:
|
Ultimately the library needs to be able to load
Each step attempts to find
This is a critical error, nothing will work. Why would you be importing |
... Including the program that imports it and does not in fact make a call into kerberos. If I import requests and don't have a working network connection, requests doesn't crash upon import. It only errors on requests.get(). Likewise if I import gssapi, I would expect gssapi should error on gssapi.Credentials() -- that is when it's trying to actually interface with Kerberos. Many things use late binding in python via the following pattern. class LazyLoadingClass:
_instance = None
def __init__(self, *args, **kwargs):
if self._instance is None:
self._instance = construct_instance(*args, **kwargs) This is similar to the code I wrote: class LazyGssBinding:
"""gss has to early bind.. for reasons"""
_gssapi = None
@classmethod
def import_lazy(cls):
if cls._gssapi is None:
try:
import gssapi
except:
raise SomeException("gssapi error")
cls._gssapi = gssapi
return cls._gssapi The real down side with using this here is that I can't mock out your classes, or subclass them, or whatever, because the import must work in order for the python mock to introspect your classes. At least now I can mock out LazyGssBinding. Here's a few reasons you might not have kfw installed:
|
Unfortunately what you want just isn't possible with how this module is structured. Things like the Line 17 in 5c316ec
This python-gssapi/gssapi/raw/creds.pyx Lines 58 to 77 in 5c316ec
When compiled we can see that this
The Ordinal are references inside that dll that is required, these will be things like the C methods being called in this file. As I don't actually have MIT KfW installed on that test host I cannot see what those ordinals match up to but it shows the compiled This also applies to the other types that are being exposed at the base level, fundamentally for Python to import them the Even if you were to comment out the checks in
Ultimately what you want can't really be done, to import this library you must have the dependencies met, it is critical for the operation for this library and it cannot be lazily loaded. The lazy loading must be in the callers code to optionally import gssapi and handle accordingly. I currently use this pattern in a library that might be used where Then when someone tries to instanciate one of the classes that use gssapi it checks to see whether it was imported or not and fails |
You could do it with a series of proxies. No?
…On Wed, Jan 24, 2024, 4:02 PM Jordan Borean ***@***.***> wrote:
Unfortunately what you want just isn't possible with how this module is
structured. Things like the gssapi.Credential or gssapi.SecurityContext
imports the base structures from gssapi.raw.* which are derived from a
compiled Python binary. These binaries have references to symbols that are
provided by the gssapi*.dll which is why during import the code tries to
be helpful and checks a few places where those symbols could be. For
example using your gssapi.Credentials() example we can see that it is
based on the rcreds.Creds object
https://github.com/pythongssapi/python-gssapi/blob/5c316ec3c8f99d3df6d689fadff4a391658e026a/gssapi/creds.py#L17
This rcreds.Creds base type is defined in the Cython pyx and pyd files
under gssapi.raw.creds
https://github.com/pythongssapi/python-gssapi/blob/5c316ec3c8f99d3df6d689fadff4a391658e026a/gssapi/raw/creds.pyx#L58-L77
When compiled we can see that this .pyd has a dependency on gssapi64.dll
$ dumpbin C:\temp\gssapi-venv\Lib\site-packages\gssapi\raw\creds.cp312-win_amd64.pyd /IMPORTS
Microsoft (R) COFF/PE Dumper Version 14.38.33133.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file C:\temp\gssapi-venv\Lib\site-packages\gssapi\raw\creds.cp312-win_amd64.pyd
File Type: DLL
Section contains the following imports:
gssapi64.dll
18000E108 Import Address Table
180010F60 Import Name Table
0 time date stamp
0 Index of first forwarder reference
Ordinal 54
Ordinal 29
Ordinal 30
Ordinal 10
Ordinal 57
Ordinal 11
...
The Ordinal are references inside that dll that is required, these will be
things like the C methods being called in this file
<https://github.com/pythongssapi/python-gssapi/blob/5c316ec3c8f99d3df6d689fadff4a391658e026a/gssapi/raw/creds.pyx#L17-L55>.
As I don't actually have MIT KfW installed on that test how I cannot see
what those ordinals match up to but it shows the compiled .pyd requires
them to load the dll.
This also applies to the other types that are being exposed at the base
level, fundamentally for Python to import them the gssapi*.dll must be
present and found by the Windows dll loader logic.
Ultimately what you want can't really be done, to import this library you
must have the dependencies met, it is critical for the operation for this
library and it cannot be lazily loaded. The lazy loading must be in the
callers code to optionally import gssapi and handle accordingly.
—
Reply to this email directly, view it on GitHub
<#290 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAL67IZXSIV3B4LCN3G3OJTYQGHHNAVCNFSM5VSA5DLKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOJQHEYDMMJQGQ2Q>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
That’s up to the caller in my opinion here. They can proxy it as the C library is a mandatory dependency of this package. It’ll be the same problem as any other Python library where the dependency isn’t met, you’ll find they will most likely also error if the dependency is missing. The trouble with this dependency is that it is a C one and we cannot host it on PyPI. Ultimately I’m not going to do the work, things work today they just might not work the way you wish them to. |
What went wrong?
Loading gssapi on windows throws "OSError: Could not find KfW installation" when there are multiple kinit.exe in the PATH. Specifically, in the case of having the Java JDK being installed it satisfies the "kinit.exe" under that path and ignores the subsequent one pointing to the kerberos installation.
How do we reproduce?
Making Kerberos the first directory in the path is obviously a workaround, but ideally the logic for finding the kerberos installation could be enhanced a bit to use "which --all" and validate the correct path.
The text was updated successfully, but these errors were encountered: