Code

various fixes for localization
[nagiosplug.git] / plugins / check_radius.c
1 /******************************************************************************
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; either version 2 of the License, or
6  (at your option) any later version.
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  GNU General Public License for more details.
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  $Id$
18  
19  ******************************************************************************/
21 const char *progname = "check_radius";
22 const char *revision = "$Revision$";
23 const char *copyright = "2000-2003";
24 const char *email = "nagiosplug-devel@lists.sourceforge.net";
26 #include "common.h"
27 #include "utils.h"
28 #include "netutils.h"
30 #include <radiusclient.h>
32 int process_arguments (int, char **);
33 void print_help (void);
34 void print_usage (void);
36 char *server = NULL;
37 char *username = NULL;
38 char *password = NULL;
39 char *nasid = NULL;
40 char *expect = NULL;
41 char *config_file = NULL;
42 unsigned short port = PW_AUTH_UDP_PORT;
43 int retries = 1;
44 int verbose = FALSE;
45 ENV *env = NULL;
47 /******************************************************************************
49 The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@
50 tags in the comments. With in the tags, the XML is assembled sequentially.
51 You can define entities in tags. You also have all the #defines available as
52 entities.
54 Please note that all tags must be lowercase to use the DocBook XML DTD.
56 @@-<article>
58 <sect1>
59 <title>Quick Reference</title>
60 <!-- The refentry forms a manpage -->
61 <refentry>
62 <refmeta>
63 <manvolnum>5<manvolnum>
64 </refmeta>
65 <refnamdiv>
66 <refname>&progname;</refname>
67 <refpurpose>&SUMMARY;</refpurpose>
68 </refnamdiv>
69 </refentry>
70 </sect1>
72 <sect1>
73 <title>FAQ</title>
74 </sect1>
76 <sect1>
77 <title>Theory, Installation, and Operation</title>
79 <sect2>
80 <title>General Description</title>
81 <para>
82 &DESCRIPTION;
83 </para>
84 </sect2>
86 <sect2>
87 <title>Future Enhancements</title>
88 <para>Todo List</para>
89 <itemizedlist>
90 <listitem>Add option to get password from a secured file rather than the command line</listitem>
91 </itemizedlist>
92 </sect2>
95 <sect2>
96 <title>Functions</title>
97 -@@
98 ******************************************************************************/
102 int
103 main (int argc, char **argv)
105         UINT4 service;
106         char msg[BUFFER_LEN];
107         SEND_DATA data;
108         int result = STATE_UNKNOWN;
109         UINT4 client_id;
110         char *str;
112         setlocale (LC_ALL, "");
113         bindtextdomain (PACKAGE, LOCALEDIR);
114         textdomain (PACKAGE);
116         if (process_arguments (argc, argv) == ERROR)
117                 usage4 (_("Could not parse arguments"));
119         str = strdup ("dictionary");
120         if ((config_file && rc_read_config (config_file)) ||
121                         rc_read_dictionary (rc_conf_str (str)))
122                 die (STATE_UNKNOWN, _("Config file error"));
124         service = PW_AUTHENTICATE_ONLY;
126         if (!(rc_avpair_add (&data.send_pairs, PW_SERVICE_TYPE, &service, 0) &&
127                                 rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) &&
128                                 rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0) &&
129                                 (nasid==NULL || rc_avpair_add (&data.send_pairs, PW_NAS_IDENTIFIER, nasid, 0))))
130                 die (STATE_UNKNOWN, _("Out of Memory?"));
132         /* 
133          * Fill in NAS-IP-Address 
134          */
136         if ((client_id = rc_own_ipaddress ()) == 0)
137                 return (ERROR_RC);
139         if (rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) ==
140                         NULL) return (ERROR_RC);
142         rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval,
143                      retries);
145         result = rc_send_server (&data, msg);
146         rc_avpair_free (data.send_pairs);
147         if (data.receive_pairs)
148                 rc_avpair_free (data.receive_pairs);
150         if (result == TIMEOUT_RC)
151                 die (STATE_CRITICAL, _("Timeout"));
152         if (result == ERROR_RC)
153                 die (STATE_CRITICAL, _("Auth Error"));
154         if (result == BADRESP_RC)
155                 die (STATE_WARNING, _("Auth Failed"));
156         if (expect && !strstr (msg, expect))
157                 die (STATE_WARNING, "%s", msg);
158         if (result == OK_RC)
159                 die (STATE_OK, _("Auth OK"));
160         return (0);
165 /* process command-line arguments */
166 int
167 process_arguments (int argc, char **argv)
169         int c;
171         int option = 0;
172         static struct option longopts[] = {
173                 {"hostname", required_argument, 0, 'H'},
174                 {"port", required_argument, 0, 'P'},
175                 {"username", required_argument, 0, 'u'},
176                 {"password", required_argument, 0, 'p'},
177                 {"nas-id", required_argument, 0, 'n'},
178                 {"filename", required_argument, 0, 'F'},
179                 {"expect", required_argument, 0, 'e'},
180                 {"retries", required_argument, 0, 'r'},
181                 {"timeout", required_argument, 0, 't'},
182                 {"verbose", no_argument, 0, 'v'},
183                 {"version", no_argument, 0, 'V'},
184                 {"help", no_argument, 0, 'h'},
185                 {0, 0, 0, 0}
186         };
188         if (argc < 2)
189                 return ERROR;
191         if (argc == 9) {
192                 config_file = argv[1];
193                 username = argv[2];
194                 password = argv[3];
195                 if (is_intpos (argv[4]))
196                         timeout_interval = atoi (argv[4]);
197                 else
198                         usage2 (_("Timeout interval must be a positive integer"), optarg);
199                 if (is_intpos (argv[5]))
200                         retries = atoi (argv[5]);
201                 else
202                         usage4 (_("Number of retries must be a positive integer"));
203                 server = argv[6];
204                 if (is_intpos (argv[7]))
205                         port = atoi (argv[7]);
206                 else
207                         usage4 (_("Port must be a positive integer"));
208                 expect = argv[8];
209                 return OK;
210         }
212         while (1) {
213                 c = getopt_long (argc, argv, "+hVvH:P:F:u:p:n:t:r:e:", longopts,
214                                                                          &option);
216                 if (c == -1 || c == EOF || c == 1)
217                         break;
219                 switch (c) {
220                 case '?':                                                                       /* print short usage statement if args not parsable */
221                         usage2 (_("Unknown argument"), optarg);
222                 case 'h':                                                                       /* help */
223                         print_help ();
224                         exit (OK);
225                 case 'V':                                                                       /* version */
226                         print_revision (progname, revision);
227                         exit (OK);
228                 case 'v':                                                                       /* verbose mode */
229                         verbose = TRUE;
230                         break;
231                 case 'H':                                                                       /* hostname */
232                         if (is_host (optarg) == FALSE) {
233                                 usage2 (_("Invalid hostname/address"), optarg);
234                         }
235                         server = optarg;
236                         break;
237                 case 'P':                                                                       /* port */
238                         if (is_intnonneg (optarg))
239                                 port = atoi (optarg);
240                         else
241                                 usage4 (_("Port must be a positive integer"));
242                         break;
243                 case 'u':                                                                       /* username */
244                         username = optarg;
245                         break;
246                 case 'p':                                                                       /* password */
247                         password = optarg;
248                         break;
249                 case 'n':                                                                       /* nas id */
250                         nasid = optarg;
251                         break;
252                 case 'F':                                                                       /* configuration file */
253                         config_file = optarg;
254                         break;
255                 case 'e':                                                                       /* expect */
256                         expect = optarg;
257                         break;
258                 case 'r':                                                                       /* retries */
259                         if (is_intpos (optarg))
260                                 retries = atoi (optarg);
261                         else
262                                 usage4 (_("Number of retries must be a positive integer"));
263                         break;
264                 case 't':                                                                       /* timeout */
265                         if (is_intpos (optarg))
266                                 timeout_interval = atoi (optarg);
267                         else
268                                 usage2 (_("Timeout interval must be a positive integer"), optarg);
269                         break;
270                 }
271         }
272         return OK;
277 void
278 print_help (void)
280         char *myport;
281         asprintf (&myport, "%d", PW_AUTH_UDP_PORT);
283         print_revision (progname, revision);
285         printf ("Copyright (c) 1999 Robert August Vincent II\n");
286         printf (COPYRIGHT, copyright, email);
288         printf(_("Tests to see if a radius server is accepting connections.\n\n"));
290         print_usage ();
292         printf (_(UT_HELP_VRSN));
294         printf (_(UT_HOST_PORT), 'P', myport);
296         printf (_("\
297  -u, --username=STRING\n\
298     The user to authenticate\n\
299  -p, --password=STRING\n\
300     Password for autentication (SECURITY RISK)\n\
301  -n, --nas-id=STRING\n\
302     NAS identifier\n\
303  -F, --filename=STRING\n\
304     Configuration file\n\
305  -e, --expect=STRING\n\
306     Response string to expect from the server\n\
307  -r, --retries=INTEGER\n\
308     Number of times to retry a failed connection\n"));
310         printf (_(UT_TIMEOUT), timeout_interval);
312         printf (_("\n\
313 This plugin tests a radius server to see if it is accepting connections.\n\
314 \n\
315 The server to test must be specified in the invocation, as well as a user\n\
316 name and password. A configuration file may also be present. The format of\n\
317 the configuration file is described in the radiusclient library sources.\n\n"));
319         printf (_("\
320 The password option presents a substantial security issue because the\n\
321 password can be determined by careful watching of the command line in\n\
322 a process listing.  This risk is exacerbated because nagios will\n\
323 run the plugin at regular prdictable intervals.  Please be sure that\n\
324 the password used does not allow access to sensitive system resources,\n\
325 otherwise compormise could occur.\n"));
327         printf (_(UT_SUPPORT));
332 void
333 print_usage (void)
335         printf ("\
336 Usage: %s -H host -F config_file -u username -p password [-n nas-id] [-P port]\n\
337                   [-t timeout] [-r retries] [-e expect]\n", progname);