Пример #1
0
int ldap_search_user(const char *account, LDAPMessage **entry)
{

   char filter[MAXLEN+1];
   int rc;
   LDAPMessage *res;

   struct timeval timeout;

   memset(filter, 0, MAXLEN+1);
   snprintf(filter, MAXLEN, "%s=%s", nickserv_conf.ldap_field_account, account);
   /*
    Now we do a search;
    */
   timeout.tv_usec = 0;
   timeout.tv_sec  = nickserv_conf.ldap_timeout;
    if(!admin_bind && LDAP_SUCCESS != ( rc = ldap_do_admin_bind())) {
       log_module(MAIN_LOG, LOG_ERROR, "failed to bind as admin");
       return rc;
    }
   if( (rc = ldap_search_st(ld, nickserv_conf.ldap_base, LDAP_SCOPE_ONELEVEL, filter, NULL, 0, &timeout, &res)) != LDAP_SUCCESS) {
       log_module(MAIN_LOG, LOG_ERROR, "search failed: %s   %s: %s", nickserv_conf.ldap_base, filter, ldap_err2string(rc));
       return(rc);
   }
   log_module(MAIN_LOG, LOG_DEBUG, "Search successfull!  %s    %s\n", nickserv_conf.ldap_base, filter);
   if(ldap_count_entries(ld, res) != 1) {
      log_module(MAIN_LOG, LOG_DEBUG, "LDAP search got %d entries when looking for %s", ldap_count_entries(ld, res), account);
      return(LDAP_OTHER); /* Search was a success, but user not found.. */
   }
   log_module(MAIN_LOG, LOG_DEBUG, "LDAP search got %d entries", ldap_count_entries(ld, res));
   *entry = ldap_first_entry(ld, res);
   return(rc);
}
Пример #2
0
static int idmap_query_attrs(
    struct idmap_context *context,
    const struct idmap_lookup *lookup,
    const unsigned attributes,
    const unsigned optional,
    PCHAR *values[],
    const int len)
{
    char filter[FILTER_LEN];
    struct idmap_config *config = &context->config;
    LDAPMessage *res = NULL, *entry;
    int i, status;

    /* format the ldap filter */
    status = idmap_filter(config, lookup, filter, FILTER_LEN);
    if (status)
        goto out;

    /* send the ldap query */
    status = ldap_search_st(context->ldap, config->base,
        LDAP_SCOPE_SUBTREE, filter, NULL, 0, NULL, &res);
    if (status) {
        eprintf("ldap search for '%s' failed with %d: %s\n",
            filter, status, ldap_err2stringA(status));
        status = LdapMapErrorToWin32(status);
        goto out;
    }

    entry = ldap_first_entry(context->ldap, res);
    if (entry == NULL) {
        status = LDAP_NO_RESULTS_RETURNED;
        eprintf("ldap search for '%s' failed with %d: %s\n",
            filter, status, ldap_err2stringA(status));
        status = LdapMapErrorToWin32(status);
        goto out;
    }

    /* fetch the attributes */
    for (i = 0; i < len; i++) {
        if (ATTR_ISSET(attributes, i)) {
            values[i] = ldap_get_values(context->ldap,
                entry, config->attributes[i]);

            /* fail if required attributes are missing */
            if (values[i] == NULL && !ATTR_ISSET(optional, i)) {
                status = LDAP_NO_SUCH_ATTRIBUTE;
                eprintf("ldap entry for '%s' missing required "
                    "attribute '%s', returning %d: %s\n",
                    filter, config->attributes[i],
                    status, ldap_err2stringA(status));
                status = LdapMapErrorToWin32(status);
                goto out;
            }
        }
    }
out:
    if (res) ldap_msgfree(res);
    return status;
}
Пример #3
0
/* ARGSUSED */
int _ns_ldap_search_st(char *service, int flags,
	char *base, int scope, char *filter,
	char **attrs, int attrsonly,
	struct timeval *timeout, LDAPMessage **res)
{
	LDAP *ld = __s_api_getLDAPconn(flags);

	return (ldap_search_st(ld, base, scope, filter,
		attrs, attrsonly, timeout, res));
}
Пример #4
0
/* -1 if trouble
   0 if user is NOT member of current server group
   1 if user IS MEMBER of current server group 
 */
