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