pamauth.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /* plugin for 3proxy with PAM auth only for *NIX (linux,*bsd)
  2. Kirill Lopuchov <lopuchov@mail.ru>
  3. Compile with: gcc -shared -o pamauth.so pamauth.c -lpam -DNOODBC
  4. */
  5. #include "../../structures.h"
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <security/pam_appl.h>
  11. static int already_loaded = 0;
  12. static struct auth pamauth;
  13. #ifdef USERCASE
  14. static int usercaselow = 0;
  15. #endif
  16. static unsigned char *service=NULL;
  17. static struct pluginlink * pl;
  18. static char *password = NULL;
  19. static int password_conversation ( int num_msg, const struct pam_message **msg,
  20. struct pam_response **resp,
  21. void *appdata_ptr)
  22. {
  23. if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF)
  24. {
  25. return PAM_CONV_ERR;
  26. }
  27. if (!appdata_ptr) appdata_ptr = password;
  28. if (!appdata_ptr)
  29. {
  30. return PAM_CONV_ERR;
  31. }
  32. *resp = calloc (num_msg, sizeof (struct pam_response));
  33. if (!*resp)
  34. {
  35. return PAM_CONV_ERR;
  36. }
  37. (*resp)[0].resp = strdup ((char *) appdata_ptr);
  38. (*resp)[0].resp_retcode = 0;
  39. return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR);
  40. }
  41. #ifdef USERCASE
  42. static void lower (char *string)
  43. {
  44. int length, i;
  45. length = strlen(string);
  46. for (i=0; i<length; i++)
  47. {
  48. string[i] = tolower(string[i]);
  49. }
  50. }
  51. #endif
  52. /* --------------------------------------------------------------------------*/
  53. static int pamfunc(struct clientparam *param)
  54. {
  55. pam_handle_t *pamh = NULL;
  56. int retval;
  57. int rc=0;
  58. struct pam_conv conv = {
  59. &password_conversation,
  60. NULL };
  61. /* test proxy user auth ------------------------*/
  62. if(!param->username || !param->password) return 4;
  63. /*if(strlen(param->password)==0) return 4;*/
  64. #ifdef USERCASE
  65. if (usercaselow > 0)
  66. { lower(param->username); }
  67. #endif
  68. /*start process auth */
  69. conv.appdata_ptr = (char *) param->password;
  70. if (!pamh)
  71. {
  72. retval = pam_start ((char *)service, "3proxy@" , &conv, &pamh);
  73. }
  74. if (retval == PAM_SUCCESS)
  75. retval = pam_set_item (pamh, PAM_USER, param->username);
  76. /*fprintf(stderr,"pam_set_item1 rc=%d\n",retval);*/
  77. if (retval == PAM_SUCCESS)
  78. retval = pam_set_item (pamh, PAM_CONV, &conv);
  79. /*fprintf(stderr,"pam_set_item2 rc=%d\n",retval); */
  80. if (retval == PAM_SUCCESS)
  81. retval = pam_authenticate (pamh, 0);
  82. /*fprintf(stderr,"pam_authenticate rc=%d\n",retval);*/
  83. if (retval == PAM_SUCCESS) { /*auth OK*/ rc=0; }
  84. else { /*auth ERR*/ rc=5; }
  85. if (pamh)
  86. retval = pam_end (pamh, retval);
  87. if (retval != PAM_SUCCESS)
  88. { pamh = NULL; }
  89. return rc;
  90. }
  91. /*------------------------------- MAIN --------------------------------------
  92. start plugin init */
  93. int start(struct pluginlink * pluginlink, int argc, unsigned char** argv)
  94. {
  95. if(argc < 2) return 1;
  96. pl = pluginlink;
  97. if(service) pl->myfree(service);
  98. service=pl->mystrdup(argv[1]);
  99. if (already_loaded) { return (0); }
  100. already_loaded = 1;
  101. pamauth.authenticate = pamfunc;
  102. pamauth.authorize = pluginlink->checkACL;
  103. pamauth.desc = "pam";
  104. pamauth.next = pluginlink->authfuncs->next;
  105. pluginlink->authfuncs->next = &pamauth;
  106. return 0;
  107. }