PAM 模块错误(传递‘snprintf’的参数 1 丢弃‘const’)

PAM module error (passing argument 1 of ‘snprintf’ discards ‘const’)

我有我的 PAM 模块:

我尝试编译它,使用字符串:

gcc -fPIC -DPIC -shared -rdynamic -o pam_test.so pam_test.c

但是我有错误:

pam_test.c: In function ‘pam_sm_authenticate’:
pam_test.c:74:9: warning: passing argument 1 of ‘snprintf’ discards ‘const’ qualifier from pointer target type [enabled by default]
         snprintf(msg[0].msg,60,"Second Password:%d:%d:%d:%d:",x1,x2,x3,x4);
         ^
In file included from pam_test.c:10:0:
/usr/include/stdio.h:386:12: note: expected ‘char * __restrict__’ but argument is of type ‘const char *’
 extern int snprintf (char *__restrict __s, size_t __maxlen,

模块代码:

#include <security/pam_modules.h>
#include <stdarg.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>


#define PAM_SM_AUTH
#define MAX_V 30


PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char **argv)
{
        unsigned int ctrl;
        int retval;
        const char *name, *p;
        char *right;
        int x1,x2,x3,x4,y;

        time_t mytime;
        struct tm *mytm;

        mytime=time(0);
        mytm=localtime(&mytime);


        srandom(mytime);
        x1=random()%MAX_V;
        x2=random()%MAX_V;
        x3=random()%MAX_V;
        x4=random()%MAX_V;

        retval = pam_get_user(pamh, &name, "login: ");

        {
            struct pam_conv *conv;
            struct pam_message *pmsg[3],msg[3];
            struct pam_response *response;


        retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ;

        pmsg[0] = &msg[0];
        msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
        msg[0].msg=malloc(100);
        snprintf(msg[0].msg,60,"Second Password:%d:%d:%d:%d:",x1,x2,x3,x4);

        retval = conv->conv(1, ( const struct pam_message ** ) pmsg
                            , &response, conv->appdata_ptr);
        y=2*x1*mytm->tm_mday+x3*mytm->tm_hour;
        right=malloc(100);
        snprintf(right,20,"%d",y);

        if (!(strcmp(right,response->resp))){
        return PAM_SUCCESS;
        }else{
        return PAM_AUTH_ERR;
        }
      }

        return PAM_SUCCESS;

}

PAM_EXTERN int pam_sm_setcred(pam_handle_t * pamh, int flags
                              ,int argc, const char **argv)
{
        unsigned int ctrl;
        int retval;
        retval = PAM_SUCCESS;
}

#ifdef PAM_STATIC
struct pam_module _pam_unix_auth_modstruct = {
    "pam_test",
    pam_sm_authenticate,
    pam_sm_setcred,
    NULL,
    NULL,
    NULL,
    NULL,
};
#endif

这里的问题是,在struct pam_message中,msg字段声明为const char*;也就是说,指向不可变字符串的指针。所以你不应该用 snprintf.

覆盖它

一个简单的解决方法是在将指向它的指针插入 msg 之前写入字符串:

char *s = malloc(100);
snprintf(s, 100, "Second Password:%d:%d:%d:%d:",x1,x2,x3,x4);
msg[0].msg = s;

注意:您应该检查 snprintf 的 return 值。如果值 returned 大于 100,则字符串被截断。