/* * The authentication thread function. * Performs scanning the queue for new requests and calling PAM for them. */ static void* pam_auth_worker(void *arg) { int current_slot = pam_first_taken_slot; struct pam_auth_request *request; while (true) { /* Wait for new data in the queue */ pthread_mutex_lock(&pam_queue_tail_mutex); while (current_slot == pam_first_free_slot) { pthread_cond_wait(&pam_data_available, &pam_queue_tail_mutex); } pthread_mutex_unlock(&pam_queue_tail_mutex); log_debug("pam_auth_worker(): processing slot %d", current_slot); /* We have at least one request in the queue */ request = &pam_auth_queue[current_slot]; current_slot = (current_slot + 1) % PAM_REQUEST_QUEUE_SIZE; /* If the socket is already in the wrong state or reused then ignore it. * This check is not safe and should not be trusted (the socket state * might change exactly after it), but it helps to quickly filter out invalid * sockets and thus save some time. */ if (!is_valid_socket(request)) { log_debug("pam_auth_worker(): invalid socket in slot %d", current_slot); request->status = PAM_STATUS_FAILED; continue; } if (pam_check_passwd(request)) { request->status = PAM_STATUS_SUCCESS; } else { request->status = PAM_STATUS_FAILED; } log_debug("pam_auth_worker(): authorization completed, status=%d", request->status); } return NULL; }
int main(int argc, char *argv[]) { char* user = NULL; char* locn = NULL; int infosystem, ch; infosystem = INFO_PAM; while ((ch = getopt(argc, argv, "ci:l:")) != -1) { switch(ch) { case 'i': if (!strcasecmp(optarg, "file")) { infosystem = INFO_FILE; } else if (!strcasecmp(optarg, "NIS")) { infosystem = INFO_NIS; } else if (!strcasecmp(optarg, "YP")) { infosystem = INFO_NIS; } else if (!strcasecmp(optarg, "opendirectory")) { infosystem = INFO_OPEN_DIRECTORY; } else if (!strcasecmp(optarg, "PAM")) { infosystem = INFO_PAM; } else { fprintf(stderr, "%s: Unknown info system \'%s\'.\n", progname, optarg); usage(); } break; case 'l': locn = optarg; break; case 'c': literal++; break; case '?': default: usage(); break; } } argc -= optind; argv += optind; if (argc > 1) { usage(); } else if (argc == 1) { user = argv[0]; } if (user == NULL) { struct passwd* pw = getpwuid(getuid()); if (pw != NULL && pw->pw_name != NULL) { user = strdup(pw->pw_name); } if (user == NULL) { fprintf(stderr, "you don't have a login name\n"); exit(1); } } switch (infosystem) { case INFO_FILE: file_check_passwd(user, locn); break; case INFO_NIS: nis_check_passwd(user, locn); break; case INFO_OPEN_DIRECTORY: od_check_passwd(user, locn); break; case INFO_PAM: pam_check_passwd(user); break; } exit(0); }