--- check_ldap.c.orig	Thu Nov 14 18:47:22 2002
+++ check_ldap.c	Fri Nov 15 13:54:00 2002
@@ -7,7 +7,10 @@
  * 
  * Last Modified: $Date: 2002/02/28 06:42:57 $
  *
- * Command line: check_ldap -h <host> -b <base_dn> -p <port> -w <warn_time> -w <crit_time>
+ * Command line: check_ldap -H <host> -b <base_dn> -p <port> [-f <attr>] 
+ *       [-a <attr>] [-e <expect>] [-W <Warn_attr>] [-C <Crit_attr>] [-r]
+ *       [-D <binddn>] [-P <password>]
+ *       [-w <warn_time>] [-c <crit_time>] [-t timeout] [-v]
  *
  * Description:
  *
@@ -17,6 +20,8 @@
  *
  * 08-25-1999 Ethan Galstad (nagios@nagios.org)
  *            Modified to use common plugin include file
+ * 11-15-2002 Gyula Szabo (gyufi@sztaki.hu)
+ *            Modified check_ldap.c
  *
  *****************************************************************************/
 
@@ -41,6 +46,12 @@
 
 char ld_defattr[] = "(objectclass=*)";
 char *ld_attr = ld_defattr;
+char *attr = "";
+char *expect = "";
+int verbose = 0;
+int reverse = 0;
+char *attr_warn = "", *attr_crit = "";
+long attr_warn_long, attr_crit_long;
 char *ld_host = NULL, *ld_base = NULL, *ld_passwd = NULL, *ld_binddn = NULL;
 unsigned int ld_port = 389;
 int warn_time = UNKNOWN, crit_time = UNKNOWN;
@@ -50,14 +61,26 @@
 {
 
 	LDAP *ld;
-	LDAPMessage *result;
+	LDAPMessage *result, *e;
 
-	int t_diff;
+	int t_diff, i;
 	time_t time0, time1;
+	BerElement *ber;
+	char *a, *dn; 
+	char **vals;
+	char * pEnd;
+	char res[50] = "";
 
 	if (process_arguments (argc, argv) == ERROR)
 		usage ("check_ldap: could not parse arguments\n");
 
+	if (validate_arguments () == ERROR)
+		usage ("check_ldap: not valid arguments\n");
+
+	/* convert strings to long integers */
+	attr_warn_long = strtol (attr_warn,&pEnd,0);
+	attr_crit_long = strtol (attr_crit,&pEnd,0);
+
 	/* initialize alarm signal handling */
 	signal (SIGALRM, socket_timeout_alarm_handler);
 
@@ -70,7 +93,7 @@
 	/* initialize ldap */
 	if (!(ld = ldap_open (ld_host, ld_port))) {
 		/*ldap_perror(ld, "ldap_open"); */
-		printf ("Could not connect to the server at port %i\n", ld_port);
+		printf ("LDAP critical - Could not connect to the server at port %i\n", ld_port);
 		return STATE_CRITICAL;
 	}
 
@@ -78,7 +101,7 @@
 	if (ldap_bind_s (ld, ld_binddn, ld_passwd, LDAP_AUTH_SIMPLE) !=
 			LDAP_SUCCESS) {
 		/*ldap_perror(ld, "ldap_bind"); */
-		printf ("Could not bind to the ldap-server\n");
+		printf ("LDAP critical - Could not bind to the ldap-server\n");
 		return STATE_CRITICAL;
 	}
 
@@ -86,10 +109,68 @@
 	if (ldap_search_s (ld, ld_base, LDAP_SCOPE_BASE, ld_attr, NULL, 0, &result)
 			!= LDAP_SUCCESS) {
 		/*ldap_perror(ld, "ldap_search"); */
-		printf ("Could not search/find objectclasses in %s\n", ld_base);
+		printf ("LDAP critical - Could not search/find objectclasses in %s\n", ld_base);
 		return STATE_CRITICAL;
 	}
 
+
+	/* For each matching entry, print the entry name and its attributes. */
+	for ( e = ldap_first_entry( ld, result ); e != NULL;
+		 e = ldap_next_entry( ld, e ) ) {
+	   if ( ( dn = ldap_get_dn( ld, e ) ) != NULL ) {
+	      if (verbose) {printf( "dn: %s\n", dn );}
+	      ldap_memfree( dn );
+	   }
+	   for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL;
+		 a = ldap_next_attribute( ld, e, ber ) ) {
+	      if ( ( vals = ldap_get_values( ld, e, a ) ) != NULL ) {
+		 for ( i = 0; vals[i] != NULL; i++ ) {
+		    if (verbose) {printf( "%s: %s\n", a, vals[i] );}
+		    if ( strcmp (a,attr) == 0 ) {
+			strcpy(res,a);
+			strcat(res,": ");
+			strncat(res,vals[i],30);
+
+			if (strcmp(vals[i],expect) != 0 && strcmp("",expect) != 0 ) {
+				printf ("LDAP critical - %s: %s \n", a, vals[i]);
+				return STATE_CRITICAL;
+			}
+			if(reverse){
+				if (attr_crit_long && strtol(vals[i],&pEnd,0)<=attr_crit_long) {
+					printf ("LDAP critical - %s: %s\n", a, vals[i]);
+					return STATE_CRITICAL;
+				}
+				if (attr_warn_long && strtol(vals[i],&pEnd,0)<=attr_warn_long) {
+					printf ("LDAP warning - %s: %s\n", a, vals[i]);
+					return STATE_WARNING;
+				}
+			}
+			else {
+				if (attr_crit_long && strtol(vals[i],&pEnd,0)>=attr_crit_long) {
+					printf ("LDAP critical - %s: %s\n", a, vals[i]);
+					return STATE_CRITICAL;
+				}
+				if (attr_warn_long && strtol(vals[i],&pEnd,0)>=attr_warn_long) {
+					printf ("LDAP warning - %s: %s\n", a, vals[i]);
+					return STATE_WARNING;
+				}
+			}
+		    }
+			
+		 }
+		 ldap_value_free( vals );
+	      }
+	      ldap_memfree( a );
+	   }
+	   if ( ber != NULL ) {
+	      ber_free( ber, 0 );
+	   }
+	   printf( "\n" );
+	}
+	ldap_msgfree( result );
+
+
+
 	/* unbind from the ldap server */
 	ldap_unbind (ld);
 
@@ -113,7 +194,8 @@
 	}
 
 	/* print out the result */
-	printf ("LDAP ok - %i seconds response time\n", t_diff);
+	if (strcmp(res,"") != 0) {printf ("LDAP ok - %i seconds response time, %s\n", t_diff, res);}
+	else {printf ("LDAP ok - %i seconds response time\n", t_diff);}
 
 	return STATE_OK;
 }
@@ -158,12 +240,15 @@
 		{"timeout", required_argument, 0, 't'},
 		{"host", required_argument, 0, 'H'},
 		{"base", required_argument, 0, 'b'},
+		{"filter", required_argument, 0, 'f'},
 		{"attr", required_argument, 0, 'a'},
+		{"expect", required_argument, 0, 'e'},
 		{"bind", required_argument, 0, 'D'},
 		{"pass", required_argument, 0, 'P'},
 		{"port", required_argument, 0, 'p'},
 		{"warn", required_argument, 0, 'w'},
 		{"crit", required_argument, 0, 'c'},
+		{"verbose", required_argument, 0, 'v'},
 		{0, 0, 0, 0}
 	};
 #endif
@@ -175,10 +260,10 @@
 	while (1) {
 #ifdef HAVE_GETOPT_H
 		c =
-			getopt_long (argc, argv, "+hVt:c:w:H:b:p:a:D:P:", long_options,
+			getopt_long (argc, argv, "+hVt:c:w:H:b:p:f:a:e:W:C:D:P:vr", long_options,
 									 &option_index);
 #else
-		c = getopt (argc, argv, "+?hVt:c:w:H:b:p:a:D:P:");
+		c = getopt (argc, argv, "+?hVt:c:w:H:b:p:f:a:e:W:C:D:P:vr");
 #endif
 
 		if (c == -1 || c == EOF)
@@ -192,9 +277,14 @@
 		case 'H':
 		case 'b':
 		case 'p':
+		case 'f':
 		case 'a':
+		case 'e':
+		case 'W':
+		case 'C':
 		case 'D':
 		case 'P':
+		case 'v':
 			i++;
 		}
 
@@ -219,9 +309,28 @@
 		case 'p':
 			ld_port = atoi (optarg);
 			break;
-		case 'a':
+		case 'f':
 			ld_attr = optarg;
 			break;
+		case 'a':
+			attr = optarg;
+			break;
+		case 'e':
+			expect = optarg;
+			break;
+		case 'W':
+			if (!is_intnonneg (optarg))
+				usage2 ("Warning value must be an integer", optarg);
+			attr_warn = optarg;
+			break;
+		case 'C':
+			if (!is_intnonneg (optarg))
+				usage2 ("Critical value must be an integer", optarg);
+			attr_crit = optarg;
+			break;
+		case 'r':
+			reverse = 1;
+			break;
 		case 'D':
 			ld_binddn = optarg;
 			break;
@@ -234,6 +343,9 @@
 		case 'c':
 			crit_time = atoi (optarg);
 			break;
+		case 'v':
+			verbose = 1;
+			break;
 		default:
 			usage ("check_ldap: could not parse arguments\n");
 			break;
@@ -247,7 +359,18 @@
 {
 	if (ld_host[0] == 0 ||
 			ld_base[0] == 0 ||
-			ld_port == UNKNOWN || warn_time == UNKNOWN || crit_time == UNKNOWN) {
+			ld_port == UNKNOWN || warn_time == UNKNOWN || crit_time == UNKNOWN ||
+			(
+				(attr != "" && expect == "") && 
+				(attr != "" && (attr_warn == "" || attr_crit == ""))
+			) ||
+			(
+				(attr_warn != "" || attr_crit != "" || expect != "") && (attr == "")
+			) ||
+			(
+				((attr_warn != "" || attr_crit != "") && expect != "")
+			)
+			) {
 		return ERROR;
 	}
 	else {
@@ -270,13 +393,19 @@
 		("\n"
 		 "Options:\n"
 		 "\t-H [--host] ... host\n"
-		 "\t-a [--attr] ... ldap attribute to search (default: \"(objectclass=*)\"\n"
+		 "\t-f [--filter] ... ldap attribute to search (default: \"(objectclass=*)\"\n"
+		 "\t-a [--attr] ... ldap attribute to compare \n"
+		 "\t-e [--expect] ... expect string to match attribute - if not equal the STATE_CRITICAL will be returned\n"
+		 "\t-W [--Warn] ... Attribute value. - if the exceeds <Warn> the STATE_WARNING will be returned\n"
+		 "\t-C [--Crit] ... Attribute value. - if the exceeds <Crit> the STATE_CRITICAL will be returned\n"
+		 "\t-r [--reverse] ... Comparing attribute value is reverse (lower attribute value is abnormal)\n"
 		 "\t-b [--base] ... ldap base (eg. ou=my unit, o=my org, c=at)\n"
 		 "\t-D [--bind] ... ldap bind DN (if required)\n"
 		 "\t-P [--pass] ... ldap password (if required)\n"
 		 "\t-p [--port] ... ldap port (normaly 389)\n"
 		 "\t-w [--warn] ... time in secs. - if the exceeds <warn> the STATE_WARNING will be returned\n"
 		 "\t-c [--crit] ... time in secs. - if the exceeds <crit> the STATE_CRITICAL will be returned\n"
+		 "\t-v [--verbose] ... Verbose output, print all attributes\n"
 		 "\n");
 }
 
@@ -285,7 +414,10 @@
 print_usage ()
 {
 	printf
-		("Usage: %s -H <host> -b <base_dn> -p <port> [-a <attr>] [-D <binddn>]\n"
-		 "         [-P <password>] [-w <warn_time>] [-c <crit_time>] [-t timeout]\n"
-		 "(Note: all times are in seconds.)\n", PROGNAME);
+		("Usage: %s -H <host> -b <base_dn> -p <port> [-f <attr>] \n"
+		 "         [-a <attr>] [-e <expect>] [-W <Warn_attr>] [-C <Crit_attr>] [-r]\n"
+		 "         [-D <binddn>] [-P <password>]\n"
+		 "         [-w <warn_time>] [-c <crit_time>] [-t timeout] [-v]\n"
+		 "(Note: all times are in seconds,\n"
+		 "       if you use -a then you\'ve to use -W and -C or -e alone.)\n", PROGNAME);
 }