File: ldap.c

package info (click to toggle)
echoping 6.0.2-2
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 7,596 kB
  • ctags: 380
  • sloc: sh: 8,966; ansic: 3,350; makefile: 162
file content (159 lines) | stat: -rw-r--r-- 4,279 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
 * LDAP plugin. TODO: loops with and without opening the connection each
 * time? $Id: ldap.c 377 2007-03-12 20:48:05Z bortz $
 */

#define IN_PLUGIN
#include "../../echoping.h"
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#include "config.h"
#endif
#include <ldap.h>

const char     *request = NULL;
const char     *base = NULL;
int             scope = LDAP_SCOPE_BASE;
const char     *hostname;
int             port = 0;
LDAP           *session;
poptContext     ldap_poptcon;
echoping_options global_options;

void
ldap_usage(const char *msg)
{
	if (msg) {
		printf("LDAP plugin error: %s\n", msg);
	}
	poptPrintUsage(ldap_poptcon, stdout, 0);
	exit(1);
}

char           *
init(const int argc, const char **argv,
     const echoping_options global_external_options)
{
	int             value;
	char           *msg = malloc(MAX_LINE);
	char           *rest, *port_text;
	char           *scope_string = NULL;
	/* popt variables */
	struct poptOption options[] = {
		{"request", 'r', POPT_ARG_STRING, &request, 0,
		 "Request (filter) to send to the LDAP server", "r"},
		{"base", 'b', POPT_ARG_STRING, &base, 0,
		 "Base of the LDAP tree", "b"},
		{"scope", 's', POPT_ARG_STRING, &scope_string, 0,
		 "Scope of the search in the LDAP tree (sub, one or base)", "s"},
		{"port", 'p', POPT_ARG_INT, &port, 0,
		 "TCP port to connect to the LDAP server", "p"},
		POPT_AUTOHELP POPT_TABLEEND
	};
	global_options = global_external_options;
	if (global_options.udp)
		err_quit("UDP makes no sense for a LDAP connection");
	ldap_poptcon = poptGetContext(NULL, argc,
				      argv, options, POPT_CONTEXT_KEEP_FIRST);
	while ((value = poptGetNextOpt(ldap_poptcon)) > 0) {
	}
	if (value < -1) {
		sprintf(msg, "%s: %s",
			poptBadOption(ldap_poptcon, POPT_BADOPTION_NOALIAS),
			poptStrerror(value));
		ldap_usage(msg);
	}
	if (port == 0)
		port = LDAP_PORT;
	hostname = poptGetArg(ldap_poptcon);
	rest = poptGetArg(ldap_poptcon);
	if (rest != NULL) {
		fprintf(stderr, "%s: ", rest);
		ldap_usage("Additional arguments");
	}
	if (base == NULL)
		base = "";
	if (request == NULL || !strcmp(request, ""))
		request = "(objectclass=*)";
	if (scope_string != NULL) {
		scope_string = (char *)to_upper(scope_string);
		if (!strcmp(scope_string, "BASE"))
			scope = LDAP_SCOPE_BASE;
		else if (!strcmp(scope_string, "SUB"))
			scope = LDAP_SCOPE_SUBTREE;
		else if (!strcmp(scope_string, "ONE"))
			scope = LDAP_SCOPE_ONELEVEL;
		else
			err_quit("Invalid scope \"%s\"", scope_string);
	}
	if (port == LDAP_PORT) {
		return "ldap";
	} else {
		port_text = malloc(99);
		sprintf(port_text, "%d", port);
		return port_text;
	}
}

void
start()
{
	int             result;
	LDAPMessage    *response;

	session = ldap_init(hostname, port);
	if (session == NULL)
		err_sys("Cannot initialize LDAP");
	/* TODO: allow non-anonymous connections, with ldap_bind_simple_s */
	/* 
	 * Unfortunately, ldap_init does not connect to the LDAP server. So
	 * connection errors (e.g. firewall), will not be detected here and
	 * loop will go on.
	 * 
	 * To quote the man page: ldap_init() acts just like ldap_open(), but
	 * does not open a connection to the LDAP server.  The actual
	 * connection open will occur when the first operation is attempted.
	 * At this time, ldap_init() is preferred.  ldap_open() will be
	 * depreciated in a later release.
	 * 
	 * So, we perform a dummy search immediately.
	 */
	result = ldap_search_s(session, base, LDAP_SCOPE_ONELEVEL, "(objectclass=*)", NULL,	/* Return 
												 * all 
												 * attributes 
												 */
			       1, &response);
	if (result != 0) {
		err_quit
		    ("Cannot connect to %s (no LDAP server or wrong base, probably): %s",
		     hostname, ldap_err2string(result));
	}
}

int
execute()
{
	int             result;
	LDAPMessage    *response;
	result = ldap_search_s(session, base, scope, request, NULL,	/* Return
									 * all
									 * attributes 
									 */
			       0,	/* Return attribute types *and* values */
			       &response);
	if (result != 0) {
		err_ret("Cannot search \"%s\": %s", request,
			ldap_err2string(result));
		return -1;
	}
	if (global_options.verbose)
		printf("Retrieved: %d entries\n",
		       ldap_count_entries(session, response));
	return 0;
}

void
terminate()
{
	ldap_unbind_s(session);
}