int ldap_ismember(ldap_opt_t * l, const char * user) {
    LDAPMessage *res;
    char * filter;
    int i;

    if ((!l->sgroup) || !(l->g_basedn))
        return 1;

    /* Am i still connected ? RETRY n times */
    /* XXX TODO: setup some conf value for retrying */
    if (!(l->flags & FLAG_CONNECTED)) 
        for (i = 0 ; i < 2 ; i++)
            if (ldap_connect(l) == 0)
                 break;

    /* quick check for attempts to be evil */
    if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) ||
        (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL))
        return FAILURE;

    /* build filter for LDAP request */
    REQUEST_GROUP(filter, l->fgroup, user);

    if (ldap_search_st( l->ld, 
        l->g_basedn,
        LDAP_SCOPE_SUBTREE,
        filter,
        NULL, 0, &l->s_timeout, &res) != LDAP_SUCCESS) {
    
        ldap_perror(l->ld, "ldap_search_st()");

        free(filter);

        /* XXX error on search, timeout etc.. close ask for reconnect */
        ldap_close(l);

        return FAILURE;
    }

    free(filter);

    /* check if any results */
    if (ldap_count_entries(l->ld, res) > 0) {
        ldap_msgfree(res);
        return 1;
    }

    ldap_msgfree(res);
    return 0;
}
Пример #5
0
static int get_ldap_seq(const char *server, int port, uint32 *seq)
{
	int ret = -1;
	struct timeval to;
	char *attrs[] = {"highestCommittedUSN", NULL};
	LDAPMessage *res = NULL;
	char **values = NULL;
	LDAP *ldp = NULL;

	*seq = DOM_SEQUENCE_NONE;

	/*
	 * Parameterised (5) second timeout on open. This is needed as the search timeout
	 * doesn't seem to apply to doing an open as well. JRA.
	 */

	if ((ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout())) == NULL)
		return -1;

	/* Timeout if no response within 20 seconds. */
	to.tv_sec = 10;
	to.tv_usec = 0;

	if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", &attrs[0], 0, &to, &res))
		goto done;

	if (ldap_count_entries(ldp, res) != 1)
		goto done;

	values = ldap_get_values(ldp, res, "highestCommittedUSN");
	if (!values || !values[0])
		goto done;

	*seq = atoi(values[0]);
	ret = 0;

  done:

	if (values)
		ldap_value_free(values);
	if (res)
		ldap_msgfree(res);
	if (ldp)
		ldap_unbind(ldp);
	return ret;
}
Пример #6
0
static int
nsldapi_get_sasl_mechs ( LDAP *ld, char **pmech )
{
        char *attr[] = { "supportedSASLMechanisms", NULL };
        char **values, **v, *mech, *m;
        LDAPMessage *res, *e;
        struct timeval  timeout;
        int slen, rc;

        if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
                return( LDAP_PARAM_ERROR );
        }

        timeout.tv_sec = SEARCH_TIMEOUT_SECS;
        timeout.tv_usec = 0;

        rc = ldap_search_st( ld, "", LDAP_SCOPE_BASE,
                "objectclass=*", attr, 0, &timeout, &res );

        if ( rc != LDAP_SUCCESS ) {
                return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
        }

        e = ldap_first_entry( ld, res );
        if ( e == NULL ) {
                ldap_msgfree( res );
                if ( ld->ld_errno == LDAP_SUCCESS ) {
                        LDAP_SET_LDERRNO( ld, LDAP_NO_SUCH_OBJECT, NULL, NULL );
                }
                return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
        }

        values = ldap_get_values( ld, e, "supportedSASLMechanisms" );
        if ( values == NULL ) {
                ldap_msgfree( res );
                LDAP_SET_LDERRNO( ld, LDAP_NO_SUCH_ATTRIBUTE, NULL, NULL );
                return( LDAP_NO_SUCH_ATTRIBUTE );
        }

        slen = 0;
        for(v = values; *v != NULL; v++ ) {
                slen += strlen(*v) + 1;
        }
        if ( (mech = NSLDAPI_CALLOC(1, slen)) == NULL) {
                ldap_value_free( values );
                ldap_msgfree( res );
                LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
                return( LDAP_NO_MEMORY );
        }
        m = mech;
        for(v = values; *v; v++) {
                if (v != values) {
                        *m++ = ' ';
                }
                slen = strlen(*v);
                strncpy(m, *v, slen);
                m += slen;
        }
        *m = '\0';

        ldap_value_free( values );
        ldap_msgfree( res );

        *pmech = mech;

        return( LDAP_SUCCESS );
}
Пример #7
0
int
qldap_lookup(qldap *q, const char *filter, const char *attrs[])
{
	/* search a unique entry */
	struct timeval	tv;
	int		rc;
	unsigned int	num_entries;
	
	CHECK(q, SEARCH);
	
	tv.tv_sec = ldap_timeout;
	tv.tv_usec = 0;

	rc = ldap_search_st(q->ld, basedn.s, LDAP_SCOPE_SUBTREE,
		filter, (char **)attrs, 0, &tv, &q->res);
	
	switch (rc) {
	/* probably more detailed information should be returned, eg.:
	   LDAP_TIMELIMIT_EXCEEDED,
	   LDAP_SIZELIMIT_EXCEEDED,
	   LDAP_PARTIAL_RESULTS,
	   LDAP_INSUFFICIENT_ACCESS,
	   LDAP_BUSY,
	   LDAP_UNAVAILABLE,
	   LDAP_UNWILLING_TO_PERFORM,
	   LDAP_TIMEOUT
	 */

	case LDAP_SUCCESS:
		logit(128, "qldap_lookup: search for %s succeeded\n",
		    filter);
		break;
	case LDAP_TIMEOUT:
	case LDAP_TIMELIMIT_EXCEEDED:
	case LDAP_BUSY:
		logit(64, "qldap_lookup: search for %s failed (%s)\n", 
		    filter, ldap_err2string(rc) );
		return TIMEOUT;
	case LDAP_NO_SUCH_OBJECT:
		logit(64, "qldap_filter: search for %s failed (%s)\n", 
		    filter, ldap_err2string(rc) );
		return NOSUCH;
	default:
		logit(64, "qldap_lookup: search for %s failed (%s)\n", 
		    filter, ldap_err2string(rc) );
		return FAILED;
	}

	/* count the results, we must have exactly one */
	num_entries = ldap_count_entries(q->ld, q->res);
	if (num_entries != 1) {
		if (num_entries > 1) {
			logit(64, "qldap_lookup: Too many entries found (%i)\n", 
			    num_entries);
			return TOOMANY;
		} else {
			logit(64, "qldap_lookup: Nothing found\n"); 
			return NOSUCH;
		}
	}
	/* go to the first entry */
	q->msg = ldap_first_entry(q->ld, q->res);
	
	/*
	 * We already selected the first and only entry so
	 * skip SEARCH state and move directly to EXTRACT state.
	 */
	q->state = EXTRACT;
	return OK;
}
Пример #8
0
int
qldap_filter(qldap *q, const char *filter, const char *attrs[],
    char *bdn, int scope)
{
	
	/* search a unique entry */
	struct	timeval tv;
	int	rc;
	
	/* search multiple entries */
	CHECK(q, SEARCH);
	
	switch (scope) {
	case SCOPE_BASE:
		scope = LDAP_SCOPE_BASE;
		break;
	case SCOPE_ONELEVEL:
		scope = LDAP_SCOPE_ONELEVEL;
		break;
	case SCOPE_SUBTREE:
		scope = LDAP_SCOPE_SUBTREE;
		break;
	default:
		return FAILED;
	}

	tv.tv_sec = ldap_timeout;
	tv.tv_usec = 0;

	rc = ldap_search_st(q->ld, bdn, scope, filter,
	    (char **)attrs, 0, &tv, &q->res);
	
	switch (rc) {
	/* probably more detailed information should be returned, eg.:
	   LDAP_TIMELIMIT_EXCEEDED,
	   LDAP_SIZELIMIT_EXCEEDED,
	   LDAP_PARTIAL_RESULTS,
	   LDAP_INSUFFICIENT_ACCESS,
	   LDAP_BUSY,
	   LDAP_UNAVAILABLE,
	   LDAP_UNWILLING_TO_PERFORM,
	   LDAP_TIMEOUT
	 */

	case LDAP_SUCCESS:
		logit(128, "qldap_filter: search for %s succeeded\n",
		    filter);
		break;
	case LDAP_TIMEOUT:
	case LDAP_TIMELIMIT_EXCEEDED:
	case LDAP_BUSY:
		logit(64, "qldap_filter: search for %s failed (%s)\n", 
		    filter, ldap_err2string(rc) );
		return TIMEOUT;
	case LDAP_NO_SUCH_OBJECT:
		logit(64, "qldap_filter: search for %s failed (%s)\n", 
		    filter, ldap_err2string(rc) );
		return NOSUCH;
	default:
		logit(64, "qldap_filter: search for %s failed (%s)\n", 
		    filter, ldap_err2string(rc) );
		return FAILED;
	}
	
	q->state = SEARCH;
	return OK;
}
Пример #9
0
static const char *dict_ldap_lookup(DICT *dict, const char *name)
{
    char   *myname = "dict_ldap_lookup";
    DICT_LDAP *dict_ldap = (DICT_LDAP *) dict;
    LDAPMessage *res = 0;
    static VSTRING *result;
    struct timeval tv;
    VSTRING *escaped_name = 0,
           *filter_buf = 0;
    int     rc = 0;
    int     sizelimit;
    char   *sub,
           *end;

    dict_errno = 0;

    if (msg_verbose)
	msg_info("%s: In dict_ldap_lookup", myname);

    /*
     * If they specified a domain list for this map, then only search for
     * addresses in domains on the list. This can significantly reduce the
     * load on the LDAP server.
     */
    if (dict_ldap->domain) {
	const char *p = strrchr(name, '@');

	if (p == 0 || p == name ||
	    match_list_match(dict_ldap->domain, ++p) == 0) {
	    if (msg_verbose)
		msg_info("%s: domain of %s not found in domain list", myname,
			 name);
	    return (0);
	}
    }

    /*
     * Initialize the result holder.
     */
    if (result == 0)
	result = vstring_alloc(2);
    vstring_strcpy(result, "");

    /*
     * Because the connection may be shared and invalidated via queries for
     * another map, update private copy of "ld" from shared connection
     * container.
     */
    dict_ldap->ld = DICT_LDAP_CONN(dict_ldap)->conn_ld;

    /*
     * Connect to the LDAP server, if necessary.
     */
    if (dict_ldap->ld == NULL) {
	if (msg_verbose)
	    msg_info
		("%s: No existing connection for LDAP source %s, reopening",
		 myname, dict_ldap->ldapsource);

	dict_ldap_connect(dict_ldap);

	/*
	 * if dict_ldap_connect() set dict_errno, abort.
	 */
	if (dict_errno)
	    return (0);
    } else if (msg_verbose)
	msg_info("%s: Using existing connection for LDAP source %s",
		 myname, dict_ldap->ldapsource);

    /*
     * Connection caching, means that the connection handle may have the
     * wrong size limit. Re-adjust before each query. This is cheap, just
     * sets a field in the ldap connection handle. We also do this in the
     * connect code, because we sometimes reconnect (below) in the middle of
     * a query.
     */
    sizelimit = dict_ldap->size_limit ? dict_ldap->size_limit : LDAP_NO_LIMIT;
    if (ldap_set_option(dict_ldap->ld, LDAP_OPT_SIZELIMIT, &sizelimit)
	!= LDAP_OPT_SUCCESS)
	msg_warn("%s: %s: Unable to set query result size limit to %ld.",
		 myname, dict_ldap->ldapsource, dict_ldap->size_limit);

    /*
     * Prepare the query.
     */
    tv.tv_sec = dict_ldap->timeout;
    tv.tv_usec = 0;
    escaped_name = vstring_alloc(20);
    filter_buf = vstring_alloc(30);

    /*
     * If any characters in the supplied address should be escaped per RFC
     * 2254, do so. Thanks to Keith Stevenson and Wietse. And thanks to
     * Samuel Tardieu for spotting that wildcard searches were being done in
     * the first place, which prompted the ill-conceived lookup_wildcards
     * parameter and then this more comprehensive mechanism.
     */
    end = (char *) name + strlen((char *) name);
    sub = (char *) strpbrk((char *) name, "*()\\\0");
    if (sub && sub != end) {
	if (msg_verbose)
	    msg_info("%s: Found character(s) in %s that must be escaped",
		     myname, name);
	for (sub = (char *) name; sub != end; sub++) {
	    switch (*sub) {
	    case '*':
		vstring_strcat(escaped_name, "\\2a");
		break;
	    case '(':
		vstring_strcat(escaped_name, "\\28");
		break;
	    case ')':
		vstring_strcat(escaped_name, "\\29");
		break;
	    case '\\':
		vstring_strcat(escaped_name, "\\5c");
		break;
	    case '\0':
		vstring_strcat(escaped_name, "\\00");
		break;
	    default:
		vstring_strncat(escaped_name, sub, 1);
	    }
	}
	if (msg_verbose)
	    msg_info("%s: After escaping, it's %s", myname,
		     vstring_str(escaped_name));
    } else
	vstring_strcpy(escaped_name, (char *) name);

    /*
     * Does the supplied query_filter even include a substitution?
     */
    if ((char *) strchr(dict_ldap->query_filter, '%') == NULL) {

	/*
	 * No, log the fact and continue.
	 */
	msg_warn("%s: %s: Fixed query_filter %s is probably useless",
		 myname, dict_ldap->ldapsource, dict_ldap->query_filter);
	vstring_strcpy(filter_buf, dict_ldap->query_filter);
    } else {
	dict_ldap_expand_filter(dict_ldap->ldapsource, dict_ldap->query_filter,
				vstring_str(escaped_name), filter_buf);
    }

    /*
     * On to the search.
     */
    if (msg_verbose)
	msg_info("%s: Searching with filter %s", myname,
		 vstring_str(filter_buf));

    rc = ldap_search_st(dict_ldap->ld, dict_ldap->search_base,
			dict_ldap->scope,
			vstring_str(filter_buf),
			dict_ldap->result_attributes->argv,
			0, &tv, &res);

    if (rc == LDAP_SERVER_DOWN) {
	if (msg_verbose)
	    msg_info("%s: Lost connection for LDAP source %s, reopening",
		     myname, dict_ldap->ldapsource);

	ldap_unbind(dict_ldap->ld);
	dict_ldap->ld = DICT_LDAP_CONN(dict_ldap)->conn_ld = 0;
	dict_ldap_connect(dict_ldap);

	/*
	 * if dict_ldap_connect() set dict_errno, abort.
	 */
	if (dict_errno)
	    return (0);

	rc = ldap_search_st(dict_ldap->ld, dict_ldap->search_base,
			    dict_ldap->scope,
			    vstring_str(filter_buf),
			    dict_ldap->result_attributes->argv,
			    0, &tv, &res);

    }
    if (rc == LDAP_SUCCESS) {

	/*
	 * Search worked; extract the requested result_attribute.
	 */

	dict_ldap_get_values(dict_ldap, res, result);

	/*
	 * OpenLDAP's ldap_next_attribute returns a bogus
	 * LDAP_DECODING_ERROR; I'm ignoring that for now.
	 */

	rc = dict_ldap_get_errno(dict_ldap->ld);
	if (rc != LDAP_SUCCESS && rc != LDAP_DECODING_ERROR)
	    msg_warn
		("%s: Had some trouble with entries returned by search: %s",
		 myname, ldap_err2string(rc));

	if (msg_verbose)
	    msg_info("%s: Search returned %s", myname,
		     VSTRING_LEN(result) >
		     0 ? vstring_str(result) : "nothing");
    } else {

	/*
	 * Rats. The search didn't work.
	 */
	msg_warn("%s: Search error %d: %s ", myname, rc,
		 ldap_err2string(rc));

	/*
	 * Tear down the connection so it gets set up from scratch on the
	 * next lookup.
	 */
	ldap_unbind(dict_ldap->ld);
	dict_ldap->ld = DICT_LDAP_CONN(dict_ldap)->conn_ld = 0;

	/*
	 * And tell the caller to try again later.
	 */
	dict_errno = DICT_ERR_RETRY;
    }

    /*
     * Cleanup.
     */
    if (res != 0)
	ldap_msgfree(res);
    if (filter_buf != 0)
	vstring_free(filter_buf);
    if (escaped_name != 0)
	vstring_free(escaped_name);

    /*
     * If we had an error, return nothing, Otherwise, return the result, if
     * any.
     */
    return (VSTRING_LEN(result) > 0 && !dict_errno ? vstring_str(result) : 0);
}
Пример #10
0
void run_ldap_tests(service_t *ldaptest, int sslcertcheck, int querytimeout)
{
#ifdef HAVE_LDAP
	ldap_data_t *req;
	testitem_t *t;
	struct timespec starttime;
	struct timespec endtime;

	/* Pick a sensible default for the timeout setting */
	if (querytimeout == 0) querytimeout = 30;

	for (t = ldaptest->items; (t); t = t->next) {
		LDAPURLDesc	*ludp;
		LDAP		*ld;
		int		rc, finished;
		int		msgID = -1;
		struct timeval	ldaptimeout;
		struct timeval	openldaptimeout;
		LDAPMessage	*result;
		LDAPMessage	*e;
		strbuffer_t	*response;
		char		buf[MAX_LINE_LEN];

		req = (ldap_data_t *) t->privdata;
		if (req->skiptest) continue;

		ludp = (LDAPURLDesc *) req->ldapdesc;

		getntimer(&starttime);

		/* Initiate session with the LDAP server */
		dbgprintf("Initiating LDAP session for host %s port %d\n",
			ludp->lud_host, ludp->lud_port);

		if( (ld = ldap_init(ludp->lud_host, ludp->lud_port)) == NULL ) {
			dbgprintf("ldap_init failed\n");
			req->ldapstatus = XYMON_LDAP_INITFAIL;
			continue;
		}

		/* 
		 * There is apparently no standard way of defining a network
		 * timeout for the initial connection setup. 
		 */
#if (LDAP_VENDOR == OpenLDAP) && defined(LDAP_OPT_NETWORK_TIMEOUT)
		/* 
		 * OpenLDAP has an undocumented ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tv)
		 */
		openldaptimeout.tv_sec = querytimeout;
		openldaptimeout.tv_usec = 0;
		ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &openldaptimeout);
#else
		/*
		 * So using an alarm() to interrupt any pending operations
		 * seems to be the least insane way of doing this.
		 *
		 * Note that we must do this right after ldap_init(), as
		 * any operation on the session handle (ld) may trigger the
		 * network connection to be established.
		 */
		connect_timeout = 0;
		signal(SIGALRM, ldap_alarmhandler);
		alarm(querytimeout);
#endif

		/*
		 * This is completely undocumented in the OpenLDAP docs.
		 * But apparently it is documented in 
		 * http://www.ietf.org/proceedings/99jul/I-D/draft-ietf-ldapext-ldap-c-api-03.txt
		 *
		 * Both of these routines appear in the <ldap.h> file 
		 * from OpenLDAP 2.1.22. Their use to enable TLS has
		 * been deciphered from the ldapsearch() utility
		 * sourcecode.
		 *
		 * According to Manon Goo <*****@*****.**>, recent (Jan. 2005)
		 * OpenLDAP implementations refuse to talk LDAPv2.
		 */
#ifdef LDAP_OPT_PROTOCOL_VERSION 
		{
			int protocol = LDAP_VERSION3;

			dbgprintf("Attempting to select LDAPv3\n");
			if ((rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) {
				dbgprintf("Failed to select LDAPv3, trying LDAPv2\n");
				protocol = LDAP_VERSION2;
				if ((rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) {
					req->output = strdup(ldap_err2string(rc));
					req->ldapstatus = XYMON_LDAP_TLSFAIL;
				}
				continue;
			}
		}
#endif

		if (req->usetls) {
			dbgprintf("Trying to enable TLS for session\n");
			if ((rc = ldap_start_tls_s(ld, NULL, NULL)) != LDAP_SUCCESS) {
				dbgprintf("ldap_start_tls failed\n");
				req->output = strdup(ldap_err2string(rc));
				req->ldapstatus = XYMON_LDAP_TLSFAIL;
				continue;
			}
		}

		if (!connect_timeout) {
			msgID = ldap_simple_bind(ld, (t->host->ldapuser ? t->host->ldapuser : ""), 
					 (t->host->ldappasswd ? t->host->ldappasswd : ""));
		}

		/* Cancel any pending alarms */
		alarm(0);
		signal(SIGALRM, SIG_DFL);

		/* Did we connect? */
		if (connect_timeout || (msgID == -1)) {
			req->ldapstatus = XYMON_LDAP_BINDFAIL;
			req->output = "Cannot connect to server";
			continue;
		}

		/* Wait for bind to complete */
		rc = 0; finished = 0; 
		ldaptimeout.tv_sec = querytimeout;
		ldaptimeout.tv_usec = 0L;
		while( ! finished ) {
			int rc2;

			rc = ldap_result(ld, msgID, LDAP_MSG_ONE, &ldaptimeout, &result);
			dbgprintf("ldap_result returned %d for ldap_simple_bind()\n", rc);
			if(rc == -1) {
				finished = 1;
				req->ldapstatus = XYMON_LDAP_BINDFAIL;

				if (result == NULL) {
					errprintf("LDAP library problem - NULL result returned\n");
					req->output = strdup("LDAP BIND failed\n");
				}
				else {
					rc2 = ldap_result2error(ld, result, 1);
					req->output = strdup(ldap_err2string(rc2));
				}
				ldap_unbind(ld);
			}
			else if (rc == 0) {
				finished = 1;
				req->ldapstatus = XYMON_LDAP_BINDFAIL;
				req->output = strdup("Connection timeout");
				ldap_unbind(ld);
			}
			else if( rc > 0 ) {
				finished = 1;
				if (result == NULL) {
					errprintf("LDAP library problem - got a NULL resultcode for status %d\n", rc);
					req->ldapstatus = XYMON_LDAP_BINDFAIL;
					req->output = strdup("LDAP library problem: ldap_result2error returned a NULL result for status %d\n");
					ldap_unbind(ld);
				}
				else {
					rc2 = ldap_result2error(ld, result, 1);
					if(rc2 != LDAP_SUCCESS) {
						req->ldapstatus = XYMON_LDAP_BINDFAIL;
						req->output = strdup(ldap_err2string(rc));
						ldap_unbind(ld);
					}
				}
			}
		} /* ... while() */

		/* We're done connecting. If something went wrong, go to next query. */
		if (req->ldapstatus != 0) continue;

		/* Now do the search. With a timeout */
		ldaptimeout.tv_sec = querytimeout;
		ldaptimeout.tv_usec = 0L;
		rc = ldap_search_st(ld, ludp->lud_dn, ludp->lud_scope, ludp->lud_filter, ludp->lud_attrs, 0, &ldaptimeout, &result);

		if(rc == LDAP_TIMEOUT) {
			req->ldapstatus = XYMON_LDAP_TIMEOUT;
			req->output = strdup(ldap_err2string(rc));
	  		ldap_unbind(ld);
			continue;
		}
		if( rc != LDAP_SUCCESS ) {
			req->ldapstatus = XYMON_LDAP_SEARCHFAILED;
			req->output = strdup(ldap_err2string(rc));
	  		ldap_unbind(ld);
			continue;
		}

		getntimer(&endtime);

		response = newstrbuffer(0);
		sprintf(buf, "Searching LDAP for %s yields %d results:\n\n", 
			t->testspec, ldap_count_entries(ld, result));
		addtobuffer(response, buf);

		for(e = ldap_first_entry(ld, result); (e != NULL); e = ldap_next_entry(ld, e) ) {
			char 		*dn;
			BerElement	*ber;
			char		*attribute;
			char		**vals;

			dn = ldap_get_dn(ld, e);
			sprintf(buf, "DN: %s\n", dn); 
			addtobuffer(response, buf);

			/* Addtributes and values */
			for (attribute = ldap_first_attribute(ld, e, &ber); (attribute != NULL); attribute = ldap_next_attribute(ld, e, ber) ) {
				if ((vals = ldap_get_values(ld, e, attribute)) != NULL) {
					int i;

					for(i = 0; (vals[i] != NULL); i++) {
						sprintf(buf, "\t%s: %s\n", attribute, vals[i]);
						addtobuffer(response, buf);
					}
				}
				/* Free memory used to store values */
				ldap_value_free(vals);
			}

			/* Free memory used to store attribute */
			ldap_memfree(attribute);
			ldap_memfree(dn);
			if (ber != NULL) ber_free(ber, 0);

			addtobuffer(response, "\n");
		}
		req->ldapstatus = XYMON_LDAP_OK;
		req->output = grabstrbuffer(response);
		tvdiff(&starttime, &endtime, &req->duration);

		ldap_msgfree(result);
		ldap_unbind(ld);
		ldap_free_urldesc(ludp);
	}
#endif
}
Пример #11
0
static int auth_ldap_do3(const char *attrname,
			 const char *user, const char *pass,
			 int (*callback)(struct authinfo *, void *),
			 void *arg, const char *newpass,
			 const char *authaddr)
{
	char *newpass_crypt=0;
	const char *attributes[10], *ldap_attributes[10];
  
	struct timeval timeout;

	LDAPMessage *result;
	LDAPMessage *entry;
	char *filter, *dn;
	int i, j;

	struct authinfo auth;
	char *homeDir=0;
	char *mailDir=0;
	char *userPassword=0;
	char *cryptPassword=0;
	char *cn=0;
	uid_t au;
	gid_t ag;
	int rc;
	char *quota=0;
        int additionalFilter = 0;
        int hasAdditionalFilter = 0;

        hasAdditionalFilter = my_ldap.filter != 0;

	memset(&auth, 0, sizeof(auth));

        if (hasAdditionalFilter)
        {
            /* To add the additional filter, we need to add on the
             * additional size for "(&)" and the other filter.  So
             * filter+3
             */
            additionalFilter = strlen(my_ldap.filter) + 3;
        }

	if ((filter=malloc(additionalFilter+strlen(attrname)+strlen(user)+
			   (my_ldap.domain ? strlen(my_ldap.domain):0)+
			   sizeof ("(=@)"))) == 0)
	{
		perror("malloc");
		return 1;
	}
        strcpy(filter, "\0");

        if (hasAdditionalFilter)
        {
            strcat(filter, "(&");
            strcat(filter, my_ldap.filter);
        }

        strcat(strcat(strcat(strcat(filter, "("), attrname), "="), user);
	if ( my_ldap.domain && my_ldap.domain[0] && strchr(user, '@') == 0 )
		strcat(strcat(filter, "@"), my_ldap.domain);
	strcat(filter, ")");
        
        if (hasAdditionalFilter)
        {
            strcat(filter, ")");
        }

	timeout.tv_sec=my_ldap.timeout;
	timeout.tv_usec=0;

	read_env("LDAP_HOMEDIR", &attributes[0], "", 0, "homeDir");
	read_env("LDAP_MAILDIR", &attributes[1], "", 0, 0);
	read_env("LDAP_FULLNAME", &attributes[2], "", 0, "cn");
	read_env("LDAP_CLEARPW", &attributes[3], "", 0, 0);
	read_env("LDAP_CRYPTPW", &attributes[4], "", 0, 0);
	read_env("LDAP_UID", &attributes[5], "", 0, 0);
	read_env("LDAP_GID", &attributes[6], "", 0, 0);
	attributes[7]=my_ldap.mail;
	read_env("LDAP_MAILDIRQUOTA", &attributes[8], "", 0, 0);

	j=0;
	for (i=0; i<9; i++)
	{
		if (attributes[i])
			ldap_attributes[j++]=attributes[i];
	}

	ldap_attributes[j]=0;

	if (ldaperror(ldap_search_st(my_ldap_fp,
				     (char *)my_ldap.basedn,LDAP_SCOPE_SUBTREE,
				     filter, (char **)ldap_attributes, 0,
				     &timeout, &result)
		      != LDAP_SUCCESS))
	{
		free(filter);

		if (my_ldap_fp)	return (-1);
		return (1);
	}

	free(filter);

	/* If we are more than one result, reject */
	if (ldap_count_entries(my_ldap_fp,result)!=1)
	{
		ldap_msgfree(result);
		return -1;
	}
#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"Nombre de résulat:    %d\n",ldap_count_entries(my_ldap_fp,result));
#endif

	dn = ldap_get_dn(my_ldap_fp, result);

#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"DN:    %s\n",dn);
#endif

	if (dn == NULL) 
	{
		ldap_perror(my_ldap_fp, "ldap_get_dn");
		return -1;
	}

	/* Get the pointer on this result */
	entry=ldap_first_entry(my_ldap_fp,result);
	if (entry==NULL)
	{
		ldap_perror(my_ldap_fp,"ldap_first_entry");
		free(dn);
		return -1;
	}

#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"after ldap_first_entry\n");
#endif
	/* Copy the directory and the password into struct */
	copy_value(my_ldap_fp,entry,attributes[0],&homeDir, user);
	if (attributes[1])
		copy_value(my_ldap_fp,entry,attributes[1],&mailDir, user);
	copy_value(my_ldap_fp,entry,attributes[2],&cn, user);
	if (attributes[3])
		copy_value(my_ldap_fp,entry,attributes[3],&userPassword, user);
	if (attributes[4])
		copy_value(my_ldap_fp,entry,attributes[4],&cryptPassword, user);

	au=my_ldap.uid;
	ag=my_ldap.gid;
	if (attributes[5])
	{
		char *p=0;
		unsigned long n;

		copy_value(my_ldap_fp, entry, attributes[5], &p, user);
		if (p) {
			if (sscanf(p, "%lu", &n) > 0)
				au= (uid_t)n;
			free(p);
		}
#if DEBUG_LDAP
		syslog(LOG_DAEMON|LOG_CRIT,"au= %d\n",au);
#endif
	}

	if (attributes[6])
	{
		char *p=0;
		unsigned long n;

		copy_value(my_ldap_fp, entry, attributes[6], &p, user);
		if (p) {
			if (sscanf(p, "%lu", &n) > 0)
				ag= (gid_t)n;
			free(p);
		}
#if DEBUG_LDAP
		syslog(LOG_DAEMON|LOG_CRIT,"ag= %d\n",ag);
#endif
	}

	if (attributes[8])
		copy_value(my_ldap_fp,entry,attributes[8],&quota, user);

	if (homeDir != 0 && my_ldap.mailroot != 0 && *my_ldap.mailroot)
	{
		char *new_mailroot=malloc(strlen(homeDir)+
					  strlen(my_ldap.mailroot)+2);

		if (!new_mailroot)
		{
			syslog(LOG_DAEMON|LOG_CRIT, "authldap: malloc failed");
			rc= -1;
		}
		else
		{
			strcat(strcat(strcpy(new_mailroot, my_ldap.mailroot),
				      "/"), homeDir);
			free(homeDir);
			homeDir=new_mailroot;
		}
	}

	auth.sysusername=user;
	auth.sysuserid= &au;
	auth.sysgroupid= ag;
	auth.homedir=homeDir;
	auth.address=authaddr;
	auth.fullname=cn;
	auth.maildir=mailDir;
	auth.clearpasswd=userPassword;
	auth.passwd=cryptPassword;
	auth.quota=quota;

	if (auth.sysusername == 0)
		auth.sysusername=auth.address="";

	if (homeDir == 0)
		auth.homedir="";

	rc=0;

	if (au == 0 || ag == 0)
	{
		syslog(LOG_DAEMON|LOG_CRIT,
		       "authlib: refuse to authenticate %s: uid=%d, gid=%d\n",
		       user, au, ag);
		rc= 1;
	}

	if (pass)
	{
		if (my_ldap.authbind) 
		{
			LDAP *bindp=ldapconnect();

			if (!bindp)
				rc=1;
			else
			{
#if HAVE_LDAP_TLS
				if(my_ldap.tls && enable_tls_on(bindp)) {
#if HAVE_SYSLOG_H
					syslog(LOG_DAEMON|LOG_CRIT, "authlib: LDAP_TLS enabled but I'm unable to start tls, check your config\n");
#endif
					rc = 1;
				} else {
#endif
					switch (ldap_simple_bind_s(bindp, dn, (char *)pass))
					{
					case LDAP_SUCCESS:
						break;
					case LDAP_INVALID_CREDENTIALS:
						rc = -1;
						break;
					default:
						rc = 1;
						break;
					}
#if HAVE_LDAP_TLS
				}
#endif
				ldap_unbind(bindp);
			}
			if (rc == 0 && newpass)
			{
				if ((newpass_crypt=authcryptpasswd(newpass,
								   NULL))
				    == 0)
					rc= -1;
			}
		}
		else
		{
			if (auth.clearpasswd)
			{
				if (strcmp(pass,auth.clearpasswd))
					rc= -1;
			}
			else
			{
			const char *p=auth.passwd;

				if (p && strncasecmp(p, "{crypt}", 7) == 0)
					p += 7; /* For authcheckpassword */

				if (!p || authcheckpassword(pass, p))
					rc= -1;
			}

			if (rc == 0 && newpass && auth.passwd)
			{
				if ((newpass_crypt=authcryptpasswd(newpass,
								   auth.passwd)
				     ) == 0)
					rc= -1;
			}
		}
        }

	if (rc == 0 && newpass)
	{
		LDAPMod *mods[3];
		int mod_index=0;

		LDAPMod mod_clear, mod_crypt;
		char *mod_clear_vals[2], *mod_crypt_vals[2];

		if (attributes[3])
		{
			mods[mod_index]= &mod_clear;
			mod_clear.mod_op=LDAP_MOD_REPLACE;
			mod_clear.mod_type=(char *)attributes[3];
			mod_clear.mod_values=mod_clear_vals;

			mod_clear_vals[0]=(char *)newpass;
			mod_clear_vals[1]=NULL;
			++mod_index;
		}

		if (attributes[4] && newpass_crypt)
		{
			mods[mod_index]= &mod_crypt;
			mod_crypt.mod_op=LDAP_MOD_REPLACE;
			mod_crypt.mod_type=(char *)attributes[4];
			mod_crypt.mod_values=mod_crypt_vals;

			mod_crypt_vals[0]=newpass_crypt;
			mod_crypt_vals[1]=NULL;
			++mod_index;
		}
		if (mod_index == 0)
			rc= -1;
		else
		{
			mods[mod_index]=0;

			if (ldap_modify_s(my_ldap_fp, dn, mods))
			{
				rc= -1;
			}
		}
	}

	if (newpass_crypt)
		free(newpass_crypt);
	free (dn);
#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"before callback rc=%d\n",rc);
#endif

	if (rc == 0 && callback)
		rc= (*callback)(&auth, arg);
#if DEBUG_LDAP
	syslog(LOG_DAEMON|LOG_CRIT,"after callback rc=%d\n",rc);
#endif

	ldap_msgfree(result);

	if (homeDir)	free(homeDir);
	if (mailDir)	free(mailDir);
	if (userPassword)	free(userPassword);
	if (cryptPassword)	free(cryptPassword);
	if (cn)		free(cn);
	if (quota)	free(quota);
	return (rc);
}
Пример #12
0
/*
 * dict_ldap_get_values: for each entry returned by a search, get the values
 * of all its attributes. Recurses to resolve any DN or URL values found.
 *
 * This and the rest of the handling of multiple attributes, DNs and URLs
 * are thanks to LaMont Jones.
 */
static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res,
				         VSTRING *result)
{
    static int recursion = 0;
    static int expansion;
    long    entries = 0;
    long    i = 0;
    int     rc = 0;
    LDAPMessage *resloop = 0;
    LDAPMessage *entry = 0;
    BerElement *ber;
    char  **vals;
    char   *attr;
    char   *myname = "dict_ldap_get_values";
    struct timeval tv;
    LDAPURLDesc *url;

    tv.tv_sec = dict_ldap->timeout;
    tv.tv_usec = 0;

    if (++recursion == 1)
	expansion = 0;

    if (msg_verbose)
	msg_info("%s[%d]: Search found %d match(es)", myname, recursion,
		 ldap_count_entries(dict_ldap->ld, res));

    for (entry = ldap_first_entry(dict_ldap->ld, res); entry != NULL;
	 entry = ldap_next_entry(dict_ldap->ld, entry)) {
	ber = NULL;

	/*
	 * LDAP should not, but may produce more than the requested maximum
	 * number of entries.
	 */
	if (dict_errno == 0 && ++entries > dict_ldap->size_limit
	    && dict_ldap->size_limit) {
	    msg_warn("%s[%d]: %s: Query size limit (%ld) exceeded", myname,
		   recursion, dict_ldap->ldapsource, dict_ldap->size_limit);
	    dict_errno = DICT_ERR_RETRY;
	}
	for (attr = ldap_first_attribute(dict_ldap->ld, entry, &ber);
	     attr != NULL;
	     ldap_memfree(attr), attr = ldap_next_attribute(dict_ldap->ld,
							    entry, ber)) {
	    vals = ldap_get_values(dict_ldap->ld, entry, attr);
	    if (vals == NULL) {
		if (msg_verbose)
		    msg_info("%s[%d]: Entry doesn't have any values for %s",
			     myname, recursion, attr);
		continue;
	    }

	    /*
	     * If we previously encountered an error, we still continue
	     * through the loop, to avoid memory leaks, but we don't waste
	     * time accumulating any further results.
	     * 
	     * XXX: There may be a more efficient way to exit the loop with no
	     * leaks, but it will likely be more fragile and not worth the
	     * extra code.
	     */
	    if (dict_errno != 0 || vals[0] == 0) {
		ldap_value_free(vals);
		continue;
	    }

	    /*
	     * The "result_attributes" list enumerates all the requested
	     * attributes, first the ordinary result attribtutes and then the
	     * special result attributes that hold DN or LDAP URL values.
	     * 
	     * The number of ordinary attributes is "num_attributes".
	     * 
	     * We compute the attribute type (ordinary or special) from its
	     * index on the "result_attributes" list.
	     */
	    for (i = 0; dict_ldap->result_attributes->argv[i]; i++) {
		if (strcasecmp(dict_ldap->result_attributes->argv[i], attr) == 0)
		    break;
	    }

	    /*
	     * Append each returned address to the result list, possibly
	     * recursing (for dn or url attributes).
	     */
	    if (i < dict_ldap->num_attributes) {
		/* Ordinary result attribute */
		for (i = 0; vals[i] != NULL; i++) {
		    if (++expansion > dict_ldap->expansion_limit &&
			dict_ldap->expansion_limit) {
			msg_warn("%s[%d]: %s: Expansion limit exceeded at"
			       " result attribute %s=%s", myname, recursion,
				 dict_ldap->ldapsource, attr, vals[i]);
			dict_errno = DICT_ERR_RETRY;
			break;
		    }
		    if (VSTRING_LEN(result) > 0)
			vstring_strcat(result, ",");
		    if (dict_ldap->result_filter == NULL)
			vstring_strcat(result, vals[i]);
		    else
			dict_ldap_expand_filter(dict_ldap->ldapsource,
						dict_ldap->result_filter,
						vals[i], result);
		}
		if (dict_errno != 0)
		    continue;
		if (msg_verbose)
		    msg_info("%s[%d]: search returned %ld value(s) for"
			     " requested result attribute %s",
			     myname, recursion, i, attr);
	    } else if (recursion < dict_ldap->recursion_limit
		       && dict_ldap->result_attributes->argv[i]) {
		/* Special result attribute */
		for (i = 0; vals[i] != NULL; i++) {
		    if (ldap_is_ldap_url(vals[i])) {
			if (msg_verbose)
			    msg_info("%s[%d]: looking up URL %s", myname,
				     recursion, vals[i]);
			rc = ldap_url_parse(vals[i], &url);
			if (rc == 0) {
			    rc = ldap_search_st(dict_ldap->ld, url->lud_dn,
					    url->lud_scope, url->lud_filter,
						url->lud_attrs, 0, &tv,
						&resloop);
			    ldap_free_urldesc(url);
			}
		    } else {
			if (msg_verbose)
			    msg_info("%s[%d]: looking up DN %s",
				     myname, recursion, vals[i]);
			rc = ldap_search_st(dict_ldap->ld, vals[i],
					    LDAP_SCOPE_BASE, "objectclass=*",
					 dict_ldap->result_attributes->argv,
					    0, &tv, &resloop);
		    }
		    switch (rc) {
		    case LDAP_SUCCESS:
			dict_ldap_get_values(dict_ldap, resloop, result);
			break;
		    case LDAP_NO_SUCH_OBJECT:

			/*
			 * Go ahead and treat this as though the DN existed
			 * and just didn't have any result attributes.
			 */
			msg_warn("%s[%d]: DN %s not found, skipping ", myname,
				 recursion, vals[i]);
			break;
		    default:
			msg_warn("%s[%d]: search error %d: %s ", myname,
				 recursion, rc, ldap_err2string(rc));
			dict_errno = DICT_ERR_RETRY;
			break;
		    }

		    if (resloop != 0)
			ldap_msgfree(resloop);

		    if (dict_errno != 0)
			break;
		}
		if (dict_errno != 0)
		    continue;
		if (msg_verbose)
		    msg_info("%s[%d]: search returned %ld value(s) for"
			     " special result attribute %s",
			     myname, recursion, i, attr);
	    } else if (recursion >= dict_ldap->recursion_limit
		       && dict_ldap->result_attributes->argv[i]) {
		msg_warn("%s[%d]: %s: Recursion limit exceeded"
			 " for special attribute %s=%s",
		   myname, recursion, dict_ldap->ldapsource, attr, vals[0]);
		dict_errno = DICT_ERR_RETRY;
	    }
	    ldap_value_free(vals);
	}
	if (ber)
	    ber_free(ber, 0);
    }

    if (msg_verbose)
	msg_info("%s[%d]: Leaving %s", myname, recursion, myname);
    --recursion;
}
Пример #13
0
/*
 **| method: object search ( mapping params );
 **|   This is the preferred way of calling this method.
 **
 **| alt: object search ( string filter );
 **| alt: object search ( string filter, array attrs );
 **| alt: object search ( string filter, array attrs, int attrsonly );
 **| alt: object search ( string filter, array attrs, int attrsonly, int timeout );
 **
 **| general: search the LDAP directory for the specified entry
 **|   (entries). The first form is the preferred one as it
 **|   encompasses all the current and future parameters as expected
 **|   by the underlying API. The following fields are read from the
 **|   mapping:@nl
 **|
 **|   @list
 **|    * base - the base DN to use in this search. Overrides the
 **|      default base DN (as set with set_base_dn)
 **|    * scope - the search scope for this search. Overrides the
 **|      default scope (as set with set_scope)
 **|    * filter - the search filter. The BNF for the filter is as
 **|      follows:
 **|      @pre
 **|        <filter> ::= `(' <filtercomp> `)'
 **|        <filtercomp> ::= <and> | <or> | <not> | <simple>
 **|        <and> ::= `&' <filterlist>
 **|        <or> ::= `|' <filterlist>
 **|        <not> ::= `!' <filter>
 **|        <filterlist> ::= <filter> | <filter> <filterlist>
 **|        <simple> ::= <attributetype> <filtertype> <attributevalue>
 **|        <filtertype> ::= `=' | `~=' | `<=' | `>='
 **|      @pre_end
 **|    * attrs - search attributes. An array of attribute types to
 **|      return in the result. If absent, all types will be returned.
 **|    * attrsonly - if != then the result will contain attribute
 **|      types only - no values shall be returned.
 **|    * timeout - the timeout, in seconds, after which the call
 **|      should return if the search isn't finished.
 **|   @list_end
 */
