/* plugin for 3proxy with PAM auth only for *NIX (linux,*bsd) Kirill Lopuchov Compile with: gcc -shared -o pamauth.so pamauth.c -lpam -DNOODBC */ #include "../../structures.h" #include #include #include #include #include pthread_mutex_t pam_mutex; static int already_loaded = 0; static struct auth pamauth; #ifdef USERCASE static int usercaselow = 0; #endif static unsigned char *service=NULL; static struct pluginlink * pl; static char *password = NULL; static int password_conversation ( int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF) { return PAM_CONV_ERR; } if (!appdata_ptr) appdata_ptr = password; if (!appdata_ptr) { return PAM_CONV_ERR; } *resp = calloc (num_msg, sizeof (struct pam_response)); if (!*resp) { return PAM_CONV_ERR; } (*resp)[0].resp = strdup ((char *) appdata_ptr); (*resp)[0].resp_retcode = 0; return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR); } #ifdef USERCASE static void lower (char *string) { int length, i; length = strlen(string); for (i=0; iusername || !param->password) return 4; /*if(strlen(param->password)==0) return 4;*/ #ifdef USERCASE if (usercaselow > 0) { lower(param->username); } #endif /*start process auth */ conv.appdata_ptr = (char *) param->password; pthread_mutex_lock(&pam_mutex); if (!pamh) { retval = pam_start ((char *)service, "3proxy@" , &conv, &pamh); } if (retval == PAM_SUCCESS) retval = pam_set_item (pamh, PAM_USER, param->username); /*fprintf(stderr,"pam_set_item1 rc=%d\n",retval);*/ if (retval == PAM_SUCCESS) retval = pam_set_item (pamh, PAM_CONV, &conv); /*fprintf(stderr,"pam_set_item2 rc=%d\n",retval); */ if (retval == PAM_SUCCESS) retval = pam_authenticate (pamh, 0); /*fprintf(stderr,"pam_authenticate rc=%d\n",retval);*/ if (retval == PAM_SUCCESS) { /*auth OK*/ rc=0; } else { /*auth ERR*/ rc=5; } if (pamh) retval = pam_end (pamh, retval); if (retval != PAM_SUCCESS) { pamh = NULL; } pthread_mutex_unlock(&pam_mutex); return rc; } /*------------------------------- MAIN -------------------------------------- start plugin init */ int start(struct pluginlink * pluginlink, int argc, unsigned char** argv) { if(argc < 2) return 1; pl = pluginlink; if(service) pl->myfree(service); service=(unsigned char *)pl->mystrdup((char *)argv[1]); if (already_loaded) { return (0); } already_loaded = 1; pthread_mutex_init(&pam_mutex, NULL); pamauth.authenticate = pamfunc; pamauth.authorize = pluginlink->checkACL; pamauth.desc = "pam"; pamauth.next = pluginlink->authfuncs->next; pluginlink->authfuncs->next = &pamauth; return 0; }