diff options
| author | David M. Syzdek <david@syzdek.net> | 2023-01-26 16:33:09 -0900 |
|---|---|---|
| committer | David M. Syzdek <david@syzdek.net> | 2023-01-26 16:33:09 -0900 |
| commit | 2602fb49bb4e48deedce78e05436369acf4206fb (patch) | |
| tree | ad9c76226f1f29f6b116cbe5c8c2d7352d7030cc | |
| parent | bbf101986b128d1fcaceb3ac92d9fbbf243ca6a3 (diff) | |
| download | ldap-utils-2602fb49bb4e48deedce78e05436369acf4206fb.tar.gz ldap-utils-2602fb49bb4e48deedce78e05436369acf4206fb.tar.bz2 ldap-utils-2602fb49bb4e48deedce78e05436369acf4206fb.tar.xz ldap-utils-2602fb49bb4e48deedce78e05436369acf4206fb.zip | |
ldapconns: adding program
| -rw-r--r-- | Makefile.am | 12 | ||||
| -rw-r--r-- | acinclude.m4 | 31 | ||||
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | src/ldapconns.c | 697 |
4 files changed, 742 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index d19ac51..6d13c97 100644 --- a/Makefile.am +++ b/Makefile.am | |||
| @@ -304,6 +304,18 @@ src_ldapdn2str_LDADD = $(AM_LDADD) -lldap -llber lib/libldaputils.a | |||
| 304 | src_ldapdn2str_SOURCES = src/ldapdn2str.c | 304 | src_ldapdn2str_SOURCES = src/ldapdn2str.c |
| 305 | 305 | ||
| 306 | 306 | ||
| 307 | # macros for src/ldapconns | ||
| 308 | if LDAPUTILS_LDAPCONNS | ||
| 309 | bin_PROGRAMS += src/ldapconns | ||
| 310 | endif | ||
| 311 | src_ldapconns_DEPENDENCIES = Makefile lib/libldaputils.a lib/libldapschema.a | ||
| 312 | src_ldapconns_CPPFLAGS = -DPROGRAM_NAME="\"ldapconns\"" $(AM_CPPFLAGS) | ||
| 313 | src_ldapconns_CFLAGS = $(AM_CFLAGS) | ||
| 314 | src_ldapconns_LDFLAGS = $(AM_LDFLAGS) | ||
| 315 | src_ldapconns_LDADD = $(AM_LDADD) -lldap -llber lib/libldaputils.a lib/libldapschema.a | ||
| 316 | src_ldapconns_SOURCES = src/ldapconns.c | ||
| 317 | |||
| 318 | |||
| 307 | # macros for src/ldapinfo | 319 | # macros for src/ldapinfo |
| 308 | if LDAPUTILS_LDAPINFO | 320 | if LDAPUTILS_LDAPINFO |
| 309 | bin_PROGRAMS += src/ldapinfo | 321 | bin_PROGRAMS += src/ldapinfo |
diff --git a/acinclude.m4 b/acinclude.m4 index ce12549..b08c6b1 100644 --- a/acinclude.m4 +++ b/acinclude.m4 | |||
| @@ -121,6 +121,36 @@ AC_DEFUN_ONCE([AC_LDAP_UTILS_LDAP2JSON],[dnl | |||
| 121 | ])dnl | 121 | ])dnl |
| 122 | 122 | ||
| 123 | 123 | ||
| 124 | # AC_LDAP_UTILS_LDAPCONNS | ||
| 125 | # ______________________________________________________________________________ | ||
| 126 | AC_DEFUN_ONCE([AC_LDAP_UTILS_LDAPCONNS],[dnl | ||
| 127 | |||
| 128 | # prerequists | ||
| 129 | AC_REQUIRE([AC_LDAP_UTILS_UTILITIES]) | ||
| 130 | |||
| 131 | enableval="" | ||
| 132 | AC_ARG_ENABLE( | ||
| 133 | ldapconns, | ||
| 134 | [AS_HELP_STRING([--disable-ldapconns], [disable building ldapconns utility])], | ||
| 135 | [ ELDAPCONNS=$enableval ], | ||
| 136 | [ ELDAPCONNS=$enableval ] | ||
| 137 | ) | ||
| 138 | |||
| 139 | if test "x${ELDAPCONNS}" != "x${LDAPUTILS_UTILITIES_ALT}";then | ||
| 140 | ELDAPCONNS=${LDAPUTILS_UTILITIES} | ||
| 141 | fi | ||
| 142 | LDAPUTILS_LDAPCONNS=${ELDAPCONNS} | ||
| 143 | |||
| 144 | LDAPUTILS_LDAPCONNS_STATUS="skip" | ||
| 145 | if test "x${ELDAPCONNS}" == "xyes";then | ||
| 146 | LDAPUTILS_LDAPCONNS_STATUS="install" | ||
| 147 | LDAPUTILS_LIBLDAPUTILS="yes" | ||
| 148 | fi | ||
| 149 | |||
| 150 | AM_CONDITIONAL([LDAPUTILS_LDAPCONNS], [test "x$LDAPUTILS_LDAPCONNS" = "xyes"]) | ||
| 151 | ])dnl | ||
| 152 | |||
| 153 | |||
| 124 | # AC_LDAP_UTILS_LDAPDEBUG | 154 | # AC_LDAP_UTILS_LDAPDEBUG |
| 125 | # ______________________________________________________________________________ | 155 | # ______________________________________________________________________________ |
| 126 | AC_DEFUN_ONCE([AC_LDAP_UTILS_LDAPDEBUG],[dnl | 156 | AC_DEFUN_ONCE([AC_LDAP_UTILS_LDAPDEBUG],[dnl |
| @@ -318,6 +348,7 @@ AC_DEFUN_ONCE([AC_LDAP_UTILS_LIBLDAPUTILS],[dnl | |||
| 318 | 348 | ||
| 319 | AC_REQUIRE([AC_LDAP_UTILS_LDAP2CSV]) | 349 | AC_REQUIRE([AC_LDAP_UTILS_LDAP2CSV]) |
| 320 | AC_REQUIRE([AC_LDAP_UTILS_LDAP2JSON]) | 350 | AC_REQUIRE([AC_LDAP_UTILS_LDAP2JSON]) |
| 351 | AC_REQUIRE([AC_LDAP_UTILS_LDAPCONNS]) | ||
| 321 | AC_REQUIRE([AC_LDAP_UTILS_LDAPDEBUG]) | 352 | AC_REQUIRE([AC_LDAP_UTILS_LDAPDEBUG]) |
| 322 | AC_REQUIRE([AC_LDAP_UTILS_LDAPDN2STR]) | 353 | AC_REQUIRE([AC_LDAP_UTILS_LDAPDN2STR]) |
| 323 | AC_REQUIRE([AC_LDAP_UTILS_LDAPINFO]) | 354 | AC_REQUIRE([AC_LDAP_UTILS_LDAPINFO]) |
diff --git a/configure.ac b/configure.ac index 8a809dc..5609347 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -199,6 +199,7 @@ AC_LDAP_UTILS_LIBLDAPSCHEMA | |||
| 199 | AC_LDAP_UTILS_LIBLDAPUTILS | 199 | AC_LDAP_UTILS_LIBLDAPUTILS |
| 200 | AC_LDAP_UTILS_LDAP2CSV | 200 | AC_LDAP_UTILS_LDAP2CSV |
| 201 | AC_LDAP_UTILS_LDAP2JSON | 201 | AC_LDAP_UTILS_LDAP2JSON |
| 202 | AC_LDAP_UTILS_LDAPCONNS | ||
| 202 | AC_LDAP_UTILS_LDAPDEBUG | 203 | AC_LDAP_UTILS_LDAPDEBUG |
| 203 | AC_LDAP_UTILS_LDAPDN2STR | 204 | AC_LDAP_UTILS_LDAPDN2STR |
| 204 | AC_LDAP_UTILS_LDAPINFO | 205 | AC_LDAP_UTILS_LDAPINFO |
| @@ -228,6 +229,7 @@ AC_MSG_NOTICE([ ]) | |||
| 228 | AC_MSG_NOTICE([ Utilities:]) | 229 | AC_MSG_NOTICE([ Utilities:]) |
| 229 | AC_MSG_NOTICE([ ldap2csv $LDAPUTILS_LDAP2CSV_STATUS]) | 230 | AC_MSG_NOTICE([ ldap2csv $LDAPUTILS_LDAP2CSV_STATUS]) |
| 230 | AC_MSG_NOTICE([ ldap2json $LDAPUTILS_LDAP2JSON_STATUS]) | 231 | AC_MSG_NOTICE([ ldap2json $LDAPUTILS_LDAP2JSON_STATUS]) |
| 232 | AC_MSG_NOTICE([ ldapconns $LDAPUTILS_LDAPCONNS_STATUS]) | ||
| 231 | AC_MSG_NOTICE([ ldapdebug $LDAPUTILS_LDAPDEBUG_STATUS]) | 233 | AC_MSG_NOTICE([ ldapdebug $LDAPUTILS_LDAPDEBUG_STATUS]) |
| 232 | AC_MSG_NOTICE([ ldapdn2str $LDAPUTILS_LDAPDN2STR_STATUS]) | 234 | AC_MSG_NOTICE([ ldapdn2str $LDAPUTILS_LDAPDN2STR_STATUS]) |
| 233 | AC_MSG_NOTICE([ ldapinfo $LDAPUTILS_LDAPINFO_STATUS]) | 235 | AC_MSG_NOTICE([ ldapinfo $LDAPUTILS_LDAPINFO_STATUS]) |
diff --git a/src/ldapconns.c b/src/ldapconns.c new file mode 100644 index 0000000..884d694 --- /dev/null +++ b/src/ldapconns.c | |||
| @@ -0,0 +1,697 @@ | |||
| 1 | /* | ||
| 2 | * LDAP Utilities | ||
| 3 | * Copyright (C) 2023 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/ldapconns.c export LDAP data to CSV file | ||
| 34 | */ | ||
| 35 | /* | ||
| 36 | * Simple Build: | ||
| 37 | * export CFLAGS='-DPROGRAM_NAME="ldapconns" -Wall -I../include' | ||
| 38 | * gcc ${CFLAGS} -c ldapconns.c | ||
| 39 | * gcc ${CFLAGS} -lldap -o ldapconns ldapconns.o ../lib/libldaputils.a | ||
| 40 | * | ||
| 41 | * Libtool Build: | ||
| 42 | * export CFLAGS='-DPROGRAM_NAME="ldapconns" -Wall -I../include' | ||
| 43 | * libtool --mode=compile --tag=CC gcc ${CFLAGS} -c ldapconns.c | ||
| 44 | * libtool --mode=link --tag=CC gcc ${CFLAGS} -lldap -o ldapconns \ | ||
| 45 | * ldapconns.lo ../lib/libldaputils.a | ||
| 46 | * | ||
| 47 | * Libtool Clean: | ||
| 48 | * libtool --mode=clean rm -f ldapconns.lo ldapconns | ||
| 49 | */ | ||
| 50 | #define _LDAP_UTILS_SRC_LDAPCONNS 1 | ||
| 51 | |||
| 52 | /////////////// | ||
| 53 | // // | ||
| 54 | // Headers // | ||
| 55 | // // | ||
| 56 | /////////////// | ||
| 57 | #pragma mark - Headers | ||
| 58 | |||
| 59 | #define _GNU_SOURCE 1 | ||
| 60 | #include <stdio.h> | ||
| 61 | #include <stdlib.h> | ||
| 62 | #include <unistd.h> | ||
| 63 | #include <string.h> | ||
| 64 | #include <strings.h> | ||
| 65 | #include <time.h> | ||
| 66 | #include <getopt.h> | ||
| 67 | #include <assert.h> | ||
| 68 | |||
| 69 | #define LDAP_DEPRECATED 1 | ||
| 70 | #include <ldap.h> | ||
| 71 | #include <ldaputils.h> | ||
| 72 | #include <ldapschema.h> | ||
| 73 | |||
| 74 | |||
| 75 | /////////////////// | ||
| 76 | // // | ||
| 77 | // Definitions // | ||
| 78 | // // | ||
| 79 | /////////////////// | ||
| 80 | #pragma mark - Definitions | ||
| 81 | |||
| 82 | #ifndef PROGRAM_NAME | ||
| 83 | #define PROGRAM_NAME "ldapconns" | ||
| 84 | #endif | ||
| 85 | |||
| 86 | #define MY_SHORT_OPTIONS LDAPUTILS_OPTIONS_COMMON LDAPUTILS_OPTIONS_SEARCH "o:" | ||
| 87 | |||
| 88 | |||
| 89 | ///////////////// | ||
| 90 | // // | ||
| 91 | // Datatypes // | ||
| 92 | // // | ||
| 93 | ///////////////// | ||
| 94 | #pragma mark - Datatypes | ||
| 95 | |||
| 96 | typedef struct my_record MyRec; | ||
| 97 | struct my_record | ||
| 98 | { | ||
| 99 | unsigned rec_num; | ||
| 100 | unsigned rec_proto; | ||
| 101 | unsigned rec_ops_recv; | ||
| 102 | unsigned rec_ops_exec; | ||
| 103 | unsigned rec_ops_pend; | ||
| 104 | unsigned rec_ops_comp; | ||
| 105 | char ** rec_mask; | ||
| 106 | char ** rec_authzdn; | ||
| 107 | char ** rec_listener; | ||
| 108 | char ** rec_peer; | ||
| 109 | char ** rec_local; | ||
| 110 | char ** rec_start; | ||
| 111 | char ** rec_activity; | ||
| 112 | }; | ||
| 113 | |||
| 114 | |||
| 115 | // configuration union | ||
| 116 | typedef struct my_config MyConfig; | ||
| 117 | struct my_config | ||
| 118 | { | ||
| 119 | size_t recs_len; | ||
| 120 | LDAPUtils * lud; | ||
| 121 | const char * filter; | ||
| 122 | const char * prog_name; | ||
| 123 | const char ** defvals; | ||
| 124 | char ** monitor; | ||
| 125 | MyRec ** recs; | ||
| 126 | char output[LDAPUTILS_OPT_LEN]; | ||
| 127 | }; | ||
| 128 | |||
| 129 | |||
| 130 | ///////////////// | ||
| 131 | // // | ||
| 132 | // Variables // | ||
| 133 | // // | ||
| 134 | ///////////////// | ||
| 135 | #pragma mark - Variables | ||
| 136 | |||
| 137 | static const char * ldapinfo_attrs[] = | ||
| 138 | { | ||
| 139 | "cn", | ||
| 140 | "monitorConnectionNumber", | ||
| 141 | "monitorConnectionProtocol", | ||
| 142 | "monitorConnectionOpsReceived", | ||
| 143 | "monitorConnectionOpsExecuting", | ||
| 144 | "monitorConnectionOpsPending", | ||
| 145 | "monitorConnectionOpsCompleted", | ||
| 146 | "monitorConnectionGet", | ||
| 147 | "monitorConnectionRead", | ||
| 148 | "monitorConnectionWrite", | ||
| 149 | "monitorConnectionMask", | ||
| 150 | "monitorConnectionAuthzDN", | ||
| 151 | "monitorConnectionListener", | ||
| 152 | "monitorConnectionPeerAddress", | ||
| 153 | "monitorConnectionLocalAddress", | ||
| 154 | "monitorConnectionStartTime", | ||
| 155 | "monitorConnectionActivityTime", | ||
| 156 | "monitorContext", | ||
| 157 | "objectclass", | ||
| 158 | NULL | ||
| 159 | }; | ||
| 160 | |||
| 161 | |||
| 162 | ////////////////// | ||
| 163 | // // | ||
| 164 | // Prototypes // | ||
| 165 | // // | ||
| 166 | ////////////////// | ||
| 167 | #pragma mark - Prototypes | ||
| 168 | |||
| 169 | // main statement | ||
| 170 | extern int | ||
| 171 | main( | ||
| 172 | int argc, | ||
| 173 | char * argv[] ); | ||
| 174 | |||
| 175 | |||
| 176 | // parses configuration | ||
| 177 | static int | ||
| 178 | my_config( | ||
| 179 | int argc, | ||
| 180 | char * argv[], | ||
| 181 | MyConfig ** cnfp ); | ||
| 182 | |||
| 183 | |||
| 184 | static int | ||
| 185 | my_field_len( | ||
| 186 | int len, | ||
| 187 | char ** val_str, | ||
| 188 | unsigned val_num ); | ||
| 189 | |||
| 190 | |||
| 191 | static int | ||
| 192 | my_monitor_connections( | ||
| 193 | MyConfig * cnf, | ||
| 194 | const char * base ); | ||
| 195 | |||
| 196 | |||
| 197 | // parses RootDSE | ||
| 198 | static int | ||
| 199 | my_rootdse( | ||
| 200 | MyConfig * cnf ); | ||
| 201 | |||
| 202 | |||
| 203 | // fress resources | ||
| 204 | static void | ||
| 205 | my_unbind( | ||
| 206 | MyConfig * cnf ); | ||
| 207 | |||
| 208 | |||
| 209 | ///////////////// | ||
| 210 | // // | ||
| 211 | // Functions // | ||
| 212 | // // | ||
| 213 | ///////////////// | ||
| 214 | #pragma mark - Functions | ||
| 215 | |||
| 216 | void | ||
| 217 | ldaputils_usage( | ||
| 218 | void ) | ||
| 219 | { | ||
| 220 | printf("Usage: %s [options]\n", PROGRAM_NAME); | ||
| 221 | ldaputils_usage_common(MY_SHORT_OPTIONS); | ||
| 222 | printf("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT); | ||
| 223 | return; | ||
| 224 | } | ||
| 225 | |||
| 226 | |||
| 227 | int | ||
| 228 | main( | ||
| 229 | int argc, | ||
| 230 | char * argv[] ) | ||
| 231 | { | ||
| 232 | int err; | ||
| 233 | MyConfig * cnf; | ||
| 234 | |||
| 235 | cnf = NULL; | ||
| 236 | |||
| 237 | // initializes resources and parses CLI arguments | ||
| 238 | if ((err = my_config(argc, argv, &cnf)) != 0) | ||
| 239 | return(1); | ||
| 240 | if (!(cnf)) | ||
| 241 | return(0); | ||
| 242 | |||
| 243 | // starts TLS and binds to LDAP | ||
| 244 | if ((err = ldaputils_bind_s(cnf->lud)) != LDAP_SUCCESS) | ||
| 245 | { | ||
| 246 | fprintf(stderr, "%s: ldap_sasl_bind_s(): %s\n", ldaputils_get_prog_name(cnf->lud), ldap_err2string(err)); | ||
| 247 | my_unbind(cnf); | ||
| 248 | return(1); | ||
| 249 | }; | ||
| 250 | |||
| 251 | // processes root DSE | ||
| 252 | if ((err = my_rootdse(cnf)) == -1) | ||
| 253 | { | ||
| 254 | my_unbind(cnf); | ||
| 255 | return(1); | ||
| 256 | }; | ||
| 257 | if (!(cnf->monitor)) | ||
| 258 | { | ||
| 259 | fprintf(stderr, "%s: unable to determine monitoring context\n", ldaputils_get_prog_name(cnf->lud)); | ||
| 260 | my_unbind(cnf); | ||
| 261 | return(1); | ||
| 262 | }; | ||
| 263 | |||
| 264 | my_unbind(cnf); | ||
| 265 | |||
| 266 | return(0); | ||
| 267 | } | ||
| 268 | |||
| 269 | |||
| 270 | int | ||
| 271 | my_config( | ||
| 272 | int argc, | ||
| 273 | char * argv[], | ||
| 274 | MyConfig ** cnfp ) | ||
| 275 | { | ||
| 276 | int c; | ||
| 277 | size_t s; | ||
| 278 | size_t len; | ||
| 279 | int err; | ||
| 280 | int option_index; | ||
| 281 | MyConfig * cnf; | ||
| 282 | |||
| 283 | static char short_options[] = MY_SHORT_OPTIONS; | ||
| 284 | static struct option long_options[] = | ||
| 285 | { | ||
| 286 | {"help", no_argument, 0, 'h'}, | ||
| 287 | {"verbose", no_argument, 0, 'v'}, | ||
| 288 | {"version", no_argument, 0, 'V'}, | ||
| 289 | {NULL, 0, 0, 0 } | ||
| 290 | }; | ||
| 291 | |||
| 292 | // allocates memory for configuration | ||
| 293 | if (!(cnf = (MyConfig *) malloc(sizeof(MyConfig)))) | ||
| 294 | { | ||
| 295 | fprintf(stderr, "%s: out of virtual memory\n", PROGRAM_NAME); | ||
| 296 | return(1); | ||
| 297 | }; | ||
| 298 | memset(cnf, 0, sizeof(MyConfig)); | ||
| 299 | |||
| 300 | // initialize ldap utilities | ||
| 301 | if ((err = ldaputils_initialize(&cnf->lud, PROGRAM_NAME)) != LDAP_SUCCESS) | ||
| 302 | { | ||
| 303 | fprintf(stderr, "%s: ldaputils_initialize(): %s\n", PROGRAM_NAME, ldap_err2string(err)); | ||
| 304 | my_unbind(cnf); | ||
| 305 | return(1); | ||
| 306 | }; | ||
| 307 | |||
| 308 | // loops through args | ||
| 309 | option_index = 0; | ||
| 310 | while((c = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1) | ||
| 311 | { | ||
| 312 | switch(ldaputils_getopt(cnf->lud, c, optarg)) | ||
| 313 | { | ||
| 314 | // shared option exit without error | ||
| 315 | case -2: | ||
| 316 | my_unbind(cnf); | ||
| 317 | return(0); | ||
| 318 | |||
| 319 | // no more arguments | ||
| 320 | case -1: | ||
| 321 | break; | ||
| 322 | |||
| 323 | // long options toggles | ||
| 324 | case 0: | ||
| 325 | break; | ||
| 326 | |||
| 327 | // shared option error | ||
| 328 | case 1: | ||
| 329 | my_unbind(cnf); | ||
| 330 | return(1); | ||
| 331 | |||
| 332 | // argument error | ||
| 333 | case '?': | ||
| 334 | fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME); | ||
| 335 | my_unbind(cnf); | ||
| 336 | return(1); | ||
| 337 | |||
| 338 | // unknown argument error | ||
| 339 | default: | ||
| 340 | fprintf(stderr, "%s: unrecognized option `--%c'\n", PROGRAM_NAME, c); | ||
| 341 | fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME); | ||
| 342 | my_unbind(cnf); | ||
| 343 | return(1); | ||
| 344 | }; | ||
| 345 | }; | ||
| 346 | |||
| 347 | cnf->prog_name = ldaputils_get_prog_name(cnf->lud); | ||
| 348 | |||
| 349 | // checks for required arguments | ||
| 350 | if (argc != optind) | ||
| 351 | { | ||
| 352 | fprintf(stderr, "%s: unknown arguments\n", cnf->prog_name); | ||
| 353 | fprintf(stderr, "Try `%s --help' for more information.\n", cnf->prog_name); | ||
| 354 | my_unbind(cnf); | ||
| 355 | return(1); | ||
| 356 | }; | ||
| 357 | |||
| 358 | // saves filter | ||
| 359 | cnf->lud->filter = "(objectclass=*)"; | ||
| 360 | |||
| 361 | // configures LDAP attributes to return in results | ||
| 362 | for(len = 0; ((ldapinfo_attrs[len])); len++); | ||
| 363 | if ((cnf->lud->attrs = (char **) malloc(sizeof(char *) * (len+1))) == NULL) | ||
| 364 | { | ||
| 365 | fprintf(stderr, "%s: out of virtual memory\n", cnf->prog_name); | ||
| 366 | my_unbind(cnf); | ||
| 367 | return(1); | ||
| 368 | }; | ||
| 369 | bzero(cnf->lud->attrs, sizeof(char *) * (len+1)); | ||
| 370 | for(s = 0; s < len; s++) | ||
| 371 | { | ||
| 372 | if ((cnf->lud->attrs[s] = strdup(ldapinfo_attrs[s])) == NULL) | ||
| 373 | { | ||
| 374 | fprintf(stderr, "%s: out of virtual memory\n", cnf->prog_name); | ||
| 375 | my_unbind(cnf); | ||
| 376 | return(1); | ||
| 377 | }; | ||
| 378 | }; | ||
| 379 | cnf->lud->attrs[s] = NULL; | ||
| 380 | |||
| 381 | // reads password | ||
| 382 | if ((err = ldaputils_pass(cnf->lud)) != 0) | ||
| 383 | { | ||
| 384 | my_unbind(cnf); | ||
| 385 | return(1); | ||
| 386 | }; | ||
| 387 | |||
| 388 | *cnfp = cnf; | ||
| 389 | |||
| 390 | return(0); | ||
| 391 | } | ||
| 392 | |||
| 393 | |||
| 394 | int | ||
| 395 | my_monitor_connections( | ||
| 396 | MyConfig * cnf, | ||
| 397 | const char * base ) | ||
| 398 | { | ||
| 399 | int rc; | ||
| 400 | int err; | ||
| 401 | int msgid; | ||
| 402 | int count; | ||
| 403 | char ** vals; | ||
| 404 | char dn[256]; | ||
| 405 | char ops[128]; | ||
| 406 | char * conn_local; | ||
| 407 | char * conn_peer; | ||
| 408 | char * str; | ||
| 409 | LDAP * ld; | ||
| 410 | LDAPMessage * res; | ||
| 411 | LDAPMessage * msg; | ||
| 412 | struct timeval timeout; | ||
| 413 | MyRec * rec; | ||
| 414 | void * ptr; | ||
| 415 | size_t pos; | ||
| 416 | int len_listener; | ||
| 417 | int len_local; | ||
| 418 | int len_peer; | ||
| 419 | int len_proto; | ||
| 420 | int len_mask; | ||
| 421 | int len_start; | ||
| 422 | int len_activity; | ||
| 423 | int len_ops; | ||
| 424 | int len_ops_recv; | ||
| 425 | int len_ops_exec; | ||
| 426 | int len_ops_pend; | ||
| 427 | int len_ops_comp; | ||
| 428 | |||
| 429 | ld = cnf->lud->ld; | ||
| 430 | |||
| 431 | // searches for cn=Connections,<monitor> | ||
| 432 | timeout.tv_sec = 5; | ||
| 433 | timeout.tv_usec = 0; | ||
| 434 | strncpy(dn, "cn=Connections,", sizeof(dn)); | ||
| 435 | strncat(dn, base, (sizeof(dn)-strlen(dn)-1)); | ||
| 436 | if ((err = ldap_search_ext(ld, dn, LDAP_SCOPE_ONE, "(objectclass=*)", cnf->lud->attrs, 0, NULL, NULL, &timeout, -1, &msgid)) != LDAP_SUCCESS) | ||
| 437 | return(-1); | ||
| 438 | if ((err = ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, &res)) < 1) | ||
| 439 | return(-1); | ||
| 440 | |||
| 441 | // parses result | ||
| 442 | rc = ldap_parse_result(ld, res, &err, NULL, NULL, NULL, NULL, 0); | ||
| 443 | if ((rc != LDAP_SUCCESS) || (err != LDAP_SUCCESS)) | ||
| 444 | { | ||
| 445 | ldap_msgfree(res); | ||
| 446 | return(-1); | ||
| 447 | }; | ||
| 448 | |||
| 449 | // retrieves entry | ||
| 450 | count = 0; | ||
| 451 | msg = ldap_first_entry(ld, res); | ||
| 452 | while ((msg)) | ||
| 453 | { | ||
| 454 | // skip entry if not a connection | ||
| 455 | if ((vals = ldap_get_values(ld, msg, "monitorConnectionNumber")) == NULL) | ||
| 456 | { | ||
| 457 | msg = ldap_next_entry(ld, msg); | ||
| 458 | continue; | ||
| 459 | }; | ||
| 460 | |||
| 461 | // allocate memory for records | ||
| 462 | if ((ptr = realloc(cnf->recs, (sizeof(MyRec *)*(cnf->recs_len+1)))) == NULL) | ||
| 463 | return(-1); | ||
| 464 | cnf->recs = ptr; | ||
| 465 | if ((cnf->recs[cnf->recs_len] = malloc(sizeof(MyRec))) == NULL) | ||
| 466 | return(-1); | ||
| 467 | memset(cnf->recs[cnf->recs_len], 0, sizeof(MyRec)); | ||
| 468 | rec = cnf->recs[cnf->recs_len]; | ||
| 469 | cnf->recs_len++; | ||
| 470 | |||
| 471 | // process monitorConnectionNumber | ||
| 472 | rec->rec_num = (unsigned)strtoull(vals[0], NULL, 10); | ||
| 473 | ldap_value_free(vals); | ||
| 474 | |||
| 475 | // process values | ||
| 476 | if ((vals = ldap_get_values(ld, msg, "monitorConnectionProtocol")) != NULL) | ||
| 477 | { | ||
| 478 | rec->rec_proto = (unsigned)strtoull(vals[0], NULL, 10); | ||
| 479 | ldap_value_free(vals); | ||
| 480 | }; | ||
| 481 | if ((vals = ldap_get_values(ld, msg, "monitorConnectionOpsReceived")) != NULL) | ||
| 482 | { | ||
| 483 | rec->rec_ops_recv = (unsigned)strtoull(vals[0], NULL, 10); | ||
| 484 | ldap_value_free(vals); | ||
| 485 | }; | ||
| 486 | if ((vals = ldap_get_values(ld, msg, "monitorConnectionOpsExecuting")) != NULL) | ||
| 487 | { | ||
| 488 | rec->rec_ops_exec = (unsigned)strtoull(vals[0], NULL, 10); | ||
| 489 | ldap_value_free(vals); | ||
| 490 | }; | ||
| 491 | if ((vals = ldap_get_values(ld, msg, "monitorConnectionOpsPending")) != NULL) | ||
| 492 | { | ||
| 493 | rec->rec_ops_pend = (unsigned)strtoull(vals[0], NULL, 10); | ||
| 494 | ldap_value_free(vals); | ||
| 495 | }; | ||
| 496 | if ((vals = ldap_get_values(ld, msg, "monitorConnectionOpsCompleted")) != NULL) | ||
| 497 | { | ||
| 498 | rec->rec_ops_comp = (unsigned)strtoull(vals[0], NULL, 10); | ||
| 499 | ldap_value_free(vals); | ||
| 500 | }; | ||
| 501 | rec->rec_mask = ldap_get_values(ld, msg, "monitorConnectionMask"); | ||
| 502 | rec->rec_authzdn = ldap_get_values(ld, msg, "monitorConnectionAuthzDN"); | ||
| 503 | rec->rec_listener = ldap_get_values(ld, msg, "monitorConnectionListener"); | ||
| 504 | rec->rec_peer = ldap_get_values(ld, msg, "monitorConnectionPeerAddress"); | ||
| 505 | rec->rec_local = ldap_get_values(ld, msg, "monitorConnectionLocalAddress"); | ||
| 506 | rec->rec_start = ldap_get_values(ld, msg, "monitorConnectionStartTime"); | ||
| 507 | rec->rec_activity = ldap_get_values(ld, msg, "monitorConnectionActivityTime"); | ||
| 508 | |||
| 509 | // retrieves next entry | ||
| 510 | msg = ldap_next_entry(ld, msg); | ||
| 511 | }; | ||
| 512 | |||
| 513 | str = ops; | ||
| 514 | len_listener = (int)strlen("Listener"); | ||
| 515 | len_proto = (int)strlen(" "); | ||
| 516 | len_mask = (int)strlen("Mask"); | ||
| 517 | len_local = (int)strlen("Local"); | ||
| 518 | len_peer = (int)strlen("Peer"); | ||
| 519 | len_start = (int)strlen("Start"); | ||
| 520 | len_activity = (int)strlen("Last Activity"); | ||
| 521 | len_ops = (int)strlen("Ops R/E/P/C"); | ||
| 522 | len_ops_recv = (int)strlen("OpsRecv"); | ||
| 523 | len_ops_exec = (int)strlen("OpsExec"); | ||
| 524 | len_ops_pend = (int)strlen("OpsPend"); | ||
| 525 | len_ops_comp = (int)strlen("OpsCmplt"); | ||
| 526 | for(pos = 0; (pos < cnf->recs_len); pos++) | ||
| 527 | { | ||
| 528 | if (!(cnf->recs[pos]->rec_proto)) | ||
| 529 | continue; | ||
| 530 | conn_peer = strrchr(cnf->recs[pos]->rec_peer[0], '='); | ||
| 531 | conn_peer = ((conn_peer)) ? &conn_peer[1] : cnf->recs[pos]->rec_peer[0]; | ||
| 532 | conn_local = strrchr(cnf->recs[pos]->rec_local[0], '='); | ||
| 533 | conn_local = ((conn_local)) ? &conn_local[1] : cnf->recs[pos]->rec_local[0]; | ||
| 534 | snprintf(ops, sizeof(ops), "%i/%i/%i/%i", | ||
| 535 | cnf->recs[pos]->rec_ops_recv, | ||
| 536 | cnf->recs[pos]->rec_ops_exec, | ||
| 537 | cnf->recs[pos]->rec_ops_pend, | ||
| 538 | cnf->recs[pos]->rec_ops_comp | ||
| 539 | ); | ||
| 540 | len_listener = my_field_len(len_listener, cnf->recs[pos]->rec_listener, 0); | ||
| 541 | len_mask = my_field_len(len_mask, cnf->recs[pos]->rec_mask, 0); | ||
| 542 | len_local = my_field_len(len_local, &conn_local, 0); | ||
| 543 | len_peer = my_field_len(len_peer, &conn_peer, 0); | ||
| 544 | len_start = my_field_len(len_start, cnf->recs[pos]->rec_start, 0); | ||
| 545 | len_activity = my_field_len(len_start, cnf->recs[pos]->rec_activity, 0); | ||
| 546 | len_ops = my_field_len(len_ops, &str, 0); | ||
| 547 | len_ops_recv = my_field_len(len_ops_recv, NULL, cnf->recs[pos]->rec_ops_recv); | ||
| 548 | len_ops_exec = my_field_len(len_ops_exec, NULL, cnf->recs[pos]->rec_ops_exec); | ||
| 549 | len_ops_pend = my_field_len(len_ops_pend, NULL, cnf->recs[pos]->rec_ops_pend); | ||
| 550 | len_ops_comp = my_field_len(len_ops_comp, NULL, cnf->recs[pos]->rec_ops_comp); | ||
| 551 | }; | ||
| 552 | |||
| 553 | printf("%-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %s\n", | ||
| 554 | len_listener, "Listener", | ||
| 555 | len_proto, " ", | ||
| 556 | len_mask, "Mask", | ||
| 557 | len_ops, "Ops R/E/P/C", | ||
| 558 | len_local, "Local", | ||
| 559 | len_peer, "Peer", | ||
| 560 | len_start, "Start", | ||
| 561 | len_activity, "Last Activity", | ||
| 562 | "AuthzDN" | ||
| 563 | ); | ||
| 564 | |||
| 565 | for(pos = 0; (pos < cnf->recs_len); pos++) | ||
| 566 | { | ||
| 567 | if (!(cnf->recs[pos]->rec_proto)) | ||
| 568 | continue; | ||
| 569 | conn_peer = strrchr(cnf->recs[pos]->rec_peer[0], '='); | ||
| 570 | conn_peer = ((conn_peer)) ? &conn_peer[1] : cnf->recs[pos]->rec_peer[0]; | ||
| 571 | conn_local = strrchr(cnf->recs[pos]->rec_local[0], '='); | ||
| 572 | conn_local = ((conn_local)) ? &conn_local[1] : cnf->recs[pos]->rec_local[0]; | ||
| 573 | snprintf(ops, sizeof(ops), "%i/%i/%i/%i", | ||
| 574 | cnf->recs[pos]->rec_ops_recv, | ||
| 575 | cnf->recs[pos]->rec_ops_exec, | ||
| 576 | cnf->recs[pos]->rec_ops_pend, | ||
| 577 | cnf->recs[pos]->rec_ops_comp | ||
| 578 | ); | ||
| 579 | printf("%-*s v%-*i %-*s %-*s %-*s %-*s %-*s %-*s %s\n", | ||
| 580 | len_listener, cnf->recs[pos]->rec_listener[0], | ||
| 581 | len_proto, cnf->recs[pos]->rec_proto, | ||
| 582 | len_mask, cnf->recs[pos]->rec_mask[0], | ||
| 583 | len_ops, ops, | ||
| 584 | len_local, conn_local, | ||
| 585 | len_peer, conn_peer, | ||
| 586 | len_start, cnf->recs[pos]->rec_start[0], | ||
| 587 | len_activity, cnf->recs[pos]->rec_activity[0], | ||
| 588 | (((cnf->recs[pos]->rec_authzdn)) ? cnf->recs[pos]->rec_authzdn[0] : "") | ||
| 589 | ); | ||
| 590 | }; | ||
| 591 | |||
| 592 | return(0); | ||
| 593 | } | ||
| 594 | |||
| 595 | int | ||
| 596 | my_field_len( | ||
| 597 | int len, | ||
| 598 | char ** val_str, | ||
| 599 | unsigned val_num ) | ||
| 600 | { | ||
| 601 | int val_len; | ||
| 602 | char buff[128]; | ||
| 603 | char * ptr; | ||
| 604 | if (!(val_str)) | ||
| 605 | { | ||
| 606 | snprintf(buff, (sizeof(buff)-1), "%u", val_num); | ||
| 607 | ptr = buff; | ||
| 608 | val_str = &ptr; | ||
| 609 | }; | ||
| 610 | val_len = (int)strlen(val_str[0]); | ||
| 611 | return( (val_len > len) ? val_len : len); | ||
| 612 | } | ||
| 613 | |||
| 614 | |||
| 615 | int | ||
| 616 | my_rootdse( | ||
| 617 | MyConfig * cnf ) | ||
| 618 | |||
| 619 | { | ||
| 620 | int rc; | ||
| 621 | int err; | ||
| 622 | int msgid; | ||
| 623 | char * errmsg; | ||
| 624 | LDAP * ld; | ||
| 625 | LDAPMessage * res; | ||
| 626 | LDAPMessage * msg; | ||
| 627 | struct timeval timeout; | ||
| 628 | |||
| 629 | ld = cnf->lud->ld; | ||
| 630 | |||
| 631 | // searches for RootDSE | ||
| 632 | timeout.tv_sec = 5; | ||
| 633 | timeout.tv_usec = 0; | ||
| 634 | if ((err = ldap_search_ext(ld, "", LDAP_SCOPE_BASE, "(objectclass=*)", cnf->lud->attrs, 0, NULL, NULL, &timeout, -1, &msgid)) != LDAP_SUCCESS) | ||
| 635 | { | ||
| 636 | fprintf(stderr, "%s: ldap_search_ext(): %s\n", cnf->prog_name, ldap_err2string(err)); | ||
| 637 | return(-1); | ||
| 638 | }; | ||
| 639 | switch((err = ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, &res))) | ||
| 640 | { | ||
| 641 | case 0: | ||
| 642 | fprintf(stderr, "%s: ldap_search_ext(): operation timed out\n", cnf->prog_name); | ||
| 643 | return(-1); | ||
| 644 | |||
| 645 | case -1: | ||
| 646 | ldap_get_option(ld, LDAP_OPT_ERROR, &err); | ||
| 647 | fprintf(stderr, "%s: ldap_result(): %s\n", cnf->prog_name, ldap_err2string(err)); | ||
| 648 | return(-1); | ||
| 649 | |||
| 650 | default: | ||
| 651 | break; | ||
| 652 | }; | ||
| 653 | |||
| 654 | // parses result | ||
| 655 | rc = ldap_parse_result(ld, res, &err, NULL, &errmsg, NULL, NULL, 0); | ||
| 656 | if (rc != LDAP_SUCCESS) | ||
| 657 | { | ||
| 658 | fprintf(stderr, "%s: ldap_parse_result(): %s\n", cnf->prog_name, ldap_err2string(rc)); | ||
| 659 | ldap_msgfree(res); | ||
| 660 | return(-1); | ||
| 661 | }; | ||
| 662 | if (err != LDAP_SUCCESS) | ||
| 663 | { | ||
| 664 | fprintf(stderr, "%s: ldap_parse_result(): %s\n", cnf->prog_name, errmsg); | ||
| 665 | ldap_memfree(errmsg); | ||
| 666 | ldap_msgfree(res); | ||
| 667 | return(-1); | ||
| 668 | }; | ||
| 669 | |||
| 670 | // retrieves entry | ||
| 671 | msg = ldap_first_entry(ld, res); | ||
| 672 | |||
| 673 | // retrieve DNs | ||
| 674 | cnf->monitor = ldap_get_values(ld, msg, "monitorContext"); | ||
| 675 | my_monitor_connections(cnf, cnf->monitor[0]); | ||
| 676 | |||
| 677 | // frees response | ||
| 678 | ldap_msgfree(res); | ||
| 679 | |||
| 680 | return(0); | ||
| 681 | } | ||
| 682 | |||
| 683 | |||
| 684 | void | ||
| 685 | my_unbind( | ||
| 686 | MyConfig * cnf ) | ||
| 687 | { | ||
| 688 | assert(cnf != NULL); | ||
| 689 | if ((cnf->lud)) | ||
| 690 | ldaputils_unbind(cnf->lud); | ||
| 691 | if ((cnf->defvals)) | ||
| 692 | free(cnf->defvals); | ||
| 693 | free(cnf); | ||
| 694 | return; | ||
| 695 | } | ||
| 696 | |||
| 697 | /* end of source file */ | ||