static void
f_ldap_search(INT32 args)
{
    char                *filter;
    int                  scope;
    struct pike_string  *base;
    char               **attrs;
    int                  attrsonly;
    struct timeval      *timeout;
    LDAPMessage         *res;
    int                  ret;
    struct object       *obj;

    if (!THIS->bound)
        Pike_error("OpenLDAP.Client: attempting operation on an unbound connection\n");
    
    if (!args)
        Pike_error("OpenLDAP.Client->search() requires at least one argument\n");

    if (args == 1) {
        switch(ARG(1).type) {
            case T_MAPPING:
            {
                /* the new style case */
                struct svalue  *val;
                struct mapping *m = ARG(1).u.mapping;

                /*
                 * m->base
                 */
                val = low_mapping_string_lookup(m,
                                                base_str);
                if (!val || val->type != T_STRING)
                    base = THIS->basedn;
                else
                    base = val->u.string;

                /*
                 * m->scope
                 */
                val = low_mapping_string_lookup(m,
                                                scope_str);
                if (!val || val->type != T_INT)
                    scope = THIS->scope;
                else
                    scope = val->u.integer;

                /*
                 * m->filter
                 */
                val = low_mapping_string_lookup(m,
                                                filter_str);
                if (!val || val->type != T_STRING)
                    filter = OL_DEF_FILTER;
                else
                    filter = val->u.string->str;

                /*
                 * m->attrs
                 */
                val = low_mapping_string_lookup(m,
                                                attrs_str);
                if (!val || val->type != T_ARRAY)
                    attrs = NULL;
                else
                    attrs = make_c_array(val);

                /*
                 * m->attrsonly
                 */
                val = low_mapping_string_lookup(m,
                                                attrsonly_str);
                if (!val || val->type != T_INT)
                    attrsonly = 0;
                else
                    attrsonly = val->u.integer != 0;

                /*
                 * m->timeout
                 */
                val = low_mapping_string_lookup(m,
                                                timeout_str);
                if (!val || val->type != T_INT)
                    timeout = NULL;
                else
                    timeout = make_timeout(val->u.integer); /*TEMPORARY*/
                
                break;
            }

            case T_STRING:
                /* the old style case */                
                base = THIS->basedn;
                scope = THIS->scope;
                filter = ARG(1).u.string->str;
                attrs = NULL;
                attrsonly = 0;
                timeout = NULL;
                break;

            default:
                Pike_error("OpenLDAP.Client->search() with single argument requires either a mapping or a string\n");
                break;
        }
    } else switch(args) {
        case 4: /* timeout */
            if (ARG(4).type != T_INT)
                Pike_error("OpenLDAP.Client->search(): argument 4 must be an integer\n");
            else
                timeout = make_timeout(ARG(4).u.integer);
            /* fall through */

        case 3: /* attrsonly */
            if (ARG(3).type != T_INT)
                Pike_error("OpenLDAP.Client->search(): argument 3 must be an integer\n");
            else
                attrsonly = ARG(3).u.integer != 0;
            /* fall through */

        case 2: /* attrs */
            if (ARG(2).type != T_ARRAY)
                Pike_error("OpenLDAP.Client->search(): argument 2 must be an array\n");
            else
                attrs = make_c_array(&ARG(2));

            base = THIS->basedn;
            scope = THIS->scope;
            filter = ARG(1).u.string->str;
            attrsonly = 0;
            timeout = NULL;
            break;

        default:
            Pike_error("OpenLDAP.Client->search(): incorrect number of arguments\n");
            break;
    }

    ret = timeout ?
        ldap_search_st(THIS->conn,
                       base->str,
                       scope,
                       filter,
                       attrs,
                       attrsonly,
                       timeout,
                       &res) :
        ldap_search_s(THIS->conn,
                      base->str,
                      scope,
                      filter,
                      attrs,
                      attrsonly,
                      &res);    
    
    if (ret)
        Pike_error("OpenLDAP.Client->search(): %s\n",
                   ldap_err2string(ret));

    pop_n_elems(args);
    
    THIS->data = res;
    obj = clone_object(result_program, 0);
    push_object(obj);
    
    if (attrs)
        free(attrs);
}
Пример #14
0
static int auth_ldap_do2(const char *user, const char *pass,
			int (*callback)(struct authinfo *, void *),
                        void *arg, const char *newpass)
{
	char *srch;
	struct timeval tv;
	const char *attributes[2];
	LDAPMessage *result, *entry;
	int cnt;
	char *v;
	const char *aname;

	if (ldapopen())	return (1);

	if (my_ldap.emailmap[0] == 0 || strchr(user, '@') == NULL)
		return (auth_ldap_do3(my_ldap.mail,
				      user, pass, callback, arg, newpass,
				      user));
	/* Mapping is not enabled */

	srch=emailmap_get_search_string(my_ldap.emailmap, user);

	if (!srch)
	{
		perror("malloc");
		exit(1);
	}

	tv.tv_sec=my_ldap.timeout;
	tv.tv_usec=0;

	attributes[0]=my_ldap.emailmap_handle;

	if (!attributes[0][0])
		attributes[0]="handle";
	attributes[1]=NULL;

	if (ldaperror(ldap_search_st(my_ldap_fp,
				     (char *)(my_ldap.emailmap_basedn[0] ?
					      my_ldap.emailmap_basedn
					      :my_ldap.basedn),
				     LDAP_SCOPE_SUBTREE,
				     srch, (char **)attributes, 0,
				     &tv, &result)
		      != LDAP_SUCCESS))
	{
		free(srch);

		if (my_ldap_fp)	return (-1);
		return (1);
	}

	if ((cnt=ldap_count_entries(my_ldap_fp, result)) != 1)
	{
		free(srch);

		if (cnt)
			syslog(LOG_DAEMON|LOG_CRIT,
			       "authldap: %d results from search: %s\n",
			       cnt, srch);
		ldap_msgfree(result);
		return -1;
	}
	free(srch);

	entry=ldap_first_entry(my_ldap_fp, result);

	if (!entry)
	{
		ldap_msgfree(result);

		syslog(LOG_DAEMON|LOG_CRIT,
		       "authldap: unexpected NULL from ldap_first_entry");
		return -1;
	}

	copy_value(my_ldap_fp, entry, attributes[0], &v, user);

	if (!v)
	{
		ldap_msgfree(result);
		return (-1);
	}

	aname=my_ldap.emailmap_handle_lookup;
	if (aname[0] == 0)
		aname=my_ldap.mail;

	cnt=auth_ldap_do3(aname, v, pass, callback, arg, newpass, user);

	ldap_msgfree(result);
	free(v);
	return (cnt);
}
Пример #15
0
DWORD
LwLdapDirectorySearch(
    HANDLE hDirectory,
    PCSTR  pszObjectDN,
    int    scope,
    PCSTR  pszQuery,
    PSTR*  ppszAttributeList,
    LDAPMessage** ppMessage
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;
    struct timeval timeout = {0};
    LDAPMessage* pMessage = NULL;

    timeout.tv_sec = 15;
    timeout.tv_usec = 0;

    dwError = ldap_search_st(pDirectory->ld,
                             pszObjectDN,
                             scope,
                             pszQuery,
                             ppszAttributeList,
                             0,
                             &timeout,
                             &pMessage);
    if (dwError) {
        if (dwError == LDAP_NO_SUCH_OBJECT) {
            LW_RTL_LOG_VERBOSE("Caught LDAP_NO_SUCH_OBJECT Error on ldap search");
            BAIL_ON_LDAP_ERROR(dwError);
        }
        if (dwError == LDAP_REFERRAL) {
            LW_RTL_LOG_ERROR("Caught LDAP_REFERRAL Error on ldap search");
            LW_RTL_LOG_ERROR("LDAP Search Info: DN: [%s]", LW_IS_NULL_OR_EMPTY_STR(pszObjectDN) ? "<null>" : pszObjectDN);
            LW_RTL_LOG_ERROR("LDAP Search Info: scope: [%d]", scope);
            LW_RTL_LOG_ERROR("LDAP Search Info: query: [%s]", LW_IS_NULL_OR_EMPTY_STR(pszQuery) ? "<null>" : pszQuery);
            if (ppszAttributeList) {
                size_t i;
                for (i = 0; ppszAttributeList[i] != NULL; i++) {
                    LW_RTL_LOG_ERROR("LDAP Search Info: attribute: [%s]", ppszAttributeList[i]);
                }
            }
            else {
                LW_RTL_LOG_ERROR("Error: LDAP Search Info: no attributes were specified");
            }
        }
        BAIL_ON_LDAP_ERROR(dwError);
    }

    *ppMessage = pMessage;

cleanup:

    return(dwError);

error:

    *ppMessage = NULL;

    if (pMessage)
    {
        ldap_msgfree(pMessage);
    }

    goto cleanup;
}
Пример #16
0
char*
ldap_lookup(config_t agent_config, const char *username, char *external_uid)
{
	LDAP		*ld;
	LDAPMessage	*result = (LDAPMessage *) 0;
	LDAPMessage	*e;
	BerElement	*ber;
	char		*a, *dn;
	char		*sane_username = malloc(strlen(username)*2);
	char		*p = sane_username;
	char		**vals = NULL;
	struct		timeval	ldaptimeout = {.tv_sec = BIND_TIMEOUT, .tv_usec = 0};
	int			i, rc=0, num_entries=0;
	char		*transcoded_query = NULL;
	char		*ldap_uri = NULL;
	char		*end_ptr;
	char		*ldap_host = _ds_read_attribute(agent_config, "ExtLookupServer");
	char		*port = _ds_read_attribute(agent_config, "ExtLookupPort");
	long		lldap_port;
	int			ldap_port = 389;
	char		*ldap_binddn = _ds_read_attribute(agent_config, "ExtLookupLogin");
	char		*ldap_passwd = _ds_read_attribute(agent_config, "ExtLookupPassword");
	char		*ldap_base = _ds_read_attribute(agent_config, "ExtLookupDB");
	char		*ldap_attrs[] = {_ds_read_attribute(agent_config, "ExtLookupLDAPAttribute"),0};
	char		*version = _ds_read_attribute(agent_config, "ExtLookupLDAPVersion");
	long		lldap_version;
	int			ldap_version = 3;
	char		*ldap_filter = _ds_read_attribute(agent_config, "ExtLookupQuery");
	int			ldap_scope;

	if (port != NULL) {
		errno=0;
		lldap_port = strtol(port, &end_ptr, 0);
		if ( (errno != 0) || (lldap_port < INT_MIN) || (lldap_port > INT_MAX) || (*end_ptr != '\0')) {
			LOG(LOG_ERR, "External Lookup: bad LDAP port number");
			return NULL;
		} else
			ldap_port = (int)lldap_port;
	}

	/* set ldap protocol version */
	if (version != NULL) {
		errno=0;
		lldap_version = strtol(version, &end_ptr, 0);
		if ((errno != 0) || (lldap_version < 1) || (lldap_version > 3) || (*end_ptr != '\0')) {
			LOG(LOG_ERR, "External Lookup: bad LDAP protocol version");
			return NULL;
		} else
			ldap_version = (int)lldap_version;
	}
		
	if (_ds_match_attribute(agent_config, "ExtLookupLDAPScope", "one"))
		ldap_scope = LDAP_SCOPE_ONELEVEL;
	else /* defaults to sub */
		ldap_scope = LDAP_SCOPE_SUBTREE;

	/* set alarm handler */
	signal(SIGALRM, sig_alrm);

	/* sanitize username for filter integration */
	for (; *username != '\0'; username++) {
		switch(*username) {
			case 0x2a: /* '*' */
			case 0x28: /* '(' */
			case 0x29: /* ')' */
			case 0x5c: /* '\' */
			case 0x00: /* NUL */
				*p++ = 0x5c; /* '\' */
				*p++ = *username;
				break;

			default:
				*p++ = *username;
				break;
		}
	}

	*p = '\0';

	LOGDEBUG("External Lookup: sanitized username is %s\n", sane_username);

	/* build proper LDAP filter*/
	transcoded_query = strdup(transcode_query(ldap_filter, sane_username, transcoded_query));
	free(sane_username);
	if (transcoded_query == NULL) {
		LOG(LOG_ERR, "External Lookup: %s", ERR_EXT_LOOKUP_MISCONFIGURED); 
		return NULL;
	}

	if( ldap_host != NULL || ldap_port ) {
	/* construct URL */
		LDAPURLDesc url;
		memset( &url, 0, sizeof(url));

		url.lud_scheme = "ldap";
		url.lud_host = ldap_host;
		url.lud_port = ldap_port;
		url.lud_scope = LDAP_SCOPE_SUBTREE;

		ldap_uri = ldap_url_desc2str( &url );
	}

	rc = ldap_initialize( &ld, ldap_uri );
	if( rc != LDAP_SUCCESS ) {
		LOG(LOG_ERR, "External Lookup: Could not create LDAP session handle for URI=%s (%d): %s\n", ldap_uri, rc, ldap_err2string(rc));
		return NULL;
	}

	if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_version ) != LDAP_OPT_SUCCESS ) {
		LOG(LOG_ERR, "External Lookup: Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", ldap_version );
		return NULL;
	}

	/* use TLS if configured */
	if ( _ds_match_attribute(agent_config, "ExtLookupCrypto", "tls" )) {
		if (ldap_version != 3) {
			LOG(LOG_ERR, "External Lookup: TLS only supported with LDAP protocol version 3");
			return NULL;
		}
		if ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
			LOG(LOG_ERR, "External Lookup: %s: %s (%d)", ERR_EXT_LOOKUP_INIT_FAIL, strerror(errno), errno);
			return NULL;
		}
	}

	/* schedules alarm */
	alarm(BIND_TIMEOUT);
	
	/* authenticate to the directory */
	if ( (rc = ldap_simple_bind_s( ld, ldap_binddn, ldap_passwd )) != LDAP_SUCCESS ) {
		/* cancel alarms */
		alarm(0);
		
		LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_INIT_FAIL, ldap_err2string(rc) );
		ldap_unbind(ld);
		return NULL;
	}
	/* cancel alarms */
	alarm(0);
	
	/* search for all entries matching the filter */

	if ( (rc = ldap_search_st( ld, 
				   ldap_base, 
				   ldap_scope,
				   transcoded_query,
				   ldap_attrs, 
				   0,
				   &ldaptimeout, 
				   &result )) != LDAP_SUCCESS ) {

	free(transcoded_query);

	switch(rc) {
		case LDAP_TIMEOUT:
		case LDAP_BUSY:
		case LDAP_UNAVAILABLE:
		case LDAP_UNWILLING_TO_PERFORM:
		case LDAP_SERVER_DOWN:
		case LDAP_TIMELIMIT_EXCEEDED:
			LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_SEARCH_FAIL, ldap_err2string(ldap_result2error(ld, result, 1)) );
			ldap_unbind( ld );
			return NULL;
			break;
		case LDAP_FILTER_ERROR:
			LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_SEARCH_FAIL, ldap_err2string(ldap_result2error(ld, result, 1)) );
			ldap_unbind( ld );
			return NULL;
			break;
		case LDAP_SIZELIMIT_EXCEEDED:
			if ( result == NULL ) {
				LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_SEARCH_FAIL, ldap_err2string(ldap_result2error(ld, result, 1)) );
				ldap_unbind( ld );
				return NULL;
			}
			break;
		default:		       
			LOG(LOG_ERR, "External Lookup: %s: code=%d, %s", ERR_EXT_LOOKUP_SEARCH_FAIL, rc, ldap_err2string(ldap_result2error(ld, result, 1)) );
			ldap_unbind( ld );
			return NULL;
		}
	}

	num_entries=ldap_count_entries(ld,result);

	LOGDEBUG("External Lookup: found %d LDAP entries", num_entries);

    switch (num_entries) {
				case 1: /* only one entry, let's proceed */
					break;
					
				case -1: /* an error occured */
				    LOG(LOG_ERR, "External Lookup: %s: %s", ERR_EXT_LOOKUP_SEARCH_FAIL, ldap_err2string(ldap_result2error(ld, result, 1)));
					ldap_unbind( ld );
					return NULL ;
					
				case 0: /* no entries found */
					LOGDEBUG("External Lookup: %s: no entries found.", ERR_EXT_LOOKUP_SEARCH_FAIL);
					ldap_msgfree( result );
					ldap_unbind( ld );
					return NULL ;

				default: /* more than one entry returned */
					LOG(LOG_ERR, "External Lookup: %s: more than one entry returned.", ERR_EXT_LOOKUP_SEARCH_FAIL);
					ldap_msgfree( result );
					ldap_unbind( ld );
			    	return NULL;
	}

	/* for each entry print out name + all attrs and values */
	for ( e = ldap_first_entry( ld, result ); e != NULL;
	    e = ldap_next_entry( ld, e ) ) {
		if ( (dn = ldap_get_dn( ld, e )) != NULL ) {
		    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++ ) {
					external_uid = strdup(vals[i]);
				}
				ldap_value_free( vals );
			}
			ldap_memfree( a );
		}
		if ( ber != NULL ) {
			ber_free( ber, 0 );
		}
	}
	ldap_msgfree( result );
	ldap_unbind( ld );
	return external_uid;
}
#endif

