123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- /*
- * $Id$
- *
- * Copyright (c) Andrew G. Morgan <morgan@ftp.kernel.org>
- *
- * pamc_start and pamc_end
- */
- #include "libpamc.h"
- /*
- * liberate path list
- */
- static void __pamc_delete_path_list(pamc_handle_t pch)
- {
- int i;
- for (i=0; pch->agent_paths[i]; ++i) {
- free(pch->agent_paths[i]);
- pch->agent_paths[i] = NULL;
- }
- free(pch->agent_paths);
- pch->agent_paths = NULL;
- }
- /*
- * open the pamc library
- */
- pamc_handle_t pamc_start(void)
- {
- int i, count, last, this;
- const char *default_path;
- pamc_handle_t pch;
- pch = calloc(1, sizeof(struct pamc_handle_s));
- if (pch == NULL) {
- D(("no memory for *pch"));
- return NULL;
- }
- pch->highest_fd_to_close = _PAMC_DEFAULT_TOP_FD;
- default_path = getenv("PAMC_AGENT_PATH");
- if (default_path == NULL) {
- default_path = PAMC_SYSTEM_AGENT_PATH;
- }
- /* number of individual paths */
- for (count=1, i=0; default_path[i]; ++i) {
- if (default_path[i] == PAMC_SYSTEM_AGENT_SEPARATOR) {
- ++count;
- }
- }
- pch->agent_paths = calloc(count+1, sizeof(char *));
- if (pch->agent_paths == NULL) {
- D(("no memory for path list"));
- goto drop_pch;
- }
- this = last = i = 0;
- while ( default_path[i] || (i != last) ) {
- if ( default_path[i] == PAMC_SYSTEM_AGENT_SEPARATOR
- || !default_path[i] ) {
- int length;
- pch->agent_paths[this] = malloc(length = 1+i-last);
- if (pch->agent_paths[this] == NULL) {
- D(("no memory for next path"));
- goto drop_list;
- }
- memcpy(pch->agent_paths[this], default_path + last, i-last);
- pch->agent_paths[this][i-last] = '\0';
- if (length > pch->max_path) {
- pch->max_path = length;
- }
- if (++this == count) {
- break;
- }
- last = ++i;
- } else {
- ++i;
- }
- }
- return pch;
- drop_list:
- __pamc_delete_path_list(pch);
- drop_pch:
- free(pch);
- return NULL;
- }
- /*
- * shutdown each of the loaded agents and
- */
- static int __pamc_shutdown_agents(pamc_handle_t pch)
- {
- int retval = PAM_BPC_TRUE;
- D(("called"));
- while (pch->chain) {
- pid_t pid;
- int status;
- pamc_agent_t *this;
- this = pch->chain;
- D(("cleaning up agent %p", this));
- pch->chain = pch->chain->next;
- this->next = NULL;
- D(("cleaning up agent: %s", this->id));
- /* close off contact with agent and wait for it to shutdown */
- close(this->writer);
- this->writer = -1;
- close(this->reader);
- this->reader = -1;
- pid = waitpid(this->pid, &status, 0);
- if (pid == this->pid) {
- D(("is exit:%d, exit val:%d",
- WIFEXITED(status), WEXITSTATUS(status)));
- if (!(WIFEXITED(status) && (WEXITSTATUS(status) == 0))) {
- retval = PAM_BPC_FALSE;
- }
- } else {
- D(("problem shutting down agent (%s): pid(%d) != waitpid(%d)!?",
- this->id, this->pid, pid));
- retval = PAM_BPC_FALSE;
- }
- pid = this->pid = 0;
- memset(this->id, 0, this->id_length);
- free(this->id);
- this->id = NULL;
- this->id_length = 0;
- free(this);
- this = NULL;
- }
- return retval;
- }
- /*
- * close the pamc library
- */
- int pamc_end(pamc_handle_t *pch_p)
- {
- int retval;
- if (pch_p == NULL) {
- D(("called with no pch_p"));
- return PAM_BPC_FALSE;
- }
- if (*pch_p == NULL) {
- D(("called with no *pch_p"));
- return PAM_BPC_FALSE;
- }
- D(("removing path_list"));
- __pamc_delete_path_list(*pch_p);
- D(("shutting down agents"));
- retval = __pamc_shutdown_agents(*pch_p);
- D(("freeing *pch_p"));
- free(*pch_p);
- *pch_p = NULL;
- return retval;
- }
|