(root)/
Linux-PAM-1.5.3/
libpam/
pam_data.c
       1  /*
       2   * Redistribution and use in source and binary forms, with or without
       3   * modification, are permitted provided that the following conditions
       4   * are met:
       5   * 1. Redistributions of source code must retain the above copyright
       6   *    notice, and the entire permission notice in its entirety,
       7   *    including the disclaimer of warranties.
       8   * 2. Redistributions in binary form must reproduce the above copyright
       9   *    notice, this list of conditions and the following disclaimer in the
      10   *    documentation and/or other materials provided with the distribution.
      11   * 3. The name of the author may not be used to endorse or promote
      12   *    products derived from this software without specific prior
      13   *    written permission.
      14   *
      15   * ALTERNATIVELY, this product may be distributed under the terms of
      16   * the GNU Public License, in which case the provisions of the GPL are
      17   * required INSTEAD OF the above restrictions.  (This clause is
      18   * necessary due to a potential bad interaction between the GPL and
      19   * the restrictions contained in a BSD-style copyright.)
      20   *
      21   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
      22   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      23   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      24   * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
      25   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      26   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      27   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      29   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      30   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      31   * OF THE POSSIBILITY OF SUCH DAMAGE.
      32   */
      33  
      34  #include "config.h"
      35  
      36  #include "pam_private.h"
      37  
      38  #include <stdlib.h>
      39  #include <string.h>
      40  
      41  static struct pam_data *_pam_locate_data(const pam_handle_t *pamh,
      42  					 const char *name)
      43  {
      44      struct pam_data *data;
      45  
      46      D(("called"));
      47  
      48      IF_NO_PAMH("_pam_locate_data", pamh, NULL);
      49  
      50      data = pamh->data;
      51  
      52      while (data) {
      53  	if (!strcmp(data->name, name)) {
      54  	    return data;
      55  	}
      56  	data = data->next;
      57      }
      58  
      59      return NULL;
      60  }
      61  
      62  int pam_set_data(
      63      pam_handle_t *pamh,
      64      const char *module_data_name,
      65      void *data,
      66      void (*cleanup)(pam_handle_t *pamh, void *data, int error_status))
      67  {
      68      struct pam_data *data_entry;
      69  
      70      D(("called"));
      71  
      72      IF_NO_PAMH("pam_set_data", pamh, PAM_SYSTEM_ERR);
      73  
      74      if (__PAM_FROM_APP(pamh)) {
      75  	D(("called from application!?"));
      76  	return PAM_SYSTEM_ERR;
      77      }
      78  
      79      /* module_data_name should not be NULL */
      80      if (module_data_name == NULL) {
      81  	D(("called with NULL as module_data_name"));
      82  	return PAM_SYSTEM_ERR;
      83      }
      84  
      85      /* first check if there is some data already. If so clean it up */
      86  
      87      if ((data_entry = _pam_locate_data(pamh, module_data_name))) {
      88  	if (data_entry->cleanup) {
      89  	    data_entry->cleanup(pamh, data_entry->data,
      90  				PAM_DATA_REPLACE | PAM_SUCCESS );
      91  	}
      92      } else if ((data_entry = malloc(sizeof(*data_entry)))) {
      93  	char *tname;
      94  
      95  	if ((tname = _pam_strdup(module_data_name)) == NULL) {
      96  	    pam_syslog(pamh, LOG_CRIT,
      97  		       "pam_set_data: no memory for data name");
      98  	    _pam_drop(data_entry);
      99  	    return PAM_BUF_ERR;
     100  	}
     101  	data_entry->next = pamh->data;
     102  	pamh->data = data_entry;
     103  	data_entry->name = tname;
     104      } else {
     105  	pam_syslog(pamh, LOG_CRIT,
     106  		   "pam_set_data: cannot allocate data entry");
     107  	return PAM_BUF_ERR;
     108      }
     109  
     110      data_entry->data = data;           /* note this could be NULL */
     111      data_entry->cleanup = cleanup;
     112  
     113      return PAM_SUCCESS;
     114  }
     115  
     116  int pam_get_data(
     117      const pam_handle_t *pamh,
     118      const char *module_data_name,
     119      const void **datap)
     120  {
     121      struct pam_data *data;
     122  
     123      D(("called"));
     124  
     125      IF_NO_PAMH("pam_get_data", pamh, PAM_SYSTEM_ERR);
     126  
     127      if (__PAM_FROM_APP(pamh)) {
     128  	D(("called from application!?"));
     129  	return PAM_SYSTEM_ERR;
     130      }
     131  
     132      /* module_data_name should not be NULL */
     133      if (module_data_name == NULL) {
     134  	D(("called with NULL as module_data_name"));
     135  	return PAM_SYSTEM_ERR;
     136      }
     137  
     138      data = _pam_locate_data(pamh, module_data_name);
     139      if (data) {
     140  	*datap = data->data;
     141  	return PAM_SUCCESS;
     142      }
     143  
     144      return PAM_NO_MODULE_DATA;
     145  }
     146  
     147  void _pam_free_data(pam_handle_t *pamh, int status)
     148  {
     149      struct pam_data *last;
     150      struct pam_data *data;
     151  
     152      D(("called"));
     153  
     154      IF_NO_PAMH("_pam_free_data", pamh, /* no return value for void fn */);
     155      data = pamh->data;
     156  
     157      while (data) {
     158  	last = data;
     159  	data = data->next;
     160  	if (last->cleanup) {
     161  	    last->cleanup(pamh, last->data, status);
     162  	}
     163  	_pam_drop(last->name);
     164  	_pam_drop(last);
     165      }
     166  }