char*
program_lookup(config_t agent_config, const char *username, char *external_uid)
{
	pid_t wstatus, pid;
	int i, status;
	int fd[2];
	char *output = malloc (1024);
	char **args = malloc (1024);
	char *token;
	char *saveptr;
	char *str;
	char *command_line = 0;
	
    /* build proper command line*/
	command_line = strdup(transcode_query(_ds_read_attribute(agent_config, "ExtLookupServer"), username, command_line));

	if (command_line == NULL) {
		LOG(LOG_ERR, ERR_EXT_LOOKUP_MISCONFIGURED);
		free(output);
		free(args);
		return NULL;
	}

	LOGDEBUG("command line is %s", command_line);
	
	/* break the command line into arguments */
	for (i = 0, str = command_line; ; i++, str = NULL) {
		token = strtok_r(str, " ", &saveptr);
		if (token == NULL)
			break;
		args[i] = token;
		LOGDEBUG("args[%d] = %s",i,token);
	}
	args[i] = (char *) 0;

	if (pipe(fd) == -1) {
		LOG(LOG_ERR, "%s: errno=%i (%s)", ERR_EXT_LOOKUP_INIT_FAIL, errno, strerror(errno));
		free(output);
		free(args);
		return NULL;
	}

	switch(pid=fork()) {

		case -1: /* couldn't fork - something went wrong */
			LOG(LOG_ERR, "%s: errno=%i (%s)", ERR_EXT_LOOKUP_INIT_FAIL, errno, strerror(errno));
			free(output);
			free(args);
			return NULL;

		case 0: /* execute the command and write to fd */
			close(fd[0]);
			dup2(fd[1], fileno(stdout));
			execve(args[0], args, 0);
			exit(EXIT_FAILURE);
			
		default: /* read from fd the first output line */
			do {
				wstatus = waitpid( pid, &status, WUNTRACED | WCONTINUED);
				if (wstatus == -1) {
					LOGDEBUG("waitpid() exited with an error: %s: errno=%i", strerror(errno), errno);
					free(output);
					free(args);
					return NULL;
				}
				if (WIFEXITED(status)) {
					LOGDEBUG("exited, status=%d\n", WEXITSTATUS(status));
					if (WEXITSTATUS(status)) {
						LOGDEBUG("Error running %s. Check path and permissions.\n", args[0]);
					}
				} else if (WIFSIGNALED(status)) {
					LOGDEBUG("killed by signal %d\n", WTERMSIG(status));
				} else if (WIFSTOPPED(status)) {
					LOGDEBUG("stopped by signal %d\n", WSTOPSIG(status));
				} else if (WIFCONTINUED(status)) {
					LOGDEBUG("continued\n");
				}
			} while (!WIFEXITED(status) && !WIFSIGNALED(status));
			close(fd[1]);
			/* just in case there's no line break at the end of the return... */
			memset(output, 0, 1024);
			if (read(fd[0], output, 1024) == -1) {
				LOG(LOG_ERR, "%s: errno=%i (%s)", ERR_EXT_LOOKUP_INIT_FAIL, errno, strerror(errno));
				free(output);
				free(args);
				return NULL;
			}
			close(fd[0]);
	}

	if (strlen(output) == 0) {
		free(output);
		free(args);
		return NULL;
	}
	
	/* terminate the output string at the first \n */
	token = strchr(output, '\n');
	if (token != NULL)
		*token = '\0';
	
	external_uid = strdup(output);
	free(output);
	free(command_line);
	free(args);
	return external_uid;
}
Пример #17
0
static int
do_entry2text_search(
	LDAP			*ld,
	char			*dn,		/* if NULL, use entry */
	char			*base,		/* if NULL, no search actions */
	LDAPMessage		*entry, 	/* if NULL, use dn */
	struct ldap_disptmpl*	tmpllist,	/* if NULL, load default file */
	char			**defattrs,
	char			***defvals,
	writeptype		writeproc,
	void			*writeparm,
	char			*eol,
	int			rdncount,	/* if 0, display full DN */
	unsigned int		opts,
	char			*urlprefix
)
{
    int				err, freedn, freetmpls, html;
    char			*buf, **fetchattrs, **vals;
    LDAPMessage			*ldmp;
    struct ldap_disptmpl	*tmpl;
    struct timeval		timeout;

    if ( dn == NULL && entry == NULLMSG ) {
	ld->ld_errno = LDAP_PARAM_ERROR;
	return( ld->ld_errno );
    }

    html = ( urlprefix != NULL );

    timeout.tv_sec = SEARCH_TIMEOUT_SECS;
    timeout.tv_usec = 0;

    if (( buf = malloc( LDAP_DTMPL_BUFSIZ )) == NULL ) {
	ld->ld_errno = LDAP_NO_MEMORY;
	return( ld->ld_errno );
    }

    freedn = freetmpls = 0;
    tmpl = NULL;

    if ( tmpllist == NULL ) {
	if (( err = ldap_init_templates( TEMPLATEFILE, &tmpllist )) != 0 ) {
	    sprintf( buf, "%sUnable to read template file %s (error %d)%s%s",
		    html ? "<!-- " : "", TEMPLATEFILE, err,
		    html ? "-->" : "", eol );
	    (*writeproc)( writeparm, buf, strlen( buf ));
	}
	freetmpls = 1;
    }

    if ( dn == NULL ) {
	if (( dn = ldap_get_dn( ld, entry )) == NULL ) {
	    free( buf );
	    if ( freetmpls ) {
		ldap_free_templates( tmpllist );
	    }
	    return( ld->ld_errno );
	}
	freedn = 1;
    }


    if ( tmpllist != NULL ) {
	ldmp = NULLMSG;

	if ( entry == NULL ) {
	    char	*ocattrs[2];

	    ocattrs[0] = OCATTRNAME;
	    ocattrs[1] = NULL;
#ifdef CLDAP
	    if ( LDAP_IS_CLDAP( ld ))
		    err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE,
			"objectClass=*", ocattrs, 0, &ldmp, NULL );
	    else
#endif /* CLDAP */
		    err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE,
			    "objectClass=*", ocattrs, 0, &timeout, &ldmp );

	    if ( err == LDAP_SUCCESS ) {
		entry = ldap_first_entry( ld, ldmp );
	    }
	}

	if ( entry != NULL ) {
	    vals = ldap_get_values( ld, entry, OCATTRNAME );
	    tmpl = ldap_oc2template( vals, tmpllist );
	    if ( vals != NULL ) {
		ldap_value_free( vals );
	    }
	}
	if ( ldmp != NULL ) {
	    ldap_msgfree( ldmp );
	}
    }

    entry = NULL;

    if ( tmpl == NULL ) {
	fetchattrs = NULL;
    } else {
	fetchattrs = ldap_tmplattrs( tmpl, NULL, 1, LDAP_SYN_OPT_DEFER );
    }

