0

I am attempting to make a simple python library that calls LogonUser to see if the plaintext password provided matches the password of the username provided, but when I compile, it gives me this error

passcheck.obj : error LNK2001: unresolved external symbol __imp_LogonUserA

full log:

running build
running build_ext
building 'passcheck' extension
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\bin\HostX86\x64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IC:\Users\memol\AppData\Local\Programs\Python\Python38\include -IC:\Users\memol\AppData\Local\Programs\Python\Python38\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" /Tcpasscheck.c /Fobuild\temp.win-amd64-3.8\Release\passcheck.obj
passcheck.c
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\bin\HostX86\x64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:C:\Users\memol\AppData\Local\Programs\Python\Python38\libs /LIBPATH:C:\Users\memol\AppData\Local\Programs\Python\Python38\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\ATLMFC\lib\x64" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\lib\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.19041.0\um\x64" /EXPORT:PyInit_passcheck build\temp.win-amd64-3.8\Release\passcheck.obj /OUT:build\lib.win-amd64-3.8\passcheck.cp38-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.8\Release\passcheck.cp38-win_amd64.lib
   Creating library build\temp.win-amd64-3.8\Release\passcheck.cp38-win_amd64.lib and object build\temp.win-amd64-3.8\Release\passcheck.cp38-win_amd64.exp
passcheck.obj : error LNK2001: unresolved external symbol __imp_LogonUserA
build\lib.win-amd64-3.8\passcheck.cp38-win_amd64.pyd : fatal error LNK1120: 1 unresolved externals
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.29.30037\\bin\\HostX86\\x64\\link.exe' failed with exit status 1120

After looking at this I have come to the conclusion I need to link the library file "advapi32.lib", However looking at the help I cannot find any way to do the solution provided in that question with command arguments, and attempting to run the command myself works but gives me the error LINK : fatal error LNK1158: cannot run 'rc.exe', and plus I'm not sure how to take what it compiles if that command worked and make it into a python library.

FULL CODE:

#include <Python.h>
#include <windows.h>
#include <winbase.h>

static PyObject* method_passcheck(PyObject* self, PyObject* args) {
    LPCSTR username;
    LPCSTR password;
    LPCSTR star = "*";
    //int bytes_copied = -1;

    /* Parse arguments */
    if (!PyArg_ParseTuple(args, "ss", &username, &password)) {
        return NULL;
    }

    PHANDLE hToken;


    int passwordWorked = LogonUserA(username, star, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, hToken);

    //FILE* fp = fopen(filename, "w");
    //bytes_copied = fputs(str, fp);
    //fclose(fp);

    return PyLong_FromLong(passwordWorked);
}
static PyMethodDef PasscheckMethods[] = {
    {"passcheck", method_passcheck, METH_VARARGS, "Python interface for fputs C library function"},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef passcheck = {
    PyModuleDef_HEAD_INIT,
    "passcheck",
    "Python interface for the fputs C library function",
    -1,
    PasscheckMethods
};

PyMODINIT_FUNC PyInit_passcheck(void) {
    return PyModule_Create(&passcheck);
}

and my setup.py:

from setuptools import setup, Extension

def main():
    setup(name="passcheck",
          version="1.0.0",
          description="Python interface for the Win32 api's RunAs function to test if a string matches a users password.",
          author="no one",
          ext_modules=[Extension("passcheck", ["passcheck.c"])])

if __name__ == "__main__":
    main()
DavidW
  • 29,336
  • 6
  • 55
  • 86
  • Your code doesn't _compile_. Fix the warnings first. (e.g.) `char *username` --> `LPCSTR username` But, more importantly, `LogonUser` wants a `char */LPCSTR` argument and you're giving it a `char **`. IIRC, winX's C compiler is a thin wrapper around it's c++ compiler, so the argument types may matter???. I'm on linux, so I don't have windows devel installed (except for `wine`). Try using the ascii version `LogonUserA` directly. Otherwise, yes, I would agree you need the lib. But, there's a huge number of args to the `cl` lines, so where does that come from? – Craig Estey Jun 25 '22 at 23:30
  • @CraigEstey For some reason my compiler is complaining when I pass a pointer to a function where the argument is a pointer to a string so I'm hoping it wasn't necessary [docs](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-logonusera) but i got every warning fixed, and its still broken. I already tried LogonUserA and it did not work. the cl args are for different library locations i think. – Spider Boy Jun 26 '22 at 00:20
  • You've got a build script, Makefile, config file, etc. That's where all these commands are created from. You may need to add some search paths for the library. First up: Does `advapi32.lib` exist on your system (i.e. is the library installed)? You may have to install the correct package. Under linux, I'd do: `find / -xdev -name advapi32.lib` So, you could try the WinX equivalent. Then, modify the build config files to point to it. If the lib is installed, and is found by the build, but the symbol remains undefined, I'd get a dump of all the symbols in the lib (e.g. `objdump` equiv). – Craig Estey Jun 26 '22 at 02:27
  • @cra The code does compile. If it didn't the linker wouldn't get invoked. And this is a linker error. To fix that error you'll want to link against the import library specified in the [documentat](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-logonusera): Advapi32.lib. In a default installation you'll find it under *"C:\Program Files (x86)\Windows Kits\10\Lib\\um\\"*. Make sure the architecture matches your target architecture. – IInspectable Jun 26 '22 at 11:18
  • That said, rc.exe is the resource compiler that takes resource scripts and compiles them into a binary format to be linked into the final image. If you don't have any resources (such as version strings, bitmaps, dialog templates, etc.) you do not need to run the resource compiler. Still, it's unlikely that you want to call the ANSI version (`LogonUserA`); it'll easily fail for user names/passwords that contain non-ASCII characters. Call `LogonUserW` instead. – IInspectable Jun 26 '22 at 11:22

1 Answers1

0

After a while I figured out a workaround, you can run py build.py install wait until linker runs and copy the command for linker, then add the file with LogonUserA At the end of the command in a string. After this you can run py build.py install again and it will take what you linked yourself and make it into a working library.