pam_modutil_searchkey.c 2.4 KB

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