(root)/
Linux-PAM-1.5.3/
libpam/
pam_modutil_searchkey.c
       1  /*
       2   * This file implements the following functions:
       3   *   pam_modutil_search_key:
       4   *     lookup a value for key in login.defs file or similar key value format
       5   */
       6  
       7  #include "config.h"
       8  
       9  #include "pam_private.h"
      10  #include "pam_modutil_private.h"
      11  #include <security/pam_ext.h>
      12  #include <stdio.h>
      13  #include <string.h>
      14  #include <stdlib.h>
      15  #include <ctype.h>
      16  #ifdef USE_ECONF
      17  #include <libeconf.h>
      18  #endif
      19  
      20  #define BUF_SIZE 8192
      21  
      22  #ifdef USE_ECONF
      23  #define LOGIN_DEFS "/etc/login.defs"
      24  
      25  #ifndef VENDORDIR
      26  #define VENDORDIR NULL
      27  #endif
      28  
      29  static char *
      30  econf_search_key (const char *name, const char *suffix, const char *key)
      31  {
      32  	econf_file *key_file = NULL;
      33  	char *val;
      34  
      35  	if (econf_readDirs (&key_file, VENDORDIR, SYSCONFDIR, name, suffix,
      36  			    " \t", "#"))
      37  		return NULL;
      38  
      39  	if (econf_getStringValue (key_file, NULL, key, &val)) {
      40  		econf_free (key_file);
      41  		return NULL;
      42  	}
      43  
      44  	econf_free (key_file);
      45  
      46  	return val;
      47  }
      48  
      49  #endif
      50  
      51  /* lookup a value for key in login.defs file or similar key value format */
      52  char *
      53  pam_modutil_search_key(pam_handle_t *pamh UNUSED,
      54  		       const char *file_name,
      55  		       const char *key)
      56  {
      57  	FILE *fp;
      58  	char *buf = NULL;
      59  	size_t buflen = 0;
      60  	char *retval = NULL;
      61  
      62  #ifdef USE_ECONF
      63  	if (strcmp (file_name, LOGIN_DEFS) == 0)
      64  		return econf_search_key ("login", ".defs", key);
      65  #endif
      66  
      67  	fp = fopen(file_name, "r");
      68  	if (NULL == fp)
      69  		return NULL;
      70  
      71  	while (!feof(fp)) {
      72  		char *tmp, *cp;
      73  #if defined(HAVE_GETLINE)
      74  		ssize_t n = getline(&buf, &buflen, fp);
      75  #elif defined (HAVE_GETDELIM)
      76  		ssize_t n = getdelim(&buf, &buflen, '\n', fp);
      77  #else
      78  		ssize_t n;
      79  
      80  		if (buf == NULL) {
      81  			buflen = BUF_SIZE;
      82  			buf = malloc(buflen);
      83  			if (buf == NULL) {
      84  				fclose(fp);
      85  				return NULL;
      86  			}
      87  		}
      88  		buf[0] = '\0';
      89  		if (fgets(buf, buflen - 1, fp) == NULL)
      90  			break;
      91  		else if (buf != NULL)
      92  			n = strlen(buf);
      93  		else
      94  			n = 0;
      95  #endif /* HAVE_GETLINE / HAVE_GETDELIM */
      96  		cp = buf;
      97  
      98  		if (n < 1)
      99  			break;
     100  		if (cp[n - 1] == '\n')
     101  			cp[n - 1] = '\0';
     102  
     103  		tmp = strchr(cp, '#');  /* remove comments */
     104  		if (tmp)
     105  			*tmp = '\0';
     106  		while (isspace((int)*cp))    /* remove spaces and tabs */
     107  			++cp;
     108  		if (*cp == '\0')        /* ignore empty lines */
     109  			continue;
     110  
     111  		tmp = strsep (&cp, " \t=");
     112  		if (cp != NULL)
     113  			while (isspace((int)*cp) || *cp == '=')
     114  				++cp;
     115  		else
     116  			cp = buf + n;   /* empty string */
     117  
     118  		if (strcasecmp(tmp, key) == 0) {
     119  			retval = strdup(cp);
     120  			break;
     121  		}
     122  	}
     123  	fclose(fp);
     124  
     125  	free(buf);
     126  
     127  	return retval;
     128  }