ImportError e PyExc_SystemError ao incorporar o Script Python no C para módulos PAM (arquivos .so)

Estou tentando escrever um módulo de demonstração do PAM em C, que usa o conceito de incorporação de Python em C para executar um script escrito em python (2.7), dentro da função pam_sm_authenticate (), escrita no arquivo C (pam_auth.c).

Este é o script python: test.py

import math
import numpy
def test_func():
   a = "test"
   return a 

O caminho para test.py é /usr/lib/Python2.7/, para que eu possa importá-lo facilmente.

Este é o arquivo C:

#define PAM_SM_AUTH
#define PAM_SM_ACCOUNT
#define PAM_SM_SESSION

#include <security/pam_modules.h>
#include <security/_pam_macros.h>
#include <security/pam_appl.h>
#include<python2.7/Python.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define NOBODY "nobody"


/*PAM Stuffs*/

PAM_EXTERN int pam_sm_authenticate(
  pam_handle_t* pamh, int flags, int argc, const char** argv)
{
    const char *user;
    int retval;
    user = NULL;
    retval = pam_get_user(pamh, &user, NULL);
    if(retval != PAM_SUCCESS)
    {
        fprintf(stderr, "%s", pam_strerror(pamh, retval));
//      return (retval);
    }
    fprintf(stdout, "retval= %d user=%s\n", retval,user);
    if (user == NULL || *user =='\0')
        pam_set_item(pamh, PAM_USER, (const char*)NOBODY);

    /* Python Wrapper */    

    // Set PYTHONPATH TO working directory
    //int res = setenv("PYTHONPATH",".",1);
    //fprintf(stdout, "%d", res);

    PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *pResult;

    // Initialize the Python Interpreter
    Py_Initialize();

    // Build the name object
    pName = PyString_FromString((char*)"test");

    // Load the module object
    pModule = PyImport_Import(pName);

    // pDict is a borrowed reference 

    PyErr_Print();
    pDict = PyModule_GetDict(pModule);

    // pFunc is also a borrowed reference 
    pFunc = PyDict_GetItemString(pDict, (char*)"test_func");

    if (PyCallable_Check(pFunc))
    {
        pValue=NULL;
        PyErr_Print();
        pResult=PyObject_CallObject(pFunc,pValue);
        PyErr_Print();
    }else 
    {
           PyErr_Print();
    }
    printf("Result is %s\n",PyString_AsString(pResult));

    // Clean up
    Py_DECREF(pModule);
    Py_DECREF(pName);/* */

    // Finish the Python Interpreter
    Py_Finalize();      

    return PAM_SUCCESS;
}

PAM_EXTERN int pam_sm_setcred(
  pam_handle_t* pamh, int flags, int argc, const char** argv)
{
    return PAM_SUCCESS;
}

PAM_EXTERN int pam_sm_acct_mgmt(
  pam_handle_t* pamh, int flags, int argc, const char** argv)
{
    return PAM_SUCCESS;
}

PAM_EXTERN int pam_sm_open_session(
  pam_handle_t* pamh, int flags, int argc, const char** argv)
{
    return PAM_SUCCESS;
}

PAM_EXTERN int pam_sm_close_session(
  pam_handle_t* pamh, int flags, int argc, const char** argv)
{
    return PAM_SUCCESS;
}

PAM_EXTERN int pam_sm_chauthtok(
  pam_handle_t* pamh, int flags, int argc, const char** argv)
{
    return PAM_SUCCESS;
}

O arquivo C é apenas uma modificação do pam_permit.c. O arquivo C é compilado usando o gcc (gcc -shared -o pam_auth.so -fPIC pam_auth.c -I / usr / include / python2.7 -lpython2.7) para obter um arquivo .so (pam_auth.so) e é colocado dentro da pasta / lib / security /

Alterei a configuração do PAM do arquivo 'sudo' em /etc/pam.d da seguinte maneira:

