Code

Fix translations when extra-opts aren't enabled
[nagiosplug.git] / plugins / check_ldap.c
1 /*****************************************************************************
2
3 * Nagios check_ldap plugin
4
5 * License: GPL
6 * Copyright (c) 2000-2008 Nagios Plugins Development Team
7
8 * Description:
9
10 * This file contains the check_ldap plugin
11
12
13 * This program is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, either version 3 of the License, or
16 * (at your option) any later version.
17
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22
23 * You should have received a copy of the GNU General Public License
24 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25
26
27 *****************************************************************************/
29 /* progname may be check_ldaps */
30 char *progname = "check_ldap";
31 const char *copyright = "2000-2008";
32 const char *email = "nagiosplug-devel@lists.sourceforge.net";
34 #include "common.h"
35 #include "netutils.h"
36 #include "utils.h"
38 #include <lber.h>
39 #define LDAP_DEPRECATED 1
40 #include <ldap.h>
42 enum {
43         UNDEFINED = 0,
44 #ifdef HAVE_LDAP_SET_OPTION
45         DEFAULT_PROTOCOL = 2,
46 #endif
47         DEFAULT_PORT = 389
48 };
50 int process_arguments (int, char **);
51 int validate_arguments (void);
52 void print_help (void);
53 void print_usage (void);
55 char ld_defattr[] = "(objectclass=*)";
56 char *ld_attr = ld_defattr;
57 char *ld_host = NULL;
58 char *ld_base = NULL;
59 char *ld_passwd = NULL;
60 char *ld_binddn = NULL;
61 int ld_port = DEFAULT_PORT;
62 #ifdef HAVE_LDAP_SET_OPTION
63 int ld_protocol = DEFAULT_PROTOCOL;
64 #endif
65 #ifndef LDAP_OPT_SUCCESS
66 # define LDAP_OPT_SUCCESS LDAP_SUCCESS
67 #endif
68 double warn_time = UNDEFINED;
69 double crit_time = UNDEFINED;
70 struct timeval tv;
71 int starttls = FALSE;
72 int ssl_on_connect = FALSE;
73 int verbose = 0;
75 /* for ldap tls */
77 char *SERVICE = "LDAP";
79 int
80 main (int argc, char *argv[])
81 {
83         LDAP *ld;
84         LDAPMessage *result;
86         /* should be    int result = STATE_UNKNOWN; */
88         int status = STATE_UNKNOWN;
89         long microsec;
90         double elapsed_time;
92         /* for ldap tls */
94         int tls;
95         int version=3;
97         setlocale (LC_ALL, "");
98         bindtextdomain (PACKAGE, LOCALEDIR);
99         textdomain (PACKAGE);
101         if (strstr(argv[0],"check_ldaps")) {
102                 asprintf (&progname, "check_ldaps");
103         }
105         /* Parse extra opts if any */
106         argv=np_extra_opts (&argc, argv, progname);
108         if (process_arguments (argc, argv) == ERROR)
109                 usage4 (_("Could not parse arguments"));
111         if (strstr(argv[0],"check_ldaps") && ! starttls && ! ssl_on_connect)
112                 starttls = TRUE;
114         /* initialize alarm signal handling */
115         signal (SIGALRM, socket_timeout_alarm_handler);
117         /* set socket timeout */
118         alarm (socket_timeout);
120         /* get the start time */
121         gettimeofday (&tv, NULL);
123         /* initialize ldap */
124 #ifdef HAVE_LDAP_INIT
125         if (!(ld = ldap_init (ld_host, ld_port))) {
126                 printf ("Could not connect to the server at port %i\n", ld_port);
127                 return STATE_CRITICAL;
128         }
129 #else
130         if (!(ld = ldap_open (ld_host, ld_port))) {
131                 if (verbose)
132                         ldap_perror(ld, "ldap_open");
133                 printf (_("Could not connect to the server at port %i\n"), ld_port);
134                 return STATE_CRITICAL;
135         }
136 #endif /* HAVE_LDAP_INIT */
138 #ifdef HAVE_LDAP_SET_OPTION
139         /* set ldap options */
140         if (ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &ld_protocol) !=
141                         LDAP_OPT_SUCCESS ) {
142                 printf(_("Could not set protocol version %d\n"), ld_protocol);
143                 return STATE_CRITICAL;
144         }
145 #endif
147         if (ld_port == LDAPS_PORT || ssl_on_connect) {
148                 asprintf (&SERVICE, "LDAPS");
149 #if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)
150                 /* ldaps: set option tls */
151                 tls = LDAP_OPT_X_TLS_HARD;
153                 if (ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
154                 {
155                         if (verbose)
156                                 ldap_perror(ld, "ldaps_option");
157                         printf (_("Could not init TLS at port %i!\n"), ld_port);
158                         return STATE_CRITICAL;
159                 }
160 #else
161                 printf (_("TLS not supported by the libraries!\n"));
162                 return STATE_CRITICAL;
163 #endif /* LDAP_OPT_X_TLS */
164         } else if (starttls) {
165                 asprintf (&SERVICE, "LDAP-TLS");
166 #if defined(HAVE_LDAP_SET_OPTION) && defined(HAVE_LDAP_START_TLS_S)
167                 /* ldap with startTLS: set option version */
168                 if (ldap_get_option(ld,LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS )
169                 {
170                         if (version < LDAP_VERSION3)
171                         {
172                                 version = LDAP_VERSION3;
173                                 ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
174                         }
175                 }
176                 /* call start_tls */
177                 if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS)
178                 {
179                         if (verbose)
180                                 ldap_perror(ld, "ldap_start_tls");
181                         printf (_("Could not init startTLS at port %i!\n"), ld_port);
182                         return STATE_CRITICAL;
183                 }
184 #else
185                 printf (_("startTLS not supported by the library, needs LDAPv3!\n"));
186                 return STATE_CRITICAL;
187 #endif /* HAVE_LDAP_START_TLS_S */
188         }
190         /* bind to the ldap server */
191         if (ldap_bind_s (ld, ld_binddn, ld_passwd, LDAP_AUTH_SIMPLE) !=
192                         LDAP_SUCCESS) {
193                 if (verbose)
194                         ldap_perror(ld, "ldap_bind");
195                 printf (_("Could not bind to the LDAP server\n"));
196                 return STATE_CRITICAL;
197         }
199         /* do a search of all objectclasses in the base dn */
200         if (ldap_search_s (ld, ld_base, LDAP_SCOPE_BASE, ld_attr, NULL, 0, &result)
201                         != LDAP_SUCCESS) {
202                 if (verbose)
203                         ldap_perror(ld, "ldap_search");
204                 printf (_("Could not search/find objectclasses in %s\n"), ld_base);
205                 return STATE_CRITICAL;
206         }
208         /* unbind from the ldap server */
209         ldap_unbind (ld);
211         /* reset the alarm handler */
212         alarm (0);
214         /* calcutate the elapsed time and compare to thresholds */
216         microsec = deltime (tv);
217         elapsed_time = (double)microsec / 1.0e6;
219         if (crit_time!=UNDEFINED && elapsed_time>crit_time)
220                 status = STATE_CRITICAL;
221         else if (warn_time!=UNDEFINED && elapsed_time>warn_time)
222                 status = STATE_WARNING;
223         else
224                 status = STATE_OK;
226         /* print out the result */
227         printf (_("LDAP %s - %.3f seconds response time|%s\n"),
228                 state_text (status),
229                 elapsed_time,
230                 fperfdata ("time", elapsed_time, "s",
231                           (int)warn_time, warn_time,
232                           (int)crit_time, crit_time,
233                           TRUE, 0, FALSE, 0));
235         return status;
238 /* process command-line arguments */
239 int
240 process_arguments (int argc, char **argv)
242         int c;
244         int option = 0;
245         /* initialize the long option struct */
246         static struct option longopts[] = {
247                 {"help", no_argument, 0, 'h'},
248                 {"version", no_argument, 0, 'V'},
249                 {"timeout", required_argument, 0, 't'},
250                 {"host", required_argument, 0, 'H'},
251                 {"base", required_argument, 0, 'b'},
252                 {"attr", required_argument, 0, 'a'},
253                 {"bind", required_argument, 0, 'D'},
254                 {"pass", required_argument, 0, 'P'},
255 #ifdef HAVE_LDAP_SET_OPTION
256                 {"ver2", no_argument, 0, '2'},
257                 {"ver3", no_argument, 0, '3'},
258 #endif
259                 {"starttls", no_argument, 0, 'T'},
260                 {"ssl", no_argument, 0, 'S'},
261                 {"use-ipv4", no_argument, 0, '4'},
262                 {"use-ipv6", no_argument, 0, '6'},
263                 {"port", required_argument, 0, 'p'},
264                 {"warn", required_argument, 0, 'w'},
265                 {"crit", required_argument, 0, 'c'},
266                 {"verbose", no_argument, 0, 'v'},
267                 {0, 0, 0, 0}
268         };
270         if (argc < 2)
271                 return ERROR;
273         for (c = 1; c < argc; c++) {
274                 if (strcmp ("-to", argv[c]) == 0)
275                         strcpy (argv[c], "-t");
276         }
278         while (1) {
279                 c = getopt_long (argc, argv, "hvV234TS6t:c:w:H:b:p:a:D:P:", longopts, &option);
281                 if (c == -1 || c == EOF)
282                         break;
284                 switch (c) {
285                 case 'h':                                                                       /* help */
286                         print_help ();
287                         exit (STATE_OK);
288                 case 'V':                                                                       /* version */
289                         print_revision (progname, NP_VERSION);
290                         exit (STATE_OK);
291                 case 't':                                                                       /* timeout period */
292                         if (!is_intnonneg (optarg))
293                                 usage2 (_("Timeout interval must be a positive integer"), optarg);
294                         else
295                                 socket_timeout = atoi (optarg);
296                         break;
297                 case 'H':
298                         ld_host = optarg;
299                         break;
300                 case 'b':
301                         ld_base = optarg;
302                         break;
303                 case 'p':
304                         ld_port = atoi (optarg);
305                         break;
306                 case 'a':
307                         ld_attr = optarg;
308                         break;
309                 case 'D':
310                         ld_binddn = optarg;
311                         break;
312                 case 'P':
313                         ld_passwd = optarg;
314                         break;
315                 case 'w':
316                         warn_time = strtod (optarg, NULL);
317                         break;
318                 case 'c':
319                         crit_time = strtod (optarg, NULL);
320                         break;
321 #ifdef HAVE_LDAP_SET_OPTION
322                 case '2':
323                         ld_protocol = 2;
324                         break;
325                 case '3':
326                         ld_protocol = 3;
327                         break;
328 #endif
329                 case '4':
330                         address_family = AF_INET;
331                         break;
332                 case 'v':
333                         verbose++;
334                         break;
335                 case 'T':
336                         if (! ssl_on_connect)
337                                 starttls = TRUE;
338                         else
339                                 usage_va(_("%s cannot be combined with %s"), "-T/--starttls", "-S/--ssl");
340                         break;
341                 case 'S':
342                         if (! starttls) {
343                                 ssl_on_connect = TRUE;
344                                 ld_port = LDAPS_PORT;
345                         } else
346                                 usage_va(_("%s cannot be combined with %s"), "-S/--ssl", "-T/--starttls");
347                         break;
348                 case '6':
349 #ifdef USE_IPV6
350                         address_family = AF_INET6;
351 #else
352                         usage (_("IPv6 support not available\n"));
353 #endif
354                         break;
355                 default:
356                         usage5 ();
357                 }
358         }
360         c = optind;
361         if (ld_host == NULL && is_host(argv[c]))
362                 ld_host = strdup (argv[c++]);
364         if (ld_base == NULL && argv[c])
365                 ld_base = strdup (argv[c++]);
367         return validate_arguments ();
371 int
372 validate_arguments ()
374         if (ld_host==NULL || strlen(ld_host)==0)
375                 usage4 (_("Please specify the host name\n"));
377         if (ld_base==NULL)
378                 usage4 (_("Please specify the LDAP base\n"));
380         return OK;
384 void
385 print_help (void)
387         char *myport;
388         asprintf (&myport, "%d", DEFAULT_PORT);
390         print_revision (progname, NP_VERSION);
392         printf ("Copyright (c) 1999 Didi Rieder (adrieder@sbox.tu-graz.ac.at)\n");
393         printf (COPYRIGHT, copyright, email);
395         printf ("\n\n");
397         print_usage ();
399         printf (UT_HELP_VRSN);
400         printf (UT_EXTRA_OPTS);
402         printf (UT_HOST_PORT, 'p', myport);
404         printf (UT_IPv46);
406         printf (" %s\n", "-a [--attr]");
407   printf ("    %s\n", _("ldap attribute to search (default: \"(objectclass=*)\""));
408   printf (" %s\n", "-b [--base]");
409   printf ("    %s\n", _("ldap base (eg. ou=my unit, o=my org, c=at"));
410   printf (" %s\n", "-D [--bind]");
411   printf ("    %s\n", _("ldap bind DN (if required)"));
412   printf (" %s\n", "-P [--pass]");
413   printf ("    %s\n", _("ldap password (if required)"));
414   printf (" %s\n", "-T [--starttls]");
415   printf ("    %s\n", _("use starttls mechanism introduced in protocol version 3"));
416   printf (" %s\n", "-S [--ssl]");
417   printf ("    %s %i\n", _("use ldaps (ldap v2 ssl method). this also sets the default port to"), LDAPS_PORT);
419 #ifdef HAVE_LDAP_SET_OPTION
420         printf (" %s\n", "-2 [--ver2]");
421   printf ("    %s\n", _("use ldap protocol version 2"));
422   printf (" %s\n", "-3 [--ver3]");
423   printf ("    %s\n", _("use ldap protocol version 3"));
424   printf ("    (%s %d)\n", _("default protocol version:"), DEFAULT_PROTOCOL);
425 #endif
427         printf (UT_WARN_CRIT);
429         printf (UT_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
431         printf (UT_VERBOSE);
433         printf ("\n");
434         printf ("%s\n", _("Notes:"));
435         printf (" %s\n", _("If this plugin is called via 'check_ldaps', method 'STARTTLS' will be"));
436         printf (_(" implied (using default port %i) unless --port=636 is specified. In that case\n"), DEFAULT_PORT);
437         printf (" %s\n", _("'SSL on connect' will be used no matter how the plugin was called."));
438         printf (" %s\n", _("This detection is deprecated, please use 'check_ldap' with the '--starttls' or '--ssl' flags"));
439         printf (" %s\n", _("to define the behaviour explicitly instead."));
440 #ifdef NP_EXTRA_OPTS
441         printf ("\n");
442         printf (UT_EXTRA_OPTS_NOTES);
443 #endif
445         printf (UT_SUPPORT);
448 /* todo
449 * add option -4 and -6 to the long manual
451 */
453 void
454 print_usage (void)
456   printf (_("Usage:"));
457         printf (" %s -H <host> -b <base_dn> [-p <port>] [-a <attr>] [-D <binddn>]",progname);
458   printf ("\n       [-P <password>] [-w <warn_time>] [-c <crit_time>] [-t timeout]%s\n",
459 #ifdef HAVE_LDAP_SET_OPTION
460                         "\n       [-2|-3] [-4|-6]"
461 #else
462                         ""
463 #endif
464                         );