#ifdef CLDAP
    if ( LDAP_IS_CLDAP( ld ))
	err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
		fetchattrs, 0, &ldmp, NULL );
    else
#endif /* CLDAP */
	err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
		fetchattrs, 0, &timeout, &ldmp );

    if ( freedn ) {
	free( dn );
    }
    if ( fetchattrs != NULL ) {
	ldap_value_free( fetchattrs );
    }

    if ( err != LDAP_SUCCESS ||
	    ( entry = ldap_first_entry( ld, ldmp )) == NULL ) {
	if ( freetmpls ) {
            ldap_free_templates( tmpllist );
        }
	free( buf );
	return( ld->ld_errno );
    }

    err = do_entry2text( ld, buf, base, entry, tmpl, defattrs, defvals,
	    writeproc, writeparm, eol, rdncount, opts, urlprefix );

    free( buf );
    if ( freetmpls ) {
	ldap_free_templates( tmpllist );
    }
    ldap_msgfree( ldmp );
    return( err );
}
Пример #18
0
static int
searchaction( LDAP *ld, char *buf, char *base, LDAPMessage *entry, char *dn,
	struct ldap_tmplitem *tip, int labelwidth, int rdncount,
	writeptype writeproc, void *writeparm, char *eol, char *urlprefix )
{
    int			err, lderr, i, count, html;
    char		**vals, **members;
    char		*value, *filtpattern, *attr, *selectname;
    char		*retattrs[2], filter[ 256 ];
    LDAPMessage		*ldmp;
    struct timeval	timeout;

    html = ( urlprefix != NULL );

    for ( i = 0; tip->ti_args != NULL && tip->ti_args[ i ] != NULL; ++i ) {
	;
    }
    if ( i < 3 ) {
	return( LDAP_PARAM_ERROR );
    }
    attr = tip->ti_args[ 0 ];
    filtpattern = tip->ti_args[ 1 ];
    retattrs[ 0 ] = tip->ti_args[ 2 ];
    retattrs[ 1 ] = NULL;
    selectname = tip->ti_args[ 3 ];

    vals = NULL;
    if ( attr == NULL ) {
	value = NULL;
    } else if ( strcasecmp( attr, "-dnb" ) == 0 ) {
	return( LDAP_PARAM_ERROR );
    } else if ( strcasecmp( attr, "-dnt" ) == 0 ) {
	value = dn;
    } else if (( vals = ldap_get_values( ld, entry, attr )) != NULL ) {
	value = vals[ 0 ];
    } else {
	value = NULL;
    }

    ldap_build_filter( filter, sizeof( filter ), filtpattern, NULL, NULL, NULL,
	    value, NULL );

    if ( html ) {
	/*
	 * if we are generating HTML, we add an HREF link that embodies this
	 * search action as an LDAP URL, instead of actually doing the search
	 * now.
	 */
	sprintf( buf, "<DT><A HREF=\"%s", urlprefix );
	if ( base != NULL ) {
	    strcat_escaped( buf, base );
	}
	strcat( buf, "??sub?" );
	strcat_escaped( buf, filter );
	sprintf( buf + strlen( buf ), "\"><B>%s</B></A><DD><BR>%s",
		tip->ti_label, eol );
	if ((*writeproc)( writeparm, buf, strlen( buf )) < 0 ) {
	    return( LDAP_LOCAL_ERROR );
	}
	return( LDAP_SUCCESS );
    }

    timeout.tv_sec = SEARCH_TIMEOUT_SECS;
    timeout.tv_usec = 0;

#ifdef CLDAP
    if ( LDAP_IS_CLDAP( ld ))
	lderr = cldap_search_s( ld, base, LDAP_SCOPE_SUBTREE, filter, retattrs,
		0, &ldmp, NULL );
    else
#endif /* CLDAP */
	lderr = ldap_search_st( ld, base, LDAP_SCOPE_SUBTREE, filter, retattrs,
		0, &timeout, &ldmp );

    if ( lderr == LDAP_SUCCESS || NONFATAL_LDAP_ERR( lderr )) {
	if (( count = ldap_count_entries( ld, ldmp )) > 0 ) {
	    if (( members = (char **)malloc( (count + 1) * sizeof(char *)))
		    == NULL ) {
		err = LDAP_NO_MEMORY;
	    } else {
		for ( i = 0, entry = ldap_first_entry( ld, ldmp );
			entry != NULL;
			entry = ldap_next_entry( ld, entry ), ++i ) {
		    members[ i ] = ldap_get_dn( ld, entry );
		}
		members[ i ] = NULL;

		ldap_sort_values( ld, members, ldap_sort_strcasecmp );

		err = do_vals2text( ld, NULL, members, tip->ti_label,
			html ? -1 : 0, LDAP_SYN_DN, writeproc, writeparm,
			eol, rdncount, urlprefix );

		ldap_value_free( members );
	    }
	}
	ldap_msgfree( ldmp );
    }

    
    if ( vals != NULL ) {
	ldap_value_free( vals );
    }

    return(( err == LDAP_SUCCESS ) ? lderr : err );
}
Пример #19
0
/*
 * ldap_getattr_fromfilter_withbase_scope():
 *   conflags: KEEPALIVE
 *   scope: LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE
 *   result: return unique search result here, allocated here, caller must free
 *
 * returns: -1 on error
 *           0 nothing found
 *           1 successfull search, result int 'result'
 *
 * All connection managment to the LDAP server is done here. Just set KEEPALIVE if you know
 * you will be dispatching more than one search in a row, then don't set it with the last search.
 * You MUST dispatch the queries timely, otherwise the LDAP handle might timeout.
 */