#%PAM-1.0

auth       required   pam_env.so readenv=1 user_readenv=0
auth       required   pam_env.so readenv=1 envfile=/etc/default/locale user_readenv=0
#@include common-auth #this line is commented to make it use my pam module
auth       required   pam_auth.so
@include common-account
@include common-session-noninteractive

A linha "auth required pam_auth.so" força o sistema a usar meu módulo para autenticação toda vez que eu uso o comando "sudo". (para ex-sudo nautilus)

Agora o problema é: Esta linha no arquivo C "pModule = PyImport_Import (pName);" fornece um erro de importação, impresso por PyErr_Print () da seguinte maneira:

stitches@Andromida:~$ sudo nautilus
retval= 0 user=stitches
Traceback (most recent call last):
  File "/usr/lib/python2.7/subho_auth.py", line 8, in <module>
    import numpy
  File "/usr/lib/python2.7/dist-packages/numpy/__init__.py", line 153, in <module>
    from . import add_newdocs
  File "/usr/lib/python2.7/dist-packages/numpy/add_newdocs.py", line 13, in <module>
    from numpy.lib import add_newdoc
  File "/usr/lib/python2.7/dist-packages/numpy/lib/__init__.py", line 8, in <module>
    from .type_check import *
  File "/usr/lib/python2.7/dist-packages/numpy/lib/type_check.py", line 11, in <module>
    import numpy.core.numeric as _nx
  File "/usr/lib/python2.7/dist-packages/numpy/core/__init__.py", line 6, in <module>
    from . import multiarray
ImportError: /usr/lib/python2.7/dist-packages/numpy/core/multiarray.so: undefined symbol: PyExc_SystemError
Segmentation fault (core dumped)

Pelo que entendi, ele falha ao importar a biblioteca numpy conforme especificado no arquivo test.py. Como resolver este problema de ImportError & PyExc_SystemError?

O script python funciona como um encanto se eu executar da seguinte maneira:

#include <Python.h>
#include <stdlib.h>
#include <string.h>
int main()
{   
    // Set PYTHONPATH TO working directory
    //int res = setenv("PYTHONPATH",".",1);
    //fprintf(stdout, "%d", res);

    PyObject *pName, *pModule, *pDict, *pFunc, *pValue, *pResult;

    // Initialize the Python Interpreter
    Py_Initialize();

    // Build the name object
    pName = PyString_FromString((char*)"test");

    // Load the module object
    pModule = PyImport_Import(pName);

    // pDict is a borrowed reference 

    PyErr_Print();
    pDict = PyModule_GetDict(pModule);

    // pFunc is also a borrowed reference 
    pFunc = PyDict_GetItemString(pDict, (char*)"test_func");

    if (PyCallable_Check(pFunc))
    {
        pValue=NULL;
        PyErr_Print();
        pResult=PyObject_CallObject(pFunc,pValue);
        PyErr_Print();
    }else 
    {
           PyErr_Print();
    }
    printf("Result is %s\n",PyString_AsString(pResult));

    // Clean up
    Py_DECREF(pModule);
    Py_DECREF(pName);/* */

    // Finish the Python Interpreter
    Py_Finalize();      

    return 0;
}

Se ele funciona com exemplos gerais de incorporação de python, por que não está funcionando em exemplos de incorporação baseados em PAM (onde os arquivos .so são usados)?

PS: Estou importando numpy por um motivo específico. Não pergunte por que não usei em nenhum lugar no script python, pois este é apenas um script de demonstração do que estou tentando alcançar. Além disso, a matemática da importação não gera nenhum erro de importação. Também recebo um erro de importação do SciPY.

PPS: Os pacotes Numpy e Scipy funcionam perfeitamente em scripts python e são instalados em /usr/lib/python2.7/dist-packages/. Estou usando o ubuntu 14.04.

Por favor ajude!!!!

questionAnswers(1)

yourAnswerToTheQuestion