(root)/
Linux-PAM-1.5.3/
modules/
pam_filter/
upperLOWER/
upperLOWER.c
       1  /*
       2   * This is a sample filter program, for use with pam_filter (a module
       3   * provided with Linux-PAM). This filter simply transposes upper and
       4   * lower case letters, it is intended for demonstration purposes and
       5   * it serves no purpose other than to annoy the user...
       6   */
       7  
       8  #include "config.h"
       9  
      10  #include <ctype.h>
      11  #include <stdio.h>
      12  #include <stdlib.h>
      13  #include <syslog.h>
      14  #include <sys/time.h>
      15  #include <sys/types.h>
      16  #include <unistd.h>
      17  
      18  #include "pam_filter.h"
      19  #include <security/pam_modutil.h>
      20  
      21  /* ---------------------------------------------------------------- */
      22  
      23  static void do_transpose(char *buffer,int len)
      24  {
      25       int i;
      26       for (i=0; i<len; ++i) {
      27  	  if (islower(buffer[i])) {
      28  	       buffer[i] = toupper(buffer[i]);
      29  	  } else {
      30  	       buffer[i] = tolower(buffer[i]);
      31  	  }
      32       }
      33  }
      34  
      35  extern char **environ;
      36  
      37  int main(int argc, char **argv UNUSED)
      38  {
      39       char buffer[BUFSIZ];
      40       fd_set readers;
      41       void (*before_user)(char *,int);
      42       void (*before_app)(char *,int);
      43  
      44       openlog("upperLOWER", LOG_CONS|LOG_PID, LOG_AUTHPRIV);
      45  
      46  #ifdef DEBUG
      47       {
      48  	  int i;
      49  
      50  	  fprintf(stderr,"environment :[\r\n");
      51  	  for (i=0; environ[i]; ++i) {
      52  	       fprintf(stderr,"-> %s\r\n",environ[i]);
      53  	  }
      54  	  fprintf(stderr,"]: end\r\n");
      55       }
      56  #endif
      57  
      58       if (argc != 1) {
      59  #ifdef DEBUG
      60  	  fprintf(stderr,"filter invoked as conventional executable\n");
      61  #else
      62  	  syslog(LOG_ERR, "filter invoked as conventional executable");
      63  #endif
      64  	  exit(1);
      65       }
      66  
      67       before_user = before_app = do_transpose;   /* assign filter functions */
      68  
      69       /* enter a loop that deals with the input and output of the
      70          user.. passing it to and from the application */
      71  
      72       FD_ZERO(&readers);                    /* initialize reading mask */
      73  
      74       for (;;) {
      75  
      76  	  FD_SET(APPOUT_FILENO, &readers);              /* wake for output */
      77  	  FD_SET(APPERR_FILENO, &readers);               /* wake for error */
      78  	  FD_SET(STDIN_FILENO, &readers);                /* wake for input */
      79  
      80  	  if ( select(APPTOP_FILE,&readers,NULL,NULL,NULL) < 0 ) {
      81  #ifdef DEBUG
      82  	       fprintf(stderr,"select failed\n");
      83  #else
      84  	       syslog(LOG_WARNING,"select failed");
      85  #endif
      86  	       break;
      87  	  }
      88  
      89  	  /* application errors */
      90  
      91  	  if ( FD_ISSET(APPERR_FILENO,&readers) ) {
      92  	       int got = read(APPERR_FILENO, buffer, BUFSIZ);
      93  	       if (got <= 0) {
      94  		    break;
      95  	       } else {
      96  		    /* translate to give to real terminal */
      97  		    if (before_user != NULL)
      98  			 before_user(buffer, got);
      99  		    if (pam_modutil_write(STDERR_FILENO, buffer, got) != got ) {
     100  			 syslog(LOG_WARNING,"couldn't write %d bytes?!",got);
     101  			 break;
     102  		    }
     103  	       }
     104  	  } else if ( FD_ISSET(APPOUT_FILENO,&readers) ) {    /* app output */
     105  	       int got = read(APPOUT_FILENO, buffer, BUFSIZ);
     106  	       if (got <= 0) {
     107  		    break;
     108  	       } else {
     109  		    /* translate to give to real terminal */
     110  		    if (before_user != NULL)
     111  			 before_user(buffer, got);
     112  		    if (pam_modutil_write(STDOUT_FILENO, buffer, got) != got ) {
     113  			 syslog(LOG_WARNING,"couldn't write %d bytes!?",got);
     114  			 break;
     115  		    }
     116  	       }
     117  	  }
     118  
     119  	  if ( FD_ISSET(STDIN_FILENO, &readers) ) {  /* user input */
     120  	       int got = read(STDIN_FILENO, buffer, BUFSIZ);
     121  	       if (got < 0) {
     122  		    syslog(LOG_WARNING,"user input junked");
     123  		    break;
     124  	       } else if (got) {
     125  		    /* translate to give to application */
     126  		    if (before_app != NULL)
     127  			 before_app(buffer, got);
     128  		    if (pam_modutil_write(APPIN_FILENO, buffer, got) != got ) {
     129  			 syslog(LOG_WARNING,"couldn't pass %d bytes!?",got);
     130  			 break;
     131  		    }
     132  	       } else {
     133  		    /* nothing received -- an error? */
     134  		    syslog(LOG_WARNING,"user input null?");
     135  		    break;
     136  	       }
     137  	  }
     138       }
     139  
     140       exit(0);
     141  }