0

Code:

#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <stdio.h>

static struct pam_conv conv = {
    misc_conv,
    NULL
};

int main(int argc, char *argv[])
{
    pam_handle_t *pamh=NULL;
    int retval;
    const char *user="nobody";

    if(argc == 2) {
        user = argv[1];
    }

    if(argc > 2) {
        fprintf(stderr, "Usage: check_user [username]\n");
        exit(1);
    }

    retval = pam_start("check_user", user, &conv, &pamh);

    if (retval == PAM_SUCCESS)
        retval = pam_authenticate(pamh, 0);    /* is user really user? */

    if (retval == PAM_SUCCESS)
        retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */

    /* This is where we have been authorized or not. */

    if (retval == PAM_SUCCESS) {
        fprintf(stdout, "Authenticated\n");
    } else {
        fprintf(stdout, "Not Authenticated\n");
    }

    if (pam_end(pamh,retval) != PAM_SUCCESS) {     /* close Linux-PAM */
        pamh = NULL;
        fprintf(stderr, "check_user: failed to release authenticator\n");
        exit(1);
    }

    return ( retval == PAM_SUCCESS ? 0:1 );       /* indicate success */
}

Two libraries I added:

  • libpam0g-dev
  • libpam0g

In /usr/include/security/ I have:

_pam_compat.h
_pam_macros.h
_pam_types.h
pam_appl.h
pam_client.h
pam_ext.h
pam_filter.h
pam_misc.h
pam_modules.h
pam_modutil.h

I compile with: gcc -o check_user -lpam check_user.c

And I get:

/usr/bin/ld: /tmp/cc9ldItB.o:(.data.rel+0x0): undefined reference to `misc_conv'
collect2: error: ld returned 1 exit status

So why do I get undefined reference to "misc_conv' when the libpam0g-dev was added?

alk
  • 69,737
  • 10
  • 105
  • 255
jnbdz
  • 4,863
  • 9
  • 51
  • 93
  • have you checked if `misc_conv` is exported by your `pam` library ? ( `nm -D` command line or other variant) – Landstalker Mar 07 '20 at 03:08
  • Do you have a 3rd pam lib available? The [manpage](https://linux.die.net/man/3/misc_conv) states: "The misc_conv function is part of the libpam_misc Library and not defined in any standard." – Gerhardh Mar 07 '20 at 12:12
  • The order of arguments matters when calling the compiler/linker. Try: `gcc -o check_user check_user.c -lpam` The rules of thumb is: "*Always specify libraries last!*" – alk Mar 07 '20 at 12:39
  • @alk I get the same thing. – jnbdz Mar 07 '20 at 13:16
  • @Landstalker when I run `nm -D` I get `nm: 'a.out': No such file` – jnbdz Mar 07 '20 at 13:17
  • @Gerhardh it is in: pam_misc.h file. – jnbdz Mar 07 '20 at 13:18
  • 1
    "*The misc_conv function is part of the libpam_misc Library*" So try to append `-lpam_misc` to the compile/link command. – alk Mar 07 '20 at 13:20
  • A .h file is not a library. – Gerhardh Mar 07 '20 at 13:27
  • @jnbdz `nm -D` must be executed on your library (your .so) and not on your binary exec program. Please check this : https://stackoverflow.com/questions/4514745/how-do-i-view-the-list-of-functions-a-linux-shared-library-is-exporting. What is `misc_conv` ? a struct, a function, .. ? if it is a function, it is declared in `pam_misc.h` and implemented in library (.so). you have therefor a linking problem – Landstalker Mar 07 '20 at 13:37
  • @jnbdz you miss an argument in `nm -D`. Add library path: `nm -D ..\path_misc\pam_misc.so` – Landstalker Mar 07 '20 at 13:47
  • @Landstalker I just have the `pam_misc.h` no `pam_misc.so`. – jnbdz Mar 07 '20 at 14:12
  • @jnbdz in this case, you cannot link. if your `misc_conv` is a function. because your compiler cant find it implementation. – Landstalker Mar 07 '20 at 14:13
  • @Landstalker I have it now `/usr/lib/x86_64-linux-gnu/libpam_misc.so` but I still get the same error as before. – jnbdz Mar 07 '20 at 22:18
  • @jnbdz please execute this : `nm -D /usr/lib/x86_64-linux-gnu/libpam_misc.so` and see if `misc_conv ` is exported – Landstalker Mar 07 '20 at 22:20

1 Answers1

1

You should add the -lpam_misc option to the command:

gcc -o check_user -lpam -lpam_misc check_user.c
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83