static int ldap_getattr_fromfilter_withbase_scope( const char *searchbase,
                                                   const char *filter,
                                                   char *attributes[],
                                                   int scope,
                                                   ldapcon_t conflags,
                                                   char **result) {
    int ret;
    int ldaperr;
    int retrycount = 0;
    int desired_version  = LDAP_VERSION3;
    static int ldapconnected = 0;
    static LDAP *ld     = NULL;
    LDAPMessage* msg    = NULL;
    LDAPMessage* entry  = NULL;
    char **attribute_values = NULL;
    struct timeval timeout;

    LOG(log_maxdebug, logtype_afpd,"ldap: BEGIN");

    timeout.tv_sec = 3;
    timeout.tv_usec = 0;

    /* init LDAP if necessary */
retry:
    ret = 0;

    if (ld == NULL) {
        LOG(log_maxdebug, logtype_default, "ldap: server: \"%s\"",
            ldap_server);
        if ((ld = ldap_init(ldap_server, LDAP_PORT)) == NULL ) {
            LOG(log_error, logtype_default, "ldap: ldap_init error: %s",
                strerror(errno));
            return -1;
        }
        if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version) != 0) {
            /* LDAP_OPT_SUCCESS is not in the proposed standard, so we check for 0
               http://tools.ietf.org/id/draft-ietf-ldapext-ldap-c-api-05.txt */
            LOG(log_error, logtype_default, "ldap: ldap_set_option failed!");
            free(ld);
            ld = NULL;
            return -1;
        }
    }

    /* connect */
    if (!ldapconnected) {
        if (LDAP_AUTH_NONE == ldap_auth_method) {
            if (ldap_bind_s(ld, "", "", LDAP_AUTH_SIMPLE) != LDAP_SUCCESS ) {
                LOG(log_error, logtype_default, "ldap: ldap_bind failed, auth_method: \'%d\'",
                    ldap_auth_method);
                free(ld);
                ld = NULL;
                return -1;
            }
            ldapconnected = 1;

        } else if (LDAP_AUTH_SIMPLE == ldap_auth_method) {
            if (ldap_bind_s(ld, ldap_auth_dn, ldap_auth_pw, ldap_auth_method) != LDAP_SUCCESS ) {
                LOG(log_error, logtype_default,
                    "ldap: ldap_bind failed: ldap_auth_dn: \'%s\', ldap_auth_pw: \'%s\', ldap_auth_method: \'%d\'",
                    ldap_auth_dn, ldap_auth_pw, ldap_auth_method);
                free(ld);
                ld = NULL;
                return -1;
            }
            ldapconnected = 1;
        }
    }

    LOG(log_maxdebug, logtype_afpd, "ldap: start search: base: %s, filter: %s, attr: %s",
        searchbase, filter, attributes[0]);

    /* start LDAP search */
    ldaperr = ldap_search_st(ld, searchbase, scope, filter, attributes, 0, &timeout, &msg);
    LOG(log_maxdebug, logtype_default, "ldap: ldap_search_st returned: %s",
        ldap_err2string(ldaperr));
    if (ldaperr != LDAP_SUCCESS) {
        LOG(log_error, logtype_default, "ldap: ldap_search_st failed: %s, retrycount: %i",
            ldap_err2string(ldaperr), retrycount);
        ret = -1;
        goto cleanup;
    }

    /* parse search result */
    LOG(log_maxdebug, logtype_default, "ldap: got %d entries from ldap search",
        ldap_count_entries(ld, msg));
    if ((ret = ldap_count_entries(ld, msg)) != 1) {
        ret = 0;
        goto cleanup;
    }

    entry = ldap_first_entry(ld, msg);
    if (entry == NULL) {
        LOG(log_error, logtype_default, "ldap: ldap_first_entry error");
        ret = -1;
        goto cleanup;
    }
    attribute_values = ldap_get_values(ld, entry, attributes[0]);
    if (attribute_values == NULL) {
        LOG(log_error, logtype_default, "ldap: ldap_get_values error");
        ret = -1;
        goto cleanup;
    }

    LOG(log_maxdebug, logtype_afpd,"ldap: search result: %s: %s",
        attributes[0], attribute_values[0]);

    /* allocate result */
    *result = strdup(attribute_values[0]);
    if (*result == NULL) {
        LOG(log_error, logtype_default, "ldap: strdup error: %s",strerror(errno));
        ret = -1;
        goto cleanup;
    }

cleanup:
    if (attribute_values)
        ldap_value_free(attribute_values);
    /* FIXME: is there another way to free entry ? */
    while (entry != NULL)
        entry = ldap_next_entry(ld, entry);
    if (msg)
        ldap_msgfree(msg);

    if (ldapconnected) {
        if ((ret == -1) || !(conflags & KEEPALIVE)) {
            LOG(log_maxdebug, logtype_default,"ldap: unbind");
            if (ldap_unbind_s(ld) != 0) {
                LOG(log_error, logtype_default, "ldap: unbind: %s\n", ldap_err2string(ldaperr));
                return -1;
            }
            ld = NULL;
            ldapconnected = 0;

            /* In case of error we try twice */
            if (ret == -1) {
                retrycount++;
                if (retrycount < 2)
                    goto retry;
            }
        }
    }
    return ret;
}
Пример #20
0
static int
do_entry2text_search(
	LDAP			*ld,
	char			*dn,		/* if NULL, use entry */
	char			*base,		/* if NULL, no search actions */
	LDAPMessage		*entry,		/* if NULL, use dn */
	struct ldap_disptmpl*	tmpllist,	/* if NULL, no template used */
	char			**defattrs,
	char			***defvals,
	writeptype		writeproc,
	void			*writeparm,
	char			*eol,
	int			rdncount,	/* if 0, display full DN */
	unsigned long		opts,
	char			*urlprefix
)
{
    int				err, freedn, html;
    char			*buf, **fetchattrs, **vals;
    LDAPMessage			*ldmp;
    struct ldap_disptmpl	*tmpl;
    struct timeval		timeout;

    if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
	return( LDAP_PARAM_ERROR );
    }

    if ( dn == NULL && entry == NULLMSG ) {
	err = LDAP_PARAM_ERROR;
	LDAP_SET_LDERRNO( ld, err, NULL, NULL );
	return( err );
    }

    html = ( urlprefix != NULL );

    timeout.tv_sec = SEARCH_TIMEOUT_SECS;
    timeout.tv_usec = 0;

    if (( buf = NSLDAPI_MALLOC( LDAP_DTMPL_BUFSIZ )) == NULL ) {
	err = LDAP_NO_MEMORY;
	LDAP_SET_LDERRNO( ld, err, NULL, NULL );
	return( err );
    }

    freedn = 0;
    tmpl = NULL;

    if ( dn == NULL ) {
	if (( dn = ldap_get_dn( ld, entry )) == NULL ) {
	    NSLDAPI_FREE( buf );
	    return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
	}
	freedn = 1;
    }


    if ( tmpllist != NULL ) {
	ldmp = NULLMSG;

	if ( entry == NULL ) {
	    char	*ocattrs[2];

	    ocattrs[0] = OCATTRNAME;
	    ocattrs[1] = NULL;
#ifdef CLDAP
	    if ( LDAP_IS_CLDAP( ld ))
		    err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE,
			"objectClass=*", ocattrs, 0, &ldmp, NULL );
	    else
#endif /* CLDAP */
		    err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE,
			    "objectClass=*", ocattrs, 0, &timeout, &ldmp );

	    if ( err == LDAP_SUCCESS ) {
		entry = ldap_first_entry( ld, ldmp );
	    }
	}

	if ( entry != NULL ) {
	    vals = ldap_get_values( ld, entry, OCATTRNAME );
	    tmpl = ldap_oc2template( vals, tmpllist );
	    if ( vals != NULL ) {
		ldap_value_free( vals );
	    }
	}
	if ( ldmp != NULL ) {
	    ldap_msgfree( ldmp );
	}
    }

    entry = NULL;

    if ( tmpl == NULL ) {
	fetchattrs = NULL;
    } else {
	fetchattrs = ldap_tmplattrs( tmpl, NULL, 1, LDAP_SYN_OPT_DEFER );
    }

#ifdef CLDAP
    if ( LDAP_IS_CLDAP( ld ))
	err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
		fetchattrs, 0, &ldmp, NULL );
    else
