如何使用PAM静态认证账号。

类别:软件工程 点击:0 评论:0 推荐:

最近在网上找了不少关于pam的资料,虽然很多,但是都只是动态交互进行验证。因为工作需要,需要进行静态的验证,于是写了如下代码。以下在Mac os X上验证通过。如果把#include <pam/pam_appl.h>,#include <pam/pam_misc.h>,改成#include <security/pam_appl.h>,#include <security/pam_misc.h>应该直接可以在Linux,和Unix等支持Posix标准的环境下运行。

#include <sys/param.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>

#include <err.h>
#include <errno.h>
#include <grp.h>
#include <paths.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>

#include <pam/pam_appl.h>
#include <pam/pam_misc.h>
//#include <pam/pam_misc.h>

int su_conv(int num_msg, const struct pam_message **msgm,    //回调函数,非常重要!!!!
       struct pam_response **response,void *appdata_ptr);


//static struct pam_conv conv = {misc_conv,NULL};

 

int main (int argc, const char * argv[])
{
    // insert code here...
    pam_handle_t *pamh; 
 const char* mytty,*p; 
 char *password = "718412";
    char *user     = "root";
 struct pam_conv conv = {su_conv, password}; 
//其中password就是直接传递给su_conv回调函数void *appdata_ptr  指针
 
 int retval = 100;  
 
 printf("uid: %d\n", getuid());
 
 retval = pam_start("su","root",&conv,&pamh);
 if(retval = PAM_SUCCESS)
 //pam_get_item(pamh,PAM_USER,(const void **)&p);
 pam_set_item(pamh,PAM_CONV, getlogin());

 mytty = ttyname(STDERR_FILENO);
 if (!mytty)
  mytty = "tty";
 pam_set_item(pamh,PAM_TTY, mytty);

 retval = pam_authenticate(pamh,PAM_SILENT);
 
 printf("return code: %d\n", retval);
 
 if(retval != PAM_SUCCESS)
 { 
      printf("invalid password\n");
      return -1; 
 }    
 
 
 retval = pam_end(pamh,PAM_SUCCESS);
 
 printf("uid: %d\n", getuid());
 setuid(0);
 printf("uid: %d\n", getuid());
       
 printf("the retval is now %d",retval);
 
    return 0;
}


int su_conv(int num_msg, const struct pam_message **msgm,
       struct pam_response **response, void *appdata_ptr)
{

   char *rec;
   struct pam_message  *m = (struct pam_message *)*msgm;
   struct pam_response *r;
  
   while(num_msg--)
   {
      switch(m->msg_style)
   {
       case PAM_PROMPT_ECHO_OFF:
      //   r->resp = strdup(getpass(m->msg));
      r               = (struct pam_response *)malloc(sizeof(struct pam_response));
      r->resp         = (char *)malloc(100);
      r->resp_retcode = 0;
    
      strcpy(r->resp, appdata_ptr);
      *response = r;
      break;
    case PAM_PROMPT_ECHO_ON:
         //r->resp = (char *)getpass(m->msg);
      //fprintf(stdout,"%s",m->msg);
      r->resp = malloc(PAM_MAX_RESP_SIZE);
      fgets(r->resp,PAM_MAX_RESP_SIZE,stdin);
      //gets(rec);
    
      break;
    case PAM_ERROR_MSG:
         (void)fputs(m->msg,stdout);
    
      break;
    case PAM_TEXT_INFO:
         fprintf(stdout,"%s\n",m->msg);
    
      break;
    default:
   
    break;
   }
   }
   return PAM_SUCCESS;
}

本文地址:http://com.8s8s.com/it/it32645.htm