_pam_macros.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #ifndef PAM_MACROS_H
  2. #define PAM_MACROS_H
  3. /*
  4. * All kind of macros used by PAM, but usable in some other
  5. * programs too.
  6. * Organized by Cristian Gafton <gafton@redhat.com>
  7. */
  8. /* a 'safe' version of strdup */
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #define x_strdup(s) ( (s) ? strdup(s):NULL )
  12. /* Good policy to strike out passwords with some characters not just
  13. free the memory */
  14. #define _pam_overwrite(x) \
  15. do { \
  16. register char *__xx__; \
  17. if ((__xx__=(x))) \
  18. while (*__xx__) \
  19. *__xx__++ = '\0'; \
  20. } while (0)
  21. #define _pam_overwrite_n(x,n) \
  22. do { \
  23. register char *__xx__; \
  24. register unsigned int __i__ = 0; \
  25. if ((__xx__=(x))) \
  26. for (;__i__<n; __i__++) \
  27. __xx__[__i__] = 0; \
  28. } while (0)
  29. /*
  30. * Don't just free it, forget it too.
  31. */
  32. #define _pam_drop(X) \
  33. do { \
  34. if (X) { \
  35. free(X); \
  36. X=NULL; \
  37. } \
  38. } while (0)
  39. #define _pam_drop_reply(/* struct pam_response * */ reply, /* int */ replies) \
  40. do { \
  41. int reply_i; \
  42. \
  43. for (reply_i=0; reply_i<replies; ++reply_i) { \
  44. if (reply[reply_i].resp) { \
  45. _pam_overwrite(reply[reply_i].resp); \
  46. free(reply[reply_i].resp); \
  47. } \
  48. } \
  49. if (reply) \
  50. free(reply); \
  51. } while (0)
  52. /* some debugging code */
  53. #ifdef PAM_DEBUG
  54. /*
  55. * This provides the necessary function to do debugging in PAM.
  56. * Cristian Gafton <gafton@redhat.com>
  57. */
  58. #include <stdio.h>
  59. #include <sys/types.h>
  60. #include <stdarg.h>
  61. #include <errno.h>
  62. #include <sys/stat.h>
  63. #include <fcntl.h>
  64. #include <unistd.h>
  65. /*
  66. * This is for debugging purposes ONLY. DO NOT use on live systems !!!
  67. * You have been warned :-) - CG
  68. *
  69. * to get automated debugging to the log file, it must be created manually.
  70. * _PAM_LOGFILE must exist and be writable to the programs you debug.
  71. */
  72. #ifndef _PAM_LOGFILE
  73. #define _PAM_LOGFILE "/var/run/pam-debug.log"
  74. #endif
  75. static void _pam_output_debug_info(const char *file, const char *fn
  76. , const int line)
  77. {
  78. FILE *logfile;
  79. int must_close = 1, fd;
  80. #ifdef O_NOFOLLOW
  81. if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_NOFOLLOW|O_APPEND)) != -1) {
  82. #else
  83. if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_APPEND)) != -1) {
  84. #endif
  85. if (!(logfile = fdopen(fd,"a"))) {
  86. logfile = stderr;
  87. must_close = 0;
  88. close(fd);
  89. }
  90. } else {
  91. logfile = stderr;
  92. must_close = 0;
  93. }
  94. fprintf(logfile,"[%s:%s(%d)] ",file, fn, line);
  95. fflush(logfile);
  96. if (must_close)
  97. fclose(logfile);
  98. }
  99. static void _pam_output_debug(const char *format, ...)
  100. {
  101. va_list args;
  102. FILE *logfile;
  103. int must_close = 1, fd;
  104. va_start(args, format);
  105. #ifdef O_NOFOLLOW
  106. if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_NOFOLLOW|O_APPEND)) != -1) {
  107. #else
  108. if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_APPEND)) != -1) {
  109. #endif
  110. if (!(logfile = fdopen(fd,"a"))) {
  111. logfile = stderr;
  112. must_close = 0;
  113. close(fd);
  114. }
  115. } else {
  116. logfile = stderr;
  117. must_close = 0;
  118. }
  119. vfprintf(logfile, format, args);
  120. fprintf(logfile, "\n");
  121. fflush(logfile);
  122. if (must_close)
  123. fclose(logfile);
  124. va_end(args);
  125. }
  126. #define D(x) do { \
  127. _pam_output_debug_info(__FILE__, __FUNCTION__, __LINE__); \
  128. _pam_output_debug x ; \
  129. } while (0)
  130. #define _pam_show_mem(X,XS) do { \
  131. int i; \
  132. register unsigned char *x; \
  133. x = (unsigned char *)X; \
  134. fprintf(stderr, " <start at %p>\n", X); \
  135. for (i = 0; i < XS ; ++x, ++i) { \
  136. fprintf(stderr, " %02X. <%p:%02X>\n", i, x, *x); \
  137. } \
  138. fprintf(stderr, " <end for %p after %d bytes>\n", X, XS); \
  139. } while (0)
  140. #define _pam_show_reply(/* struct pam_response * */reply, /* int */replies) \
  141. do { \
  142. int reply_i; \
  143. setbuf(stderr, NULL); \
  144. fprintf(stderr, "array at %p of size %d\n",reply,replies); \
  145. fflush(stderr); \
  146. if (reply) { \
  147. for (reply_i = 0; reply_i < replies; reply_i++) { \
  148. fprintf(stderr, " elem# %d at %p: resp = %p, retcode = %d\n", \
  149. reply_i, reply+reply_i, reply[reply_i].resp, \
  150. reply[reply_i].resp, _retcode); \
  151. fflush(stderr); \
  152. if (reply[reply_i].resp) { \
  153. fprintf(stderr, " resp[%d] = '%s'\n", \
  154. strlen(reply[reply_i].resp), reply[reply_i].resp); \
  155. fflush(stderr); \
  156. } \
  157. } \
  158. } \
  159. fprintf(stderr, "done here\n"); \
  160. fflush(stderr); \
  161. } while (0)
  162. #else
  163. #define D(x) do { } while (0)
  164. #define _pam_show_mem(X,XS) do { } while (0)
  165. #define _pam_show_reply(reply, replies) do { } while (0)
  166. #endif /* PAM_DEBUG */
  167. #endif /* PAM_MACROS_H */