#endif /* CLDAP */
	err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
		fetchattrs, 0, &timeout, &ldmp );

    if ( freedn ) {
	NSLDAPI_FREE( dn );
    }
    if ( fetchattrs != NULL ) {
	ldap_value_free( fetchattrs );
    }

    if ( err != LDAP_SUCCESS ||
	    ( entry = ldap_first_entry( ld, ldmp )) == NULL ) {
	NSLDAPI_FREE( buf );
	return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
    }

    err = do_entry2text( ld, buf, base, entry, tmpl, defattrs, defvals,
	    writeproc, writeparm, eol, rdncount, opts, urlprefix );

    NSLDAPI_FREE( buf );
    ldap_msgfree( ldmp );
    return( err );
}
Пример #21
0
int ldapLogin(char *thisUid, char *thisPwd, struct threadInfo * ti) {
	extern struct threadInfo *pMainThreadInfo;

	int (*dbConnect)(struct threadStorageInfo *);
	void (*dbDisconnect)(struct threadStorageInfo *);
	int (*dbCookie)(char *, int, struct threadStorageInfo *);
	int (*dbInsert)(char *, int, struct threadStorageInfo *);

	dbConnect = pMainThreadInfo->dbInfo.connect;
	dbDisconnect = pMainThreadInfo->dbInfo.disconnect;
	dbCookie = pMainThreadInfo->dbInfo.cookie;
	dbInsert = pMainThreadInfo->dbInfo.insert;

	if(thisUid == NULL) {
		return(-1);
	}

	if((ti->directoryInfo.ldapUri = configFetch("ldap_uri", &ti->directoryInfo.i)) == NULL) {
		ti->directoryInfo.ldapUri = LDAP_MYURI;
	}

	if((ti->directoryInfo.ldapUsername = configFetch("ldap_username", &ti->directoryInfo.i)) == NULL) {
		ti->directoryInfo.ldapUsername = LDAP_MYUSERNAME;
	}

	if((ti->directoryInfo.ldapPassword = configFetch("ldap_password", &ti->directoryInfo.i)) == NULL) {
		ti->directoryInfo.ldapPassword = LDAP_MYPASSWORD;
	}

	if((ti->directoryInfo.ldapAttr = configFetch("ldap_searchattr", &ti->directoryInfo.i)) == NULL) {
		ti->directoryInfo.ldapAttr = LDAP_MYATTR;
	}

	if((ti->directoryInfo.ldapBase = configFetch("ldap_searchbase", &ti->directoryInfo.i)) == NULL) {
		ti->directoryInfo.ldapBase = LDAP_MYBASE;
	}

	if((ti->directoryInfo.ldapFilter = configFetch("ldap_searchfilter", &ti->directoryInfo.i)) == NULL) {
		ti->directoryInfo.ldapFilter = LDAP_MYFILTER;
	}

	if(ldap_initialize(&ti->directoryInfo.l, ti->directoryInfo.ldapUri) != LDAP_SUCCESS) {
		ldapMessage(ti, ERROR_SLIGHT, "Error occurred while trying to initialize LDAP connection", NULL);

		return(-1);
	}

	ti->directoryInfo.v = LDAP_MYVERSION;

	if(ldap_set_option(ti->directoryInfo.l, LDAP_OPT_PROTOCOL_VERSION, (int *) &ti->directoryInfo.v) != LDAP_OPT_SUCCESS) {
		ldapMessage(ti, ERROR_SLIGHT, "Error occurred while trying to initialize LDAP connection", NULL);

		ldap_unbind(ti->directoryInfo.l);

		return(-1);
	}

	if(ti->directoryInfo.ldapUsername != NULL && ti->directoryInfo.ldapUsername[0] != 0) {
		if(ldap_bind_s(ti->directoryInfo.l, ti->directoryInfo.ldapUsername, ti->directoryInfo.ldapPassword, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) {
			ldapMessage(ti, ERROR_SLIGHT, "Error occurred while trying to establish LDAP connection", ti->directoryInfo.ldapUsername);

			ldap_unbind(ti->directoryInfo.l);

			return(-1);
		}
	}

	ti->directoryInfo.timeVal.tv_sec = LDAP_MYTIMEOUT;
	ti->directoryInfo.timeVal.tv_usec = 0;

	if(ldap_search_st(ti->directoryInfo.l, ti->directoryInfo.ldapBase, LDAP_SCOPE_SUBTREE, ti->directoryInfo.ldapFilter, NULL, 0, &ti->directoryInfo.timeVal, &ti->directoryInfo.m) != LDAP_SUCCESS) {
		ldapMessage(ti, ERROR_SLIGHT, "Error occurred while trying to search from LDAP database", ti->directoryInfo.ldapFilter);

		ldap_unbind(ti->directoryInfo.l);

		return(-1);
	}

	if(ldap_count_entries(ti->directoryInfo.l, ti->directoryInfo.m) <= 0) {
		ldapMessage(ti, ERROR_SLIGHT, "Search from LDAP database returned no entries", ti->directoryInfo.ldapFilter);

		ldap_msgfree(ti->directoryInfo.m);
		ldap_unbind(ti->directoryInfo.l);

		return(-1);
	}

	if((ti->directoryInfo.e = ldap_first_entry(ti->directoryInfo.l, ti->directoryInfo.m)) == NULL) {
		ldapMessage(ti, ERROR_SLIGHT, "Search from LDAP database returned no entries", ti->directoryInfo.ldapFilter);

		ldap_msgfree(ti->directoryInfo.m);
		ldap_unbind(ti->directoryInfo.l);

		return(-1);
	}

	if((ti->directoryInfo.d = ldap_get_dn(ti->directoryInfo.l, ti->directoryInfo.e)) == NULL) {
		ldapMessage(ti, ERROR_SLIGHT, "Search from LDAP database returned no entries", ti->directoryInfo.ldapFilter);

		ldap_msgfree(ti->directoryInfo.m);
		ldap_unbind(ti->directoryInfo.l);

		return(-1);
	}

	snprintf(ti->directoryInfo.dnSpace, sizeof(ti->directoryInfo.dnSpace), "%s=%s,%s%c", ti->directoryInfo.ldapAttr, thisUid, ti->directoryInfo.d, 0);

	ldap_memfree(ti->directoryInfo.d);
	ldap_msgfree(ti->directoryInfo.m);

	if(ldap_bind_s(ti->directoryInfo.l, ti->directoryInfo.dnSpace, thisPwd, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) {
		ldapMessage(ti, ERROR_SLIGHT, "Authentication against LDAP failed", ti->directoryInfo.dnSpace);

		ldap_unbind(ti->directoryInfo.l);

		return(-1);
	}

	ldap_unbind(ti->directoryInfo.l);

	ti->directoryInfo.l = NULL;

	if(dbConnect(&ti->storageInfo) == 0) {
		if(dbCookie(thisUid, strlen(thisUid), &ti->storageInfo) != 0) {
			ldapMessage(ti, ERROR_SLIGHT, "Authentication against LDAP failed", "Error occurred while trying to create session");

			dbDisconnect(&ti->storageInfo);

			return(-1);
		}

		if(dbInsert(thisUid, strlen(thisUid), &ti->storageInfo) != 0) {
			ldapMessage(ti, ERROR_SLIGHT, "Authentication against LDAP failed", "Error occurred while trying to create session");

			dbDisconnect(&ti->storageInfo);

			return(-1);
		}

		dbDisconnect(&ti->storageInfo);

		return(0);
	}
	else {
		ldapMessage(ti, ERROR_SLIGHT, "Authentication against LDAP failed", "Error occurred while trying to create session");

		return(-1);
	}
}
/*
 * fetches a binary blob from an ldap url
 */
static err_t
fetch_ldap_url(char *url, chunk_t *blob)
{
    LDAPURLDesc *lurl;
    err_t ugh = NULL;
    int rc;

    DBG(DBG_CONTROL,
	DBG_log("Trying LDAP URL '%s'", url)
    )

    rc = ldap_url_parse(url, &lurl);
    
    if (rc == LDAP_SUCCESS)
    {
	LDAP *ldap = ldap_init(lurl->lud_host, lurl->lud_port);

	if (ldap != NULL)
	{
	    int ldap_version = (LDAP_VER == 2)? LDAP_VERSION2 : LDAP_VERSION3;
	    struct timeval timeout;

	    timeout.tv_sec  = FETCH_CMD_TIMEOUT;
	    timeout.tv_usec = 0;
	    ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
	    ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);

	    rc = ldap_simple_bind_s(ldap, NULL, NULL);

	    if (rc == LDAP_SUCCESS)
	    {
		LDAPMessage *result;

		timeout.tv_sec = FETCH_CMD_TIMEOUT;
		timeout.tv_usec = 0;
		
		rc = ldap_search_st(ldap, lurl->lud_dn
					, lurl->lud_scope
					, lurl->lud_filter
					, lurl->lud_attrs
					, 0, &timeout, &result);

		if (rc == LDAP_SUCCESS)
		{
		    ugh = parse_ldap_result(ldap, result, blob);
		    ldap_msgfree(result);
		}
		else
		{
		    ugh = ldap_err2string(rc);
		}
	    }
	    else
	    {
		ugh = ldap_err2string(rc);
	    }
	    ldap_unbind_s(ldap);
	}
	else
	{
	    ugh = "ldap init";
	}
	ldap_free_urldesc(lurl);
    }
    else
    {
	ugh = ldap_err2string(rc);
    }
    return ugh;
}
Пример #23
0
int
do_search(
    REQUEST         *r,
    RESPONSE        *resp
)
{
    char            *filtertype, **search_attrs, *search_filter;
    char            *print_filter, *human_filter;
    int             scope, count = 0, rc, i = 0, j, in_home;
    int option_param;
    struct timeval  timeout;
    LDAPFiltInfo    *fi;
    LDAPMessage     *e, *res;
    static char     *def_attrs[] = 
                {"objectClass", "sn", "aliasedObjectName", "labeledURI", 0};
    struct ldap_disptmpl    *tmpl;
    char    **oc;
    char    *result_dn, *doc, *foc, *url_dn;
    char    *base_dn, *base_ufn, *result_ufn, *alias_ufn, *sortstring, *cp, *bp;
    char    **sn, href[10 * BUFSIZ], *temp, **val, *server = NULL;
    int     counter = 0, base_len, isalias = 0;

#ifdef WEB500GW_DEBUG
    Web500gw_debug(WEB500GW_DEBUG_TRACE, "do_search (%s, %s, (",
        r->r_dn, flag2string(r->r_flags), 0, 0);
    while (r->r_attrs && r->r_attrs[i]) {
        Web500gw_debug(WEB500GW_DEBUG_TRACE, "%s ", r->r_attrs[i], 0, 0, 0);
        i++;
    }
    Web500gw_debug(WEB500GW_DEBUG_TRACE, "), %s)\n", 
        (r->r_filter && *r->r_filter) ? r->r_filter : "No filter", 0, 0, 0);
#endif

    if (r->r_ld == (LDAP *)0 &&
        (r->r_ld = web500gw_ldap_init(r, resp, NULL, NULL, 1)) == NULL)
        return NOTOK;

    base_dn = r->r_dn;
    if (strlen(base_dn) > 0) {
        base_ufn = friendly_dn(resp, base_dn);
    } else {
        base_ufn = NULL;
    }
    base_len = base_ufn ? strlen(base_ufn) : 0;


    if (r->r_filter == NULL) {
        return NOTOK;
    }
    print_filter = r->r_filter;
#if defined(OWN_STR_TRANSLATION)
    search_filter = strdup(web500gw_isotot61(r->r_filter));
#else
    search_filter = r->r_filter;
#endif
    if (*search_filter == '\0' || *(search_filter+1) != '=') {
        scope = LDAP_SCOPE_ONELEVEL;
    } else {
        if (*search_filter == 'S') {
            scope = LDAP_SCOPE_SUBTREE;
        } else {
            scope = LDAP_SCOPE_ONELEVEL;
        }
        search_filter += 2;
        print_filter += 2;
    }

    /* make a "human readable filter" - for now, no artistic things are done */
    human_filter = print_filter;
    if ((cp = strchr(print_filter, '=')) != NULL) {
        if ((cp = strchr(cp+1, '=')) != NULL) {
            /* two '=' in it - must be a complex filter - isn't readable... */
            human_filter = MSG_COMPLEX_FILTER;
        }
    }

    if (*search_filter) {   /* not the default filter */
        r->r_flags |= FLAG_FILTER;
                            /* skip leading white spaces */
        while (isspace(*search_filter)) ++search_filter;
    }
    if (r->r_attrs == NULL || *r->r_attrs == NULL) {
        /* No attributes requested - read default attrs for sorting */
        search_attrs = def_attrs;
    } else {
        j = 0;
        while (def_attrs[j]) j++;
        search_attrs = (char **) calloc(r->r_attrnumb + j + 1, sizeof(char *));
        i = j = 0;
        while (r->r_attrs && r->r_attrs[i])  {
            search_attrs[i] = r->r_attrs[i];
            i++;
        }
        while (def_attrs[j]) 
            search_attrs[i++] = def_attrs[j++];    
        search_attrs[i] = NULL;
    }

    if ((in_home = isinhome(base_dn)))
        /* ACCESS sizelimit if searching below HOME DN */
        ldap_set_option(r->r_ld, LDAP_OPT_SIZELIMIT, &(r->r_access->a_sizelimit));
    else
        ldap_set_option(r->r_ld, LDAP_OPT_SIZELIMIT, &sizelimit);

    /* A simple filter (not starting with '(') with a comma in it 
     *  -> UFN assumed */

    /*    if (ufnsearch && search_filter[0] != '(' && 
        strchr(search_filter, ',') != NULL && strlen(search_filter) > 3) {
        if (strlen(base_dn) > 0)
            ldap_ufn_setprefix(r->r_ld, base_dn);
        timeout.tv_sec = timelimit;
        timeout.tv_usec = 0;
        ldap_ufn_timeout((void *) &timeout);

	option_param = LDAP_DEREF_FINDING;
	ldap_set_option(r->r_ld, LDAP_OPT_DEREF, (void *) &option_param);
#ifdef WEB500GW_DEBUG
        Web500gw_debug(WEB500GW_DEBUG_TRACE, "ldap_ufn_search_s (%s)\n", 
            search_filter, 0, 0, 0);
#endif
        if ((rc = ldap_ufn_search_s(r->r_ld, search_filter, search_attrs, 0, &res))
            != LDAP_SUCCESS && rc != LDAP_SIZELIMIT_EXCEEDED) {
            do_error(r, resp, rc, 0, get_ldap_result_code(r->r_ld), get_ldap_matched_str(r->r_ld));
            return NOTOK;
        }
        count = ldap_count_entries(r->r_ld, res);
#ifdef WEB500GW_DEBUG
        Web500gw_debug(WEB500GW_DEBUG_TRACE, "UFN ready: %d results!\n",
            count, 0, 0, 0);
#endif
        // Reset DN, because this UFN search was probably not below DN
        base_dn = base_ufn = "";
        in_home = 0;

        friendlyDesc = MSG_UFN;

	} else { */
        /* let's do the search */
        filtertype = (scope == LDAP_SCOPE_ONELEVEL ? "web500gw onelevel" :
            "web500gw subtree");

	option_param = (scope == LDAP_SCOPE_ONELEVEL ? LDAP_DEREF_FINDING : LDAP_DEREF_ALWAYS);

	ldap_set_option(r->r_ld, LDAP_OPT_DEREF, 
			(void *) &option_param);
        timeout.tv_sec = timelimit;
        timeout.tv_usec = 0;
    
        friendlyDesc = NULL;

        /* try all filters til we have success */
        for (fi = ldap_getfirstfilter(r->r_access->a_filtd, filtertype, search_filter);
            fi != NULL; fi = ldap_getnextfilter(r->r_access->a_filtd)) {
#ifdef WEB500GW_DEBUG
            Web500gw_debug(WEB500GW_DEBUG_FILTER, "  search %s: %s -- %s\n",
                scope == LDAP_SCOPE_ONELEVEL ? "onelevel" : "subtree",
                fi->lfi_filter, fi->lfi_desc, 0);
#endif
            if ((rc = ldap_search_st(r->r_ld, base_dn, scope, fi->lfi_filter,
                search_attrs, 0, &timeout, &res)) != LDAP_SUCCESS && 
                rc != LDAP_SIZELIMIT_EXCEEDED && rc != LDAP_INSUFFICIENT_ACCESS 
                && rc != LDAP_TIMELIMIT_EXCEEDED && rc != LDAP_TIMEOUT
                && rc != LDAP_PARTIAL_RESULTS) {
                do_error(r, resp, rc, 0, get_ldap_result_code(r->r_ld), get_ldap_matched_str(r->r_ld));
                return NOTOK;
            }
            if ((count = ldap_count_entries(r->r_ld, res)) > 0) {
                /* found something */
                friendlyDesc = friendly_label(resp, fi->lfi_desc);
#ifdef WEB500GW_DEBUG
                Web500gw_debug(WEB500GW_DEBUG_FILTER, 
                    " searched ... and found %d results!\n", count, 0, 0, 0);
#endif
                break;
            }
#ifdef WEB500GW_DEBUG
            Web500gw_debug(WEB500GW_DEBUG_FILTER, 
                " searched ... and found no results!\n", 0, 0, 0, 0);
#endif
        }
	option_param = LDAP_DEREF_ALWAYS;
	ldap_set_option(r->r_ld, LDAP_OPT_DEREF, (void *) &option_param);
	/* }*/

    if (count < 1) {        /* nothing found :-( */
        if (r->r_flags & FLAG_SEARCHACT) {
            /* in a search action we silently ignore this */
            return OK;
        }

        resp->resp_status = NOT_FOUND;
        if (resp->resp_httpheader == 0) {
            if (r->r_httpversion == 1) {
                /* Expires now */
                resp->resp_expires = 0;
                http_header(r, resp);
            }
            if (r->r_method == HEAD) {
                return OK;
            }
        }
        if (resp->resp_htmlheader == 0) {
            msg_fprintf(fp, in_home && *MSG_HTML_START_NO_SEARCH_RESULTS_HOME
            ? MSG_HTML_START_NO_SEARCH_RESULTS_HOME : MSG_HTML_START_NO_SEARCH_RESULTS, 
                "ss", print_filter, base_ufn ? base_ufn : MSG_ROOT);
            resp->resp_htmlheader = 1;

            if (!(r->r_flags & FLAG_ENTRYONLY)) {
                if (in_home && MSG_HOMEBANNER) {
                    msg_fprintf(fp, MSG_HOMEBANNER, "sss", r->r_query,
                        other_lang_select, other_lang_string);
                } else {
                    msg_fprintf(fp, MSG_BANNER, "sss", r->r_query,
                        other_lang_select, other_lang_string);
                }
            }
            if (rc == LDAP_INSUFFICIENT_ACCESS) {
                fputs(MSG_NO_LIST_ACCESS, fp);
            } else if (rc == LDAP_TIMELIMIT_EXCEEDED || rc == LDAP_TIMEOUT) {
                fputs(MSG_TIMELIMIT, fp);
            } else {
                if (print_filter && *print_filter) {
                    msg_fprintf(fp, MSG_NO_SEARCH_RESULTS, "ssss",
                    (scope == LDAP_SCOPE_ONELEVEL ?  MSG_ONELEVEL : MSG_SUBTREE),
                    print_filter, human_filter, base_ufn ? base_ufn : MSG_ROOT);
                } else {
                    fputs(MSG_NOTHING_FOUND_READORSEARCH, fp);
                }
            }
            if (!(r->r_flags & FLAG_ENTRYONLY)) {
                make_upsearch(r->r_ld, r, resp, 1);
                if (in_home && MSG_HOMETRAILER) {
                    fputs(MSG_HOMETRAILER, fp);
                } else {
                    fputs(MSG_TRAILER, fp);
                }
            }
            fputs(MSG_HTML_END, fp);
            fputs("\n", fp);
        } else {        
            /* resp->resp_htmlheader != 0 -> within a document (searchaction) */
            if (rc == LDAP_INSUFFICIENT_ACCESS) {
                fputs(MSG_NO_LIST_ACCESS, fp);
            } else if (rc == LDAP_TIMELIMIT_EXCEEDED || rc == LDAP_TIMEOUT) {
                fputs(MSG_TIMELIMIT, fp);
            } else {
                fputs(MSG_NOTHING_FOUND_READORSEARCH, fp);
                fputs(MSG_HTML_END, fp);
                fputs("\n", fp);
            }
        }
        return OK;
    }
    if (showonematch == 1 && count == 1 && r->r_attrnumb == 0 &&
        !(r->r_flags & FLAG_SEARCHACT)) {
    /* header != 0 ? */
        /* only one result and not searching for special attrs (searchaction) */
        e = ldap_first_entry(r->r_ld, res);
        if (e != NULL) {
            char **oc, **aliasdn;
            oc = ldap_get_values(r->r_ld, e, objectclass_attr);
            aliasdn = ldap_get_values(r->r_ld, e, "aliasedObjectName");
            if (aliasdn && *aliasdn)
                result_dn = *aliasdn;
            else
                result_dn = ldap_get_dn(r->r_ld, e);
            if (result_dn) {
                result_ufn = friendly_dn(resp, result_dn);
                if (gwswitch) {
                    server = gw_switch(r->r_ld, resp, e);
                }
                r->r_flags &= ~FLAG_FILTER;    /* it's not a search anymore */
                url_dn = dn2url(r, result_dn, 
                          server ? r->r_flags & ~FLAG_LANGUAGE : r->r_flags, 
                          0, NULL, server);

                /* Redirect */
#ifdef WEB500GW_DEBUG
                Web500gw_debug(WEB500GW_DEBUG_TRACE, 
                    "do_search: found one entry -> REDIRECT: %s\n",
                         url_dn, 0, 0, 0);
#endif
                resp->resp_status = REDIRECT;
                if (resp->resp_httpheader == 0 && r->r_httpversion == 1) {
                    resp->resp_location = malloc(strlen(url_dn) + 11);
                    strcpy(resp->resp_location, url_dn);

                    http_header(r, resp);
                    /* free(resp->resp_location); */
                }
                if (r->r_method == HEAD) {
                    return OK;
                }
                msg_fprintf(fp, in_home && *MSG_HTML_START_SEARCH_RESULTS_HOME ?
                MSG_HTML_START_SEARCH_RESULTS_HOME : MSG_HTML_START_SEARCH_RESULTS, 
                    "ss", print_filter, result_ufn);
                msg_fprintf(fp, MSG_REDIRECT, "ss", url_dn, result_ufn);
                fputs(MSG_HTML_END, fp);
                fputs("\n", fp);
                return OK;
            }
        }
    }

    /* Found something */
    /* Prepare HTTP + HTML header */
    if (resp->resp_httpheader == 0 && r->r_httpversion == 1) {
        http_header(r, resp);
        if (r->r_method == HEAD)
            return OK;
    }
    if (resp->resp_htmlheader == 0) {
        msg_fprintf(fp, in_home && *MSG_HTML_START_SEARCH_RESULTS_HOME ?
            MSG_HTML_START_SEARCH_RESULTS_HOME : MSG_HTML_START_SEARCH_RESULTS, 
            "ss", print_filter, base_ufn ? base_ufn : MSG_ROOT);
        if (!(r->r_flags & FLAG_ENTRYONLY)) {
            if (in_home && MSG_HOMEBANNER) {
                msg_fprintf(fp, MSG_HOMEBANNER, "sss", r->r_query,
                    other_lang_select, other_lang_string);
            } else {
                msg_fprintf(fp, MSG_BANNER, "sss", r->r_query,
                    other_lang_select, other_lang_string);
            }
        }
        resp->resp_htmlheader = 1;
    }
    if ((!(r->r_flags & FLAG_ENTRYONLY)) && 
        (r->r_browser->b_upsearch & UPSEARCH_ON_TOP)) {
        make_upsearch(r->r_ld, r, resp, 1);
    }
    if (r->r_flags & FLAG_FILTER && 
        (!(r->r_flags & FLAG_ENTRYONLY))) {
        /* Not the default filter and not entryonly */

        msg_fprintf(fp, MSG_SEARCH_RESULTS, "ssssisss",
            (scope == LDAP_SCOPE_ONELEVEL ?  MSG_ONELEVEL : MSG_SUBTREE),
            print_filter, human_filter, 
            base_ufn && *base_ufn ? base_ufn : MSG_ROOT,
            count, count == 1 ? MSG_ENTRY : MSG_ENTRIES, friendlyDesc,
            rc == LDAP_PARTIAL_RESULTS ?
            resp->resp_language->l_conf->c_errmsg[LDAP_PARTIAL_RESULTS] : "");
    }
    if (ldap_result2error(r->r_ld, res, 0) == LDAP_SIZELIMIT_EXCEEDED) {
        fprintf(fp, r->r_flags & FLAG_FILTER && r->r_access->a_sizelimit == 0 ? 
            MSG_SIZELIMIT_1 : MSG_SIZELIMIT_0, count);
    }
    
    /* Now prepare the result for sorting */ 

#ifdef WEB500GW_DEBUG
    Web500gw_debug(WEB500GW_DEBUG_TRACE, 
        "do_search: preparing for sort\n", 0, 0, 0, 0);
#endif

    /* for all the results ... */
    for (e = ldap_first_entry(r->r_ld, res); e != NULL && counter < MAX_LISTSIZE; 
         e = ldap_next_entry(r->r_ld, e)) {

        result_dn = ldap_get_dn(r->r_ld, e);
        result_ufn = friendly_dn(resp, result_dn);
        if ((val = ldap_get_values(r->r_ld, e, "aliasedObjectName"))) {
            /* entry is alias */
            free(result_dn);
            result_dn = strdup(*val);
            alias_ufn = friendly_dn(resp, result_dn);
            ldap_value_free(val);
            isalias = 1;
        } else {
            isalias = 0;
        }
        if (isalias && r->r_flags & FLAG_DEREFALIAS) {
            /* if alias, look for objectClass of real entry */
            oc = deref(r->r_ld, result_dn);
        } else {
            oc = ldap_get_values(r->r_ld, e, objectclass_attr);
        }
            
        /* find template to see the plural name of the objectclass */
        tmpl = ldap_oc2template(oc, r->r_access->a_tmpllist);
        doc = pick_oc(oc);
        if (tmpl && tmpl->dt_pluralname) {
            foc = strdup(friendly_label(resp, tmpl->dt_pluralname));
        } else {
            foc = strdup(friendly_label(resp, doc));
            if (strcmp(foc, doc) == 0) {
            /* "no friendly objectclass" found -> last in the list (a hack) */
                foc = (char *)malloc(strlen(doc)+9);
                sprintf(foc, "&#032;%s", doc);
            }
        }
        if (strncasecmp(result_ufn, "{ASN}", 5) == 0) {
            /* ASNs are not something we want to display! */
            free(result_dn);
            ldap_value_free(oc);
            continue;
        }
        if (base_len > 0) {
            /* strip search base from result */
            result_ufn = strip_ufn_dn(result_ufn, base_ufn);
        }
#ifdef nodef
            cp = result_ufn + strlen(result_ufn) - 1;
            bp = base_ufn + base_len - 1;
            while (bp >= base_ufn && *cp-- && *bp-- && *cp == *bp);
            
            if ((bp+1) == base_ufn && cp != NULL) { /* Complete match on base */
                /* strip trailing whitespaces and ',' */
                while (*cp && isspace(*cp)) cp--;
                if (cp != NULL && *cp == ',')
                    *cp = '\0';
            }
        }
#endif
        
        sortstring = strdup(result_ufn);
        if (strcasecmp(doc, "country") == 0) {  /* a country */
            sn = NULL;
        } else {                                /* not a country */
            /* DNs may have components in '"', ignored  when sorting */
            if (*sortstring == '"') {
                sortstring++;
                cp = strchr(sortstring+1, '"');
            } else {
                cp = sortstring;
            }
            if ((cp = strchr(cp,',')))
                *cp = '\0';
            if (isalias) {      /* aliases don't have surnames */
                if (isoc (oc, "person")) {
                }
            }
            sn = ldap_get_values(r->r_ld, e, "sn");
/*  Delete spaces ???
            if (sn) {
                cp = *sn;
                while ((cp = strchr(cp,' '))) {
                    cp ++;
                    spaces ++;
                }
            }
            while (spaces > 0) {
                if ((cp = strrchr(sortstring,' '))) {
                    *cp = '\0';
                    spaces --;
                } else
                    break;
            }
*/
            if ((cp = strchr(sortstring,'+'))) {
                cp --;
                *cp = '\0';
            }
        }

        if (gwswitch) {
            server = gw_switch(r->r_ld, resp, e);
        }
        /* build the link (HREF) */
        if (isalias) {
            if (isnonleaf(r->r_ld, oc, result_dn)) {
                if (r->r_flags & FLAG_NOHREFDN)
                    msg_snprintf(href, sizeof(href), MSG_DN_ALIAS_TO_NONLEAF, 
                        "sss", result_ufn, alias_ufn, html_encode(result_dn));
                else
                    msg_snprintf(href, sizeof(href), MSG_HREF_ALIAS_TO_NONLEAF,
                        "ssssss",
                        dn2url(r, result_dn, server ? 0 : FLAG_LANGUAGE,
                        0, NULL, server), result_ufn,
                        alias_ufn, html_encode(result_dn),
                        string_encode(result_ufn),string_encode(result_dn));
            } else {
                if (r->r_flags & FLAG_NOHREFDN)
                    msg_snprintf(href, sizeof(href), MSG_DN_ALIAS_TO_LEAF, 
                        "sss",
                        result_ufn, alias_ufn, html_encode(result_dn));
                else
                    msg_snprintf(href, sizeof(href), MSG_HREF_ALIAS_TO_LEAF,
                        "ssssss",
                        dn2url(r, result_dn, server ? 0 : FLAG_LANGUAGE, 0, NULL,
                        server), result_ufn,
                        alias_ufn, html_encode(result_dn),
                        string_encode(result_ufn),string_encode(result_dn));
            }
        } else if (isnonleaf(r->r_ld, oc, result_dn)) {
            if (r->r_flags & FLAG_NOHREFDN)
                msg_snprintf(href, sizeof(href), MSG_DN_NON_LEAF, "ss",
                    result_ufn, html_encode(result_dn));
            else
                msg_snprintf(href, sizeof(href), MSG_HREF_NON_LEAF, "sssss",
                    dn2url(r, result_dn, server ? 0 : FLAG_LANGUAGE, 0,
                    NULL, server), result_ufn,
                    html_encode(result_dn), string_encode(result_ufn),
                    string_encode(result_dn));
        } else {
            if (r->r_flags & FLAG_NOHREFDN)
                msg_snprintf(href, sizeof(href), MSG_DN_LEAF, "ss",
                    result_ufn, html_encode(result_dn));
            else
                msg_snprintf(href, sizeof(href), MSG_HREF_LEAF, "sssss",
                    dn2url(r, result_dn, server ? 0 : FLAG_LANGUAGE, 0,
                    NULL, server), result_ufn, 
                    html_encode(result_dn), string_encode(result_ufn),
                    string_encode(result_dn));
        }
        /* build the sortstring:  foc[sn]sortstring */
        if (sn) {
            temp = (char *) malloc(strlen(foc)+strlen(*sn)+strlen(sortstring)+1);
        } else {
            temp = (char *) malloc(strlen(foc)+strlen(sortstring)+1);
        }
        strcpy(temp, foc);
        if (sn) {
            strcat(temp, *sn);
        }
        strcat(temp, sortstring);
        if (!dnlist[counter]) {
            dnlist[counter] = (struct dncompare *) malloc(sizeof(struct dncompare));
        }
        dnlist[counter]->sortstring = temp;
        dnlist[counter]->href = strdup(href);
        dnlist[counter]->friendly_oc = foc;
        dnlist[counter]->oc = doc;
        dnlist[counter]->tmpl = tmpl;
        dnlist[counter]->entry = e;
        dnlist[counter]->dn = strdup(result_dn);
        counter++;
        ldap_value_free(oc);
        free(result_dn);
        if (sn)
            ldap_value_free(sn);
    }
Пример #24
0
int
do_addform(
    REQUEST     *r,
    RESPONSE    *resp
)
{
#ifndef MODIFY
    do_error(r, resp, LDAP_OTHER, NOT_IMPLEMENTED, MSG_NOT_SUPPORTED, NULL);
    return NOTOK;
#else   /* defined MODIFY */

    int             rc, in_home;
    char            *bind_as, *pw, *args, *tmpl, *basedn, *rdn, *ufn, *cp;
    LDAPMessage     *res;
    struct timeval  timeout;
    struct ldap_disptmpl    *templ;


/* 
 * query = default Base-DN, 
 * args = dn=BindDN&userPassword=PASSWD&tmpl=template&basedn=DN
 */
    args = r->r_method == POST ? r->r_postdata : r->r_filter;

#ifdef WEB500GW_DEBUG
    Web500gw_debug(WEB500GW_DEBUG_TRACE, "do_addform (%s, %s)\n",    
        r->r_dn, args ? args : "", 0, 0);
#endif

    if (args == NULL) {
        do_error(r, resp, LDAP_OTHER, BAD_REQUEST, NULL, NULL);
        return NOTOK;
    }
    bind_as = pw = tmpl = basedn = NULL;
    cp = args;
    while (cp && *cp) {
        if (strncmp(cp, "dn=", 3) == 0) {
            bind_as = cp + 3;
        } else if (strncmp(cp, "userPassword="******"tmpl=", 5) == 0) {
            tmpl = cp + 5;
        } else if (strncmp(cp, "basedn=", 7) == 0) {
            basedn = cp + 7;
        } /* else ignore */
        cp = strchr(cp, '&');
        if (cp && *cp)
            *cp++ = '\0';
    }
    if (!bind_as) {
        do_error(r, resp, LDAP_OTHER, BAD_REQUEST, MSG_NO_BIND_DN, NULL);
        return NOTOK;
    }
    hex_qdecode(bind_as);

    if (! pw) {
        do_error(r, resp, LDAP_OTHER, BAD_REQUEST, MSG_MISSING_PASSWORD, NULL);
        return NOTOK;
    }
    hex_qdecode(pw);
    if (basedn && *basedn) {
        hex_qdecode(basedn);
    } else {
        basedn = r->r_dn;
    }
    hex_qdecode(tmpl);
    if (tmpl && *tmpl)      /* overrides the template in URL */
        r->r_template = tmpl;
        
    if (! (r->r_template && *r->r_template)) {
        /* need a objectclass template */
        do_error(r, resp, LDAP_OTHER, BAD_REQUEST, MSG_TEMPLATE_MISSING, NULL);
        return NOTOK;
    }

/*  No bind necessary at this stage but checking it anyway to block
 *  non-admins */
    if ((!bind_as) || strlen(bind_as) == 0) { /* No DN to bind as */
        do_error (r, resp, LDAP_INAPPROPRIATE_AUTH, BAD_REQUEST, 
                 MSG_UNKNOWN_ARGUMENT, NULL);
        return NOTOK;
    }
    r->r_binddn = bind_as;
    if ((!pw) || strlen(pw) == 0) { /* we need a password for simple auth */
        do_error (r, resp, LDAP_INAPPROPRIATE_AUTH, 0, MSG_NULL_PASSWORD, NULL);
        return NOTOK;
    }

#ifdef WEB500GW_DEBUG
    Web500gw_debug(WEB500GW_DEBUG_TRACE, "BINDING as %s ... ", bind_as, 0, 0, 0);
#endif
    if ((r->r_ld = web500gw_ldap_init(r, resp, bind_as, pw, 1)) == (LDAP *)0)
        return NOTOK;
#ifdef WEB500GW_DEBUG
    Web500gw_debug(WEB500GW_DEBUG_TRACE, "BOUND\n", 0, 0, 0, 0);
#endif

    /* let's see if basedn exists ... */
    timeout.tv_sec = timelimit;
    timeout.tv_usec = 0;
    if ((rc = ldap_search_st(r->r_ld, basedn, LDAP_SCOPE_BASE, default_filter,
        NULL, 0, &timeout, &res)) != LDAP_SUCCESS) {
        /* better error description here ??? */
        do_error(r, resp, rc, 0, get_ldap_error_str(r->r_ld), get_ldap_matched_str(r->r_ld));
        return NOTOK;
    }
    /* check if nonleaf here ??? */

    ufn = friendly_dn(resp, basedn);
    rdn = friendly_rdn(resp, basedn, 1);
    in_home = isinhome(basedn);
 
    /* find the requested template */
    templ = ldap_name2template(r->r_template, r->r_access->a_tmpllist);
    if (templ == NULL) {            /* template not found */
        do_error(r, resp, LDAP_OTHER, BAD_REQUEST, MSG_TEMPLATE_MISSING, NULL);
        return NOTOK;
    }
    /* .. and see if it's allowed to add such an entry */
    if (!LDAP_IS_DISPTMPL_OPTION_SET(templ, LDAP_DTMPL_OPT_ADDABLE)) {
        do_error(r, resp, LDAP_OTHER, BAD_REQUEST, MSG_ADD_OC_NOT_ADDABLE, NULL);
        return NOTOK;
    }

    if (r->r_httpversion == 1 && resp->resp_httpheader == 0) {
        /* Expires now - don't allow to cache */
        /* resp->resp_expires = 0; */
        http_header(r, resp);
    }
    if (resp->resp_htmlheader == 0) {
        msg_fprintf(fp, in_home && *MSG_HTML_START_MISC_HOME ?
            MSG_HTML_START_MISC_HOME : MSG_HTML_START_MISC, 
            "sss", MSG_ADD, rdn, ufn);
        resp->resp_htmlheader = 1;
    }
    msg_fprintf(fp, MSG_EXPLAIN_ADD, "ss", rdn, ufn);
    fprintf(fp, "<FORM METHOD=POST ACTION=\"%s\">\n", 
        dn2url(r, basedn, FLAG_LANGUAGE|FLAG_TMPL, ACTION_ADD, NULL, NULL));

    if (r->r_browser->b_opts & B_HIDDEN) {
        fprintf(fp, "<INPUT TYPE=\"hidden\" NAME=\"adder_dn\" VALUE=\"%s\">\n\
<INPUT TYPE=\"hidden\" NAME=\"adder_pw\" VALUE=\"%s\">\n",
	      html_encode(bind_as, strlen(bind_as)), html_encode(pw, strlen(pw)));

    } else {
Пример #25
0
ldap_key_t * ldap_getuserkey(ldap_opt_t *l, const char * user) {
    ldap_key_t * k = (ldap_key_t *) calloc (1, sizeof(ldap_key_t));
    LDAPMessage *res, *e;
    char * filter;
    int i;
    char *attrs[] = {
      l->pub_key_attr,
      NULL
    };

    if ((!k) || (!l))
         return NULL;

    /* Am i still connected ? RETRY n times */
    /* XXX TODO: setup some conf value for retrying */
    if (!(l->flags & FLAG_CONNECTED))
        for (i = 0 ; i < 2 ; i++)
            if (ldap_connect(l) == 0)
                break;

    /* quick check for attempts to be evil */
    if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) ||
        (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL))
        return NULL;

    /* build  filter for LDAP request */
    REQUEST_USER(filter, user, l->filter);

    if ( ldap_search_st( l->ld,
        l->u_basedn,
        LDAP_SCOPE_SUBTREE,
        filter,
        attrs, 0, &l->s_timeout, &res ) != LDAP_SUCCESS) {
        
        ldap_perror(l->ld, "ldap_search_st()");

        free(filter);
        free(k);

        /* XXX error on search, timeout etc.. close ask for reconnect */
        ldap_close(l);

        return NULL;
    } 

    /* free */
    free(filter);

    /* check if any results */
    i = ldap_count_entries(l->ld,res);
    if (i <= 0) {
        ldap_msgfree(res);
        free(k);
        return NULL;
    }

    if (i > 1)
        debug("[LDAP] duplicate entries, using the FIRST entry returned");

    e = ldap_first_entry(l->ld, res);
    k->keys = ldap_get_values_len(l->ld, e, l->pub_key_attr);
    k->num = ldap_count_values_len(k->keys);

    ldap_msgfree(res);
    return k;
}