aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.md1
-rw-r--r--Makefile.am17
-rw-r--r--README.md8
-rw-r--r--acinclude.m424
-rw-r--r--configure.ac2
-rw-r--r--doc/ldapinfo.1.in137
-rw-r--r--src/ldapinfo.c709
7 files changed, 898 insertions, 0 deletions
diff --git a/ChangeLog.md b/ChangeLog.md
index 61e0f83..9548912 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -10,6 +10,7 @@ Copyright (C) 2012, 2019 David M. Syzdek <david@syzdek.net>
10 - ldap2csv: adding ability to specify default values (syzdek) 10 - ldap2csv: adding ability to specify default values (syzdek)
11 - ldap2csv: making search filter optional (syzdek) 11 - ldap2csv: making search filter optional (syzdek)
12 - ldap2json: adding utility (syzdek) 12 - ldap2json: adding utility (syzdek)
13 - ldapinfo: adding utility (syzdek)
13 - ldaptree: fixing filter handling when specifing attributes (syzdek) 14 - ldaptree: fixing filter handling when specifing attributes (syzdek)
14 - ldaptree: adding comments above graph (syzdek) 15 - ldaptree: adding comments above graph (syzdek)
15 - ldaptree: fixing segfault when displaying linear tree (syzdek) 16 - ldaptree: fixing segfault when displaying linear tree (syzdek)
diff --git a/Makefile.am b/Makefile.am
index ee95de5..2b5514f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -91,6 +91,7 @@ EXTRA_DIST = $(noinst_HEADERS) \
91 TODO.md \ 91 TODO.md \
92 $(srcdir)/doc/ldap2csv.1.in \ 92 $(srcdir)/doc/ldap2csv.1.in \
93 $(srcdir)/doc/ldap2json.1.in \ 93 $(srcdir)/doc/ldap2json.1.in \
94 $(srcdir)/doc/ldapinfo.1.in \
94 $(srcdir)/doc/ldapdebug.1.in \ 95 $(srcdir)/doc/ldapdebug.1.in \
95 $(srcdir)/doc/ldaptree.1.in \ 96 $(srcdir)/doc/ldaptree.1.in \
96 lib/libldaputils/libldaputils.sym 97 lib/libldaputils/libldaputils.sym
@@ -179,6 +180,19 @@ src_ldapdn2str_LDADD = $(AM_LDADD) -lldap -llber lib/libldaputils.a
179src_ldapdn2str_SOURCES = src/ldapdn2str.c 180src_ldapdn2str_SOURCES = src/ldapdn2str.c
180 181
181 182
183# macros for ldapinfo
184if LDAPUTILS_LDAPINFO
185 bin_PROGRAMS += src/ldapinfo
186 man_MANS += doc/ldapinfo.1
187endif
188src_ldapinfo_DEPENDENCIES = Makefile lib/libldaputils.a
189src_ldapinfo_CPPFLAGS = -DPROGRAM_NAME="\"ldapinfo\"" $(AM_CPPFLAGS)
190src_ldapinfo_CFLAGS = $(AM_CFLAGS)
191src_ldapinfo_LDFLAGS = $(AM_LDFLAGS)
192src_ldapinfo_LDADD = $(AM_LDADD) -lldap -llber lib/libldaputils.a
193src_ldapinfo_SOURCES = src/ldapinfo.c
194
195
182# macros for ldaptree 196# macros for ldaptree
183if LDAPUTILS_LDAPTREE 197if LDAPUTILS_LDAPTREE
184bin_PROGRAMS += src/ldaptree 198bin_PROGRAMS += src/ldaptree
@@ -213,6 +227,9 @@ doc/ldap2json.1: Makefile $(srcdir)/doc/ldap2json.1.in
213doc/ldapdebug.1: Makefile $(srcdir)/doc/ldapdebug.1.in 227doc/ldapdebug.1: Makefile $(srcdir)/doc/ldapdebug.1.in
214 @$(do_subst_dt) 228 @$(do_subst_dt)
215 229
230doc/ldapinfo.1: Makefile $(srcdir)/doc/ldapinfo.1.in
231 @$(do_subst_dt)
232
216doc/ldaptree.1: Makefile $(srcdir)/doc/ldaptree.1.in 233doc/ldaptree.1: Makefile $(srcdir)/doc/ldaptree.1.in
217 @$(do_subst_dt) 234 @$(do_subst_dt)
218 235
diff --git a/README.md b/README.md
index d4b420b..666b3ec 100644
--- a/README.md
+++ b/README.md
@@ -43,6 +43,7 @@ Contents
43 - ldap2json 43 - ldap2json
44 - ldapdebug 44 - ldapdebug
45 - ldapdn2str 45 - ldapdn2str
46 - ldapinfo
46 - ldaptree 47 - ldaptree
47 * Source Code 48 * Source Code
48 * Package Maintence Notes 49 * Package Maintence Notes
@@ -261,6 +262,13 @@ The following are example of the output presentations available:
261 - `dc=org,dc=foo,ou=People,uid=administrator` 262 - `dc=org,dc=foo,ou=People,uid=administrator`
262 263
263 264
265ldapinfo
266--------
267
268ldapinfo is a shell utilty which queries the LDAP server for server information and
269displays the information in human readble form.
270
271
264ldaptree 272ldaptree
265-------- 273--------
266 274
diff --git a/acinclude.m4 b/acinclude.m4
index 0182766..a83b639 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -128,6 +128,30 @@ AC_DEFUN([AC_LDAP_UTILS_LDAPDN2STR],[dnl
128])dnl 128])dnl
129 129
130 130
131# AC_LDAP_UTILS_LDAPINFO
132# ______________________________________________________________________________
133AC_DEFUN([AC_LDAP_UTILS_LDAPINFO],[dnl
134
135 # prerequists
136 AC_REQUIRE([AC_LDAP_UTILS_UTILITIES])
137
138 enableval=""
139 AC_ARG_ENABLE(
140 ldapinfo,
141 [AS_HELP_STRING([ --disable-ldapinfo], [disable building ldapinfo utility])],
142 [ ELDAPINFO=$enableval ],
143 [ ELDAPINFO=$enableval ]
144 )
145
146 if test "x${ELDAPINFO}" != "x${LDAPUTILS_UTILITIES_ALT}";then
147 ELDAPINFO=${LDAPUTILS_UTILITIES}
148 fi
149 LDAPUTILS_LDAPINFO=${ELDAPINFO}
150
151 AM_CONDITIONAL([LDAPUTILS_LDAPINFO], [test "x$LDAPUTILS_LDAPINFO" = "xyes"])
152])dnl
153
154
131# AC_LDAP_UTILS_LDAPTREE 155# AC_LDAP_UTILS_LDAPTREE
132# ______________________________________________________________________________ 156# ______________________________________________________________________________
133AC_DEFUN([AC_LDAP_UTILS_LDAPTREE],[dnl 157AC_DEFUN([AC_LDAP_UTILS_LDAPTREE],[dnl
diff --git a/configure.ac b/configure.ac
index e29c014..9dbde10 100644
--- a/configure.ac
+++ b/configure.ac
@@ -180,6 +180,7 @@ AC_LDAP_UTILS_LDAP2CSV
180AC_LDAP_UTILS_LDAP2JSON 180AC_LDAP_UTILS_LDAP2JSON
181AC_LDAP_UTILS_LDAPDEBUG 181AC_LDAP_UTILS_LDAPDEBUG
182AC_LDAP_UTILS_LDAPDN2STR 182AC_LDAP_UTILS_LDAPDN2STR
183AC_LDAP_UTILS_LDAPINFO
183AC_LDAP_UTILS_LDAPTREE 184AC_LDAP_UTILS_LDAPTREE
184 185
185# Creates outputs 186# Creates outputs
@@ -200,6 +201,7 @@ AC_MSG_NOTICE([ Build ldap2csv $LDAPUTILS_LDAP2CSV])
200AC_MSG_NOTICE([ Build ldap2json $LDAPUTILS_LDAP2JSON]) 201AC_MSG_NOTICE([ Build ldap2json $LDAPUTILS_LDAP2JSON])
201AC_MSG_NOTICE([ Build ldapdebug $LDAPUTILS_LDAPDEBUG]) 202AC_MSG_NOTICE([ Build ldapdebug $LDAPUTILS_LDAPDEBUG])
202AC_MSG_NOTICE([ Build ldapdn2str $LDAPUTILS_LDAPDN2STR]) 203AC_MSG_NOTICE([ Build ldapdn2str $LDAPUTILS_LDAPDN2STR])
204AC_MSG_NOTICE([ Build ldapinfo $LDAPUTILS_LDAPINFO])
203AC_MSG_NOTICE([ Build ldaptree $LDAPUTILS_LDAPTREE]) 205AC_MSG_NOTICE([ Build ldaptree $LDAPUTILS_LDAPTREE])
204AC_MSG_NOTICE([ ]) 206AC_MSG_NOTICE([ ])
205AC_MSG_NOTICE([ Please send suggestions to: $PACKAGE_BUGREPORT]) 207AC_MSG_NOTICE([ Please send suggestions to: $PACKAGE_BUGREPORT])
diff --git a/doc/ldapinfo.1.in b/doc/ldapinfo.1.in
new file mode 100644
index 0000000..e5e6710
--- /dev/null
+++ b/doc/ldapinfo.1.in
@@ -0,0 +1,137 @@
1.\"
2.\" LDAP Utilities
3.\" Copyright (C) 2019 David M. Syzdek <david@syzdek.net>.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions are
7.\" met:
8.\"
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\"
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\" notice, this list of conditions and the following disclaimer in the
14.\" documentation and/or other materials provided with the distribution.
15.\"
16.\" 3. Neither the name of the copyright holder nor the names of its
17.\" contributors may be used to endorse or promote products derived from
18.\" this software without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21.\" IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22.\" THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27.\" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31.\"
32.\" doc/ldap2csv.1.in - man page for ldap2csv
33.\"
34.TH "LDAPINFO" "1" "@RELEASE_MONTH@" "@PACKAGE_NAME@" "User Commands"
35.SH NAME
36ldapinfo \- Retrieve LDAP server information
37
38
39.SH SYNOPSIS
40\fBldap2csv\fR
41[\fB-b\fR \fIbasedn\fR]
42[\fB-c\fR]
43[\fB-d\fR \fIlevel\fR]
44[\fB-D\fR \fIbinddn\fR]
45[\fB-H\fR \fIURI\fR]
46[\fB-l\fR \fIlimit\fR]
47[\fB-L\fR[\fB-L\fR]]
48[\fB-n\fR]
49[\fB-v\fR | \fB--version\fR]
50[\fB-s\fR \fIscope\fR]
51[\fB-w\fR \fIpasswd\fR]
52[\fB-W\fR]
53[\fB-x\fR]
54[\fB-y\fR \fIfile\fR]
55[\fB-Y\fR \fImech\fR]
56[\fB-z\fR \fIlimit\fR]
57[\fB-Z\fR[\fB-Z\fR]]
58.sp
59\fBldap2csv\fR [ \fB-h\fR | \fB--help\fR ]
60.sp
61\fBldap2csv\fR [ \fB-V\fR | \fB--version\fR ]
62
63
64.SH DESCRIPTION
65ldapinfo is a shell utilty which connects to an LDAP server and displays
66server information.
67
68
69.SH OPTIONS
70.TP
71\fB-c\fR
72do not stop if an error is encountered
73.TP
74\fB-d\fR
75set OpenLDAP debug level to `level'
76.TP
77\fB-D\fR \fIbinddn\fR
78bind DN used for simple bind
79.TP
80\fB-H\fR \fIURI\fR
81specifies list of LDAP Uniform Resource Identifier(s) used to connect to LDAP server
82.TP
83\fB-l\fR \fIlimit\fR
84time limit (in seconds) for search
85.TP
86\fB-L\fR
87two \fB-L\fR disables comments
88.TP
89\fB-v\fR \fB--version\fR
90run in verbose mode
91.TP
92\fB-s\fR \fIscope\fR
93specifies search filter. Must be one of \fIbase\fR, \fIone\fR, \fIsub\fR, or \fIchild\fR
94.TP
95\fB-w\fR \fIpasswd\fR
96bind password used for simple bind
97.TP
98\fB-W\fR
99prompt for bind password used in simple bind
100.TP
101\fB-x\fR
102use simple authentication for bind
103.TP
104\fB-y\fR \fIfile\fR
105read bind password from file
106.TP
107\fB-Y\fR \fImech\fR
108SASL mechanism used during bind
109.TP
110\fB-z\fR \fIlimit\fR
111size limit for search
112.TP
113\fB-Z\fR[\fB-Z\fR]
114Issue StartTLS before bind request. \fB-ZZ\fR requires TLS operations to be successful.
115
116
117.SH "SEE ALSO"
118.BR ldapsearch (1),
119.BR ldapdebug (1),
120.BR ldaptree (1),
121.BR ldap.conf (5)
122
123
124.SH AUTHOR
125David M. Syzdek <david@syzdek.net>
126
127
128.SH ACKNOWLEDGEMENTS
129\fB@PACKAGE_NAME@\fR is developed and maintained by David M. Syzdek
130<david@syzdek.net>. \fB@PACKAGE_NAME@\fR utilizes and is styled after the
131tools and libraries maintained by the \fBThe OpenLDAP Project\fR
132<http://www.openldap.org/>.
133
134
135.Sh CAVEATS
136
137.\" end of man page
diff --git a/src/ldapinfo.c b/src/ldapinfo.c
new file mode 100644
index 0000000..dc1cb01
--- /dev/null
+++ b/src/ldapinfo.c
@@ -0,0 +1,709 @@
1/*
2 * LDAP Utilities
3 * Copyright (C) 2019 David M. Syzdek <david@syzdek.net>.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * 3. Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32/**
33 * @file src/ldapinfo.c export LDAP data to CSV file
34 */
35/*
36 * Simple Build:
37 * export CFLAGS='-DPROGRAM_NAME="ldapinfo" -Wall -I../include'
38 * gcc ${CFLAGS} -c ldapinfo.c
39 * gcc ${CFLAGS} -lldap -o ldapinfo ldapinfo.o ../lib/libldaputils.a
40 *
41 * Libtool Build:
42 * export CFLAGS='-DPROGRAM_NAME="ldapinfo" -Wall -I../include'
43 * libtool --mode=compile --tag=CC gcc ${CFLAGS} -c ldapinfo.c
44 * libtool --mode=link --tag=CC gcc ${CFLAGS} -lldap -o ldapinfo \
45 * ldapinfo.lo ../lib/libldaputils.a
46 *
47 * Libtool Clean:
48 * libtool --mode=clean rm -f ldapinfo.lo ldapinfo
49 */
50#define _LDAP_UTILS_SRC_LDAPINFO 1
51
52///////////////
53// //
54// Headers //
55// //
56///////////////
57#pragma mark - Headers
58
59#include <stdio.h>
60#include <stdlib.h>
61#include <unistd.h>
62#include <string.h>
63#include <strings.h>
64#include <time.h>
65#include <getopt.h>
66#include <assert.h>
67
68#define LDAP_DEPRECATED 1
69#include <ldap.h>
70#include <ldaputils.h>
71
72
73///////////////////
74// //
75// Definitions //
76// //
77///////////////////
78#pragma mark - Definitions
79
80#ifndef PROGRAM_NAME
81#define PROGRAM_NAME "ldapinfo"
82#endif
83
84#define MY_SHORT_OPTIONS LDAPUTILS_OPTIONS_COMMON LDAPUTILS_OPTIONS_SEARCH "o:"
85
86
87/////////////////
88// //
89// Datatypes //
90// //
91/////////////////
92#pragma mark - Datatypes
93
94// configuration union
95typedef struct my_config MyConfig;
96struct my_config
97{
98 LDAPUtils * lud;
99 const char * filter;
100 const char * prog_name;
101 const char ** defvals;
102 char output[LDAPUTILS_OPT_LEN];
103};
104
105
106/////////////////
107// //
108// Variables //
109// //
110/////////////////
111#pragma mark - Variables
112
113static const char * ldapinfo_attrs[] =
114{
115 "cn",
116 "objectclass",
117 "configContext",
118 "isGlobalCatalogReady",
119 "monitorContext",
120 "monitorCounter",
121 "monitoredInfo",
122 "monitorOverlay",
123 "monitorUpdateRef",
124 "namingContexts",
125 "objectclass",
126 "readOnly",
127 "subschemaSubentry",
128 "supportedControl",
129 "supportedExtension",
130 "supportedFeatures",
131 "supportedLDAPVersion",
132 "supportedSASLMechanisms",
133 "vendorVersion",
134 "vendorName",
135 NULL
136};
137
138
139//////////////////
140// //
141// Prototypes //
142// //
143//////////////////
144#pragma mark - Prototypes
145
146// main statement
147int main(int argc, char * argv[]);
148
149// parses configuration
150int my_config(int argc, char * argv[], MyConfig ** cnfp);
151
152void my_field(const char * name, const char * val);
153
154void my_fields(const char * name, char ** vals);
155
156int my_monitor_connections(MyConfig * cnf, const char * base);
157
158int my_monitor_database(MyConfig * cnf, const char * base);
159
160// parses RootDSE
161int my_rootdse(MyConfig * cnf);
162
163int my_results(MyConfig * cnf, LDAPMessage * res);
164
165// fress resources
166void my_unbind(MyConfig * cnf);
167
168
169/////////////////
170// //
171// Functions //
172// //
173/////////////////
174#pragma mark - Functions
175
176/// prints program usage and exits
177void ldaputils_usage(void)
178{
179 printf("Usage: %s [options]\n", PROGRAM_NAME);
180 ldaputils_usage_common(MY_SHORT_OPTIONS);
181 printf("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
182 return;
183}
184
185
186/// main statement
187/// @param[in] argc number of arguments
188/// @param[in] argv array of arguments
189int main(int argc, char * argv[])
190{
191 int err;
192 MyConfig * cnf;
193
194 cnf = NULL;
195
196 // initializes resources and parses CLI arguments
197 if ((err = my_config(argc, argv, &cnf)) != 0)
198 return(1);
199 if (!(cnf))
200 return(0);
201
202 // starts TLS and binds to LDAP
203 if ((err = ldaputils_bind_s(cnf->lud)) != LDAP_SUCCESS)
204 {
205 fprintf(stderr, "%s: ldap_sasl_bind_s(): %s\n", ldaputils_get_prog_name(cnf->lud), ldap_err2string(err));
206 my_unbind(cnf);
207 return(1);
208 };
209
210 // processes root DSE
211 if ((err = my_rootdse(cnf)) == -1)
212 {
213 my_unbind(cnf);
214 return(1);
215 };
216
217 my_unbind(cnf);
218
219 return(0);
220}
221
222
223/// parses configuration
224/// @param[in] argc number of arguments
225/// @param[in] argv array of arguments
226/// @param[in] cnfp reference to configuration pointer
227int my_config(int argc, char * argv[], MyConfig ** cnfp)
228{
229 int c;
230 size_t s;
231 size_t len;
232 int err;
233 int option_index;
234 MyConfig * cnf;
235
236 static char short_options[] = MY_SHORT_OPTIONS;
237 static struct option long_options[] =
238 {
239 {"help", no_argument, 0, 'h'},
240 {"verbose", no_argument, 0, 'v'},
241 {"version", no_argument, 0, 'V'},
242 {NULL, 0, 0, 0 }
243 };
244
245 // allocates memory for configuration
246 if (!(cnf = (MyConfig *) malloc(sizeof(MyConfig))))
247 {
248 fprintf(stderr, "%s: out of virtual memory\n", PROGRAM_NAME);
249 return(1);
250 };
251 memset(cnf, 0, sizeof(MyConfig));
252
253 // initialize ldap utilities
254 if ((err = ldaputils_initialize(&cnf->lud, PROGRAM_NAME)) != LDAP_SUCCESS)
255 {
256 fprintf(stderr, "%s: ldaputils_initialize(): %s\n", PROGRAM_NAME, ldap_err2string(err));
257 my_unbind(cnf);
258 return(1);
259 };
260
261 // loops through args
262 option_index = 0;
263 while((c = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1)
264 {
265 switch(ldaputils_getopt(cnf->lud, c, optarg))
266 {
267 // shared option exit without error
268 case -2:
269 my_unbind(cnf);
270 return(0);
271
272 // no more arguments
273 case -1:
274 break;
275
276 // long options toggles
277 case 0:
278 break;
279
280 // shared option error
281 case 1:
282 my_unbind(cnf);
283 return(1);
284
285 // argument error
286 case '?':
287 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
288 my_unbind(cnf);
289 return(1);
290
291 // unknown argument error
292 default:
293 fprintf(stderr, "%s: unrecognized option `--%c'\n", PROGRAM_NAME, c);
294 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
295 my_unbind(cnf);
296 return(1);
297 };
298 };
299
300 cnf->prog_name = ldaputils_get_prog_name(cnf->lud);
301
302 // checks for required arguments
303 if (argc != optind)
304 {
305 fprintf(stderr, "%s: unknown arguments\n", cnf->prog_name);
306 fprintf(stderr, "Try `%s --help' for more information.\n", cnf->prog_name);
307 my_unbind(cnf);
308 return(1);
309 };
310
311 // saves filter
312 cnf->lud->filter = "(objectclass=*)";
313
314 // configures LDAP attributes to return in results
315 for(len = 0; ((ldapinfo_attrs[len])); len++);
316 if ((cnf->lud->attrs = (char **) malloc(sizeof(char *) * (len+1))) == NULL)
317 {
318 fprintf(stderr, "%s: out of virtual memory\n", cnf->prog_name);
319 my_unbind(cnf);
320 return(1);
321 };
322 bzero(cnf->lud->attrs, sizeof(char *) * (len+1));
323 for(s = 0; s < len; s++)
324 {
325 if ((cnf->lud->attrs[s] = strdup(ldapinfo_attrs[s])) == NULL)
326 {
327 fprintf(stderr, "%s: out of virtual memory\n", cnf->prog_name);
328 my_unbind(cnf);
329 return(1);
330 };
331 };
332 cnf->lud->attrs[s] = NULL;
333
334 // reads password
335 if ((err = ldaputils_pass(cnf->lud)) != 0)
336 {
337 my_unbind(cnf);
338 return(1);
339 };
340
341 *cnfp = cnf;
342
343 return(0);
344}
345
346
347void my_field(const char * name, const char * val)
348{
349 if (!(name))
350 name = "";
351 printf("%-28s %s\n", name, val);
352 return;
353}
354
355
356void my_fields(const char * name, char ** vals)
357{
358 size_t x;
359 if (!(vals))
360 {
361 my_field(name, NULL);
362 return;
363 };
364 my_field(name, vals[0]);
365 for(x = 1; ((vals[x])); x++)
366 my_field(NULL, vals[x]);
367 return;
368}
369
370
371int my_monitor_connections(MyConfig * cnf, const char * base)
372{
373 int rc;
374 int err;
375 int msgid;
376 int count;
377 char ** name;
378 char ** vals;
379 char dn[256];
380 LDAP * ld;
381 LDAPMessage * res;
382 LDAPMessage * msg;
383 struct timeval timeout;
384
385 ld = cnf->lud->ld;
386
387 // searches for cn=Connections,<monitor>
388 timeout.tv_sec = 5;
389 timeout.tv_usec = 0;
390 strncpy(dn, "cn=Connections,", sizeof(dn));
391 strncat(dn, base, (sizeof(dn)-strlen(dn)-1));
392 if ((err = ldap_search_ext(ld, dn, LDAP_SCOPE_ONE, "(objectclass=*)", cnf->lud->attrs, 0, NULL, NULL, &timeout, -1, &msgid)) != LDAP_SUCCESS)
393 return(-1);
394 if ((err = ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, &res)) < 1)
395 return(-1);
396
397 // parses result
398 rc = ldap_parse_result(ld, res, &err, NULL, NULL, NULL, NULL, 0);
399 if ((rc != LDAP_SUCCESS) || (err != LDAP_SUCCESS))
400 {
401 ldap_msgfree(res);
402 return(-1);
403 };
404
405 // retrieves entry
406 count = 0;
407 msg = ldap_first_entry(ld, res);
408 while ((msg))
409 {
410 if ((name = ldap_get_values(ld, msg, "cn")) == NULL)
411 {
412 msg = ldap_next_entry(ld, msg);
413 continue;
414 };
415 if (!(name[0][0]))
416 {
417 ldap_value_free(name);
418 msg = ldap_next_entry(ld, msg);
419 continue;
420 };
421
422 vals = ldap_get_values(ld, msg, "monitorCounter");
423
424 if (!(strcasecmp(name[0], "Current")))
425 my_field("Current connections:", vals[0]);
426 else if (!(strcasecmp(name[0], "Total")))
427 my_field("Total connections:", vals[0]);
428 else if (!(strcasecmp(name[0], "Max File Descriptors")))
429 my_field("Max File Descriptors:", vals[0]);
430
431 if ((name))
432 ldap_value_free(name);
433 if ((vals))
434 ldap_value_free(vals);
435
436 // retrieves next entry
437 msg = ldap_next_entry(ld, msg);
438 };
439
440 printf("\n");
441
442 return(0);
443}
444
445
446int my_monitor_database(MyConfig * cnf, const char * base)
447{
448 int rc;
449 int err;
450 int msgid;
451 int count;
452 size_t s;
453 char ** vals;
454 char dn[256];
455 char buff[256];
456 LDAP * ld;
457 LDAPMessage * res;
458 LDAPMessage * msg;
459 struct timeval timeout;
460
461 ld = cnf->lud->ld;
462
463 // searches for cn=Databases,cn=monitor
464 timeout.tv_sec = 5;
465 timeout.tv_usec = 0;
466 strncpy(dn, "cn=Databases,", sizeof(dn));
467 strncat(dn, base, (sizeof(dn)-strlen(dn)-1));
468 if ((err = ldap_search_ext(ld, dn, LDAP_SCOPE_ONE, "(objectclass=*)", cnf->lud->attrs, 0, NULL, NULL, &timeout, -1, &msgid)) != LDAP_SUCCESS)
469 return(-1);
470 if ((err = ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, &res)) < 1)
471 return(-1);
472
473 // parses result
474 rc = ldap_parse_result(ld, res, &err, NULL, NULL, NULL, NULL, 0);
475 if ((rc != LDAP_SUCCESS) || (err != LDAP_SUCCESS))
476 {
477 ldap_msgfree(res);
478 return(-1);
479 };
480
481 // retrieves entry
482 count = 0;
483 msg = ldap_first_entry(ld, res);
484 while ((msg))
485 {
486 if ((vals = ldap_get_values(ld, msg, "namingContexts")) == NULL)
487 {
488 msg = ldap_next_entry(ld, msg);
489 continue;
490 };
491 if (!(vals[0][0]))
492 {
493 msg = ldap_next_entry(ld, msg);
494 continue;
495 };
496 strncpy(buff, vals[0], sizeof(buff));
497 ldap_value_free(vals);
498
499 if ((vals = ldap_get_values(ld, msg, "monitoredInfo")) != NULL)
500 {
501 strncat(buff, " (", sizeof(buff)-strlen(buff)-1);
502 strncat(buff, vals[0], sizeof(buff)-strlen(buff)-1);
503 strncat(buff, ")", sizeof(buff)-strlen(buff)-1);
504 ldap_value_free(vals);
505 };
506
507 if ((vals = ldap_get_values(ld, msg, "monitorOverlay")) != NULL)
508 {
509 strncat(buff, " [", sizeof(buff)-strlen(buff)-1);
510 for(s = 0; ((vals[s])); s++)
511 {
512 strncat(buff, " ", sizeof(buff)-strlen(buff)-1);
513 strncat(buff, vals[s], sizeof(buff)-strlen(buff)-1);
514 };
515 strncat(buff, " ]", sizeof(buff)-strlen(buff)-1);
516 ldap_value_free(vals);
517 };
518
519 my_field(((count)) ? NULL : "Naming contexts:", buff);
520 count++;
521
522 // retrieves next entry
523 msg = ldap_next_entry(ld, msg);
524 };
525
526 return(0);
527}
528
529
530// parses RootDSE
531int my_rootdse(MyConfig * cnf)
532{
533 int rc;
534 int err;
535 int msgid;
536 size_t s;
537 char ** monitor;
538 char ** vals;
539 char * errmsg;
540 LDAP * ld;
541 LDAPMessage * res;
542 LDAPMessage * msg;
543 struct timeval timeout;
544
545 ld = cnf->lud->ld;
546
547 // searches for RootDSE
548 timeout.tv_sec = 5;
549 timeout.tv_usec = 0;
550 if ((err = ldap_search_ext(ld, "", LDAP_SCOPE_BASE, "(objectclass=*)", cnf->lud->attrs, 0, NULL, NULL, &timeout, -1, &msgid)) != LDAP_SUCCESS)
551 {
552 fprintf(stderr, "%s: ldap_search_ext(): %s\n", cnf->prog_name, ldap_err2string(err));
553 return(-1);
554 };
555 switch((err = ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, &res)))
556 {
557 case 0:
558 fprintf(stderr, "%s: ldap_search_ext(): operation timed out\n", cnf->prog_name);
559 return(-1);
560
561 case -1:
562 ldap_get_option(ld, LDAP_OPT_ERROR, &err);
563 fprintf(stderr, "%s: ldap_result(): %s\n", cnf->prog_name, ldap_err2string(err));
564 return(-1);
565
566 default:
567 break;
568 };
569
570 // parses result
571 rc = ldap_parse_result(ld, res, &err, NULL, &errmsg, NULL, NULL, 0);
572 if (rc != LDAP_SUCCESS)
573 {
574 fprintf(stderr, "%s: ldap_parse_result(): %s\n", cnf->prog_name, ldap_err2string(rc));
575 ldap_msgfree(res);
576 return(-1);
577 };
578 if (err != LDAP_SUCCESS)
579 {
580 fprintf(stderr, "%s: ldap_parse_result(): %s\n", cnf->prog_name, errmsg);
581 ldap_memfree(errmsg);
582 ldap_msgfree(res);
583 return(-1);
584 };
585
586 // retrieves entry
587 msg = ldap_first_entry(ld, res);
588
589 // obtain vendor name and version
590 if ((vals = ldap_get_values(ld, msg, "vendorName")) != NULL)
591 {
592 my_fields("Vendor name:", vals);
593 ldap_value_free(vals);
594 }
595 else if ((vals = ldap_get_values(ld, msg, "isGlobalCatalogReady")) != NULL)
596 {
597 my_field("Vendor name:", "Microsoft Active Directory");
598 ldap_value_free(vals);
599 }
600 else if ((vals = ldap_get_values(ld, msg, "objectClass")) != NULL)
601 {
602 for(s = 0; ((vals[s])); s++)
603 if (!(strcasecmp(vals[s], "OpenLDAProotDSE")))
604 my_field("Vendor name:", "OpenLDAP");
605 ldap_value_free(vals);
606 };
607 if ((vals = ldap_get_values(ld, msg, "vendorVersion")) != NULL)
608 {
609 my_fields("Vendor version:", vals);
610 ldap_value_free(vals);
611 };
612 if ((vals = ldap_get_values(ld, msg, "supportedLDAPVersion")) != NULL)
613 {
614 my_fields("LDAP version:", vals);
615 ldap_value_free(vals);
616 };
617
618 // DNs
619 if ((vals = ldap_get_values(ld, msg, "subschemaSubentry")) != NULL)
620 {
621 my_fields("Subschema Subentry:", vals);
622 ldap_value_free(vals);
623 };
624 if ((vals = ldap_get_values(ld, msg, "configContext")) != NULL)
625 {
626 my_fields("Configuration context:", vals);
627 ldap_value_free(vals);
628 };
629 if ((monitor = ldap_get_values(ld, msg, "monitorContext")) != NULL)
630 my_fields("Monitoring context:", monitor);
631 printf("\n");
632
633 // connection stats
634 if ((monitor))
635 my_monitor_connections(cnf, monitor[0]);
636
637 // obtain naming contexts
638 vals = ldap_get_values(ld, msg, "namingContexts");
639 if ((monitor))
640 {
641 if ((rc = my_monitor_database(cnf, monitor[0])) == -1)
642 my_fields("Naming contexts:", vals);
643 printf("\n");
644 }
645 else
646 {
647 my_fields("Naming contexts:", vals);
648 printf("\n");
649 };
650
651 if ((monitor))
652 ldap_value_free(monitor);
653
654 // obtain supported controls
655 if ((vals = ldap_get_values(ld, msg, "supportedControl")) != NULL)
656 {
657 my_fields("Supported controls:", vals);
658 printf("\n");
659 ldap_value_free(vals);
660 };
661
662 // obtain supported extension
663 if ((vals = ldap_get_values(ld, msg, "supportedExtension")) != NULL)
664 {
665 my_fields("Supported extension:", vals);
666 printf("\n");
667 ldap_value_free(vals);
668 };
669
670 // obtain supported features
671 if ((vals = ldap_get_values(ld, msg, "supportedFeatures")) != NULL)
672 {
673 my_fields("Supported features:", vals);
674 printf("\n");
675 ldap_value_free(vals);
676 };
677
678 // obtain supported SASL mechanisms
679 if ((vals = ldap_get_values(ld, msg, "supportedSASLMechanisms")) != NULL)
680 {
681 my_fields("Supported SASL mechanisms:", vals);
682 printf("\n");
683 ldap_value_free(vals);
684 };
685
686 // frees response
687 ldap_msgfree(res);
688
689 return(0);
690}
691
692
693// fress resources
694void my_unbind(MyConfig * cnf)
695{
696 assert(cnf != NULL);
697
698 if ((cnf->lud))
699 ldaputils_unbind(cnf->lud);
700
701 if ((cnf->defvals))
702 free(cnf->defvals);
703
704 free(cnf);
705
706 return;
707}
708
709/* end of source file */