Beispiel #1
0
/* parses a message to construct a nice contact */
OPENLDAP::ContactPtr
OPENLDAP::Book::parse_result (LDAPMessage* message)
{
  ContactPtr result;
  BerElement *ber = NULL;
  struct berval bv, *bvals;
  std::string username;
  std::map<std::string, std::string> call_addresses;
  char **attributes = bookinfo.urld->lud_attrs;
  int i, rc;

  /* skip past entry DN */
  rc = ldap_get_dn_ber (ldap_context, message, &ber, &bv);

  while (rc == LDAP_SUCCESS) {
    rc = ldap_get_attribute_ber (ldap_context, message, ber, &bv, &bvals);
    if (bv.bv_val == NULL) break;
    if (attributes[0] == NULL || !g_ascii_strcasecmp(bv.bv_val, attributes[0])) {
      username = std::string (bvals[0].bv_val, bvals[0].bv_len);
    } else {
      for (i=1; attributes[i]; i++) {
        if (!g_ascii_strcasecmp(bv.bv_val,attributes[i]) && bvals && bvals[0].bv_val ) {
          /* FIXME: this is annoying. Assume if a colon is present that
           * the value is already in URI form, otherwise add a sip: prefix.
           */
          if (strchr(bvals[0].bv_val, ':'))
            call_addresses[attributes[i]] = std::string (bvals[0].bv_val, bvals[0].bv_len);
          else
            call_addresses[attributes[i]] = std::string ("sip:") +
              std::string (bvals[0].bv_val, bvals[0].bv_len);
        }
      }
    }
    if (bvals) ber_memfree(bvals);
  }

  ber_free (ber, 0);

  if (!username.empty () && !call_addresses.empty()) {

    result = OPENLDAP::Contact::create (core, fix_to_utf8 (username), call_addresses);
  }

  return result;
}
Beispiel #2
0
static int
_mu_entry_to_auth_data (LDAP *ld, LDAPMessage *msg,
			struct mu_auth_data **return_data)
{
  int rc;
  BerElement *ber = NULL;
  struct berval bv;
  char *ufn = NULL;
  struct mu_auth_data d;
  mu_iterator_t itr = NULL;
  
  memset (&d, 0, sizeof d);
  
  rc = ldap_get_dn_ber (ld, msg, &ber, &bv);
  ufn = ldap_dn2ufn (bv.bv_val);
  /* FIXME: Use debug or diag functions */
  mu_error ("INFO: %s", ufn);
  ldap_memfree (ufn);
  
  mu_assoc_get_iterator (ldap_param.field_map, &itr);
  for (mu_iterator_first (itr); !mu_iterator_is_done (itr);
       mu_iterator_next (itr))
    {
      char *key;
      char **pattr;
      char *attr;
      struct berval **values;
      
      mu_iterator_current_kv (itr, (const void **)&key, (void**) &pattr);
      attr = *pattr;
      values = ldap_get_values_len (ld, msg, attr);
      if (!values || !values[0])
	{
	  mu_error ("LDAP field `%s' (`%s') has NULL value",
		    key, *pattr);
	  _free_partial_auth_data (&d);
	  return MU_ERR_READ;
	}
      
      rc = _assign_partial_auth_data (&d, key, values[0]->bv_val);
      
      ldap_value_free_len (values);
      if (rc)
	{
	  _free_partial_auth_data (&d);
	  return rc;
	}
    }
  
  rc = mu_auth_data_alloc (return_data,
			   d.name,
			   d.passwd,
			   d.uid,
			   d.gid,
			   d.gecos,
			   d.dir,
			   d.shell,
			   d.mailbox,
			   1);
  if (rc == 0)
    mu_auth_data_set_quota (*return_data, d.quota);

  _free_partial_auth_data (&d);
  
  return rc;
}
Beispiel #3
0
static int
do_base( char *uri, char *dn, struct berval *pass, char *base, char *filter, char *pwattr,
	int maxloop, int force, int chaserefs, int noinit, int delay,
	int action_type, void *action )
{
	LDAP	*ld = NULL;
	int  	i = 0;
	int     rc = LDAP_SUCCESS;
	ber_int_t msgid;
	LDAPMessage *res, *msg;
	char **dns = NULL;
	struct berval *creds = NULL;
	char *attrs[] = { LDAP_NO_ATTRS, NULL };
	int ndns = 0;
#ifdef _WIN32
	DWORD beg, end;
#else
	struct timeval beg, end;
#endif
	int version = LDAP_VERSION3;
	char *nullstr = "";

	ldap_initialize( &ld, uri );
	if ( ld == NULL ) {
		tester_perror( "ldap_initialize", NULL );
		exit( EXIT_FAILURE );
	}

	(void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
	(void) ldap_set_option( ld, LDAP_OPT_REFERRALS,
		chaserefs ? LDAP_OPT_ON: LDAP_OPT_OFF );

	rc = ldap_sasl_bind_s( ld, dn, LDAP_SASL_SIMPLE, pass, NULL, NULL, NULL );
	if ( rc != LDAP_SUCCESS ) {
		tester_ldap_error( ld, "ldap_sasl_bind_s", NULL );
		exit( EXIT_FAILURE );
	}

	fprintf( stderr, "PID=%ld - Bind(%d): base=\"%s\", filter=\"%s\" attr=\"%s\".\n",
			(long) pid, maxloop, base, filter, pwattr );

	if ( pwattr != NULL ) {
		attrs[ 0 ] = pwattr;
	}
	rc = ldap_search_ext( ld, base, LDAP_SCOPE_SUBTREE,
			filter, attrs, 0, NULL, NULL, 0, 0, &msgid );
	if ( rc != LDAP_SUCCESS ) {
		tester_ldap_error( ld, "ldap_search_ext", NULL );
		exit( EXIT_FAILURE );
	}

	while ( ( rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &res ) ) > 0 )
	{
		BerElement *ber;
		struct berval bv;
		int done = 0;

		for ( msg = ldap_first_message( ld, res ); msg;
			msg = ldap_next_message( ld, msg ) )
		{
			switch ( ldap_msgtype( msg ) ) {
			case LDAP_RES_SEARCH_ENTRY:
				rc = ldap_get_dn_ber( ld, msg, &ber, &bv );
				dns = realloc( dns, (ndns + 1)*sizeof(char *) );
				dns[ndns] = ber_strdup( bv.bv_val );
				if ( pwattr != NULL ) {
					struct berval	**values = ldap_get_values_len( ld, msg, pwattr );

					creds = realloc( creds, (ndns + 1)*sizeof(struct berval) );
					if ( values == NULL ) {
novals:;
						creds[ndns].bv_len = 0;
						creds[ndns].bv_val = nullstr;

					} else {
						static struct berval	cleartext = BER_BVC( "{CLEARTEXT} " );
						struct berval		value = *values[ 0 ];

						if ( value.bv_val[ 0 ] == '{' ) {
							char *end = ber_bvchr( &value, '}' );

							if ( end ) {
								if ( ber_bvcmp( &value, &cleartext ) == 0 ) {
									value.bv_val += cleartext.bv_len;
									value.bv_len -= cleartext.bv_len;

								} else {
									ldap_value_free_len( values );
									goto novals;
								}
							}

						}

						ber_dupbv( &creds[ndns], &value );
						ldap_value_free_len( values );
					}
				}
				ndns++;
				ber_free( ber, 0 );
				break;

			case LDAP_RES_SEARCH_RESULT:
				done = 1;
				break;
			}
			if ( done )
				break;
		}
		ldap_msgfree( res );
		if ( done ) break;
	}

#ifdef _WIN32
	beg = GetTickCount();
#else
	gettimeofday( &beg, NULL );
#endif

	if ( ndns == 0 ) {
		tester_error( "No DNs" );
		return 1;
	}

	fprintf( stderr, "  PID=%ld - Bind base=\"%s\" filter=\"%s\" got %d values.\n",
		(long) pid, base, filter, ndns );

	/* Ok, got list of DNs, now start binding to each */
	for ( i = 0; i < maxloop; i++ ) {
		int		j;
		struct berval	cred = { 0, NULL };


#if 0	/* use high-order bits for better randomness (Numerical Recipes in "C") */
		j = rand() % ndns;
#endif
		j = ((double)ndns)*rand()/(RAND_MAX + 1.0);

		if ( creds && !BER_BVISEMPTY( &creds[j] ) ) {
			cred = creds[j];
		}

		if ( do_bind( uri, dns[j], &cred, 1, force, chaserefs, noinit, &ld,
			action_type, action ) && !force )
		{
			break;
		}

		if ( delay ) {
			sleep( delay );
		}
	}

	if ( ld != NULL ) {
		ldap_unbind_ext( ld, NULL, NULL );
		ld = NULL;
	}

#ifdef _WIN32
	end = GetTickCount();
	end -= beg;

	fprintf( stderr, "  PID=%ld - Bind done %d in %d.%03d seconds.\n",
		(long) pid, i, end / 1000, end % 1000 );
#else
	gettimeofday( &end, NULL );
	end.tv_usec -= beg.tv_usec;
	if (end.tv_usec < 0 ) {
		end.tv_usec += 1000000;
		end.tv_sec -= 1;
	}
	end.tv_sec -= beg.tv_sec;

	fprintf( stderr, "  PID=%ld - Bind done %d in %ld.%06ld seconds.\n",
		(long) pid, i, (long) end.tv_sec, (long) end.tv_usec );
#endif

	if ( dns ) {
		for ( i = 0; i < ndns; i++ ) {
			ber_memfree( dns[i] );
		}
		free( dns );
	}

	if ( creds ) {
		for ( i = 0; i < ndns; i++ ) {
			if ( creds[i].bv_val != nullstr ) {
				ber_memfree( creds[i].bv_val );
			}
		}
		free( creds );
	}

	return 0;
}
Beispiel #4
0
extern "C" std::string
getRecipient(void * vh, Source * source)

{
	ldap_handle * h = (ldap_handle *) vh;
	int msgtype;
	int code;
	int rc;
	struct berval bv;
	std::string result;

	if (!h)
		return "";

	for (;;) {
		if (h->value && h->value->bv_val) {
			result = std::string(h->value->bv_val,
			    h->value->bv_len);
			h->value++;

			if (result.length() > 5 &&
			    !strncasecmp(result.c_str(), "smtp:", 5))
				result = result.substr(5);

			if (result.find_first_not_of(mailchars) !=
			    std::string::npos)
				continue;

			return result;
			}

		if (h->ber) {
			rc = ldap_get_attribute_ber(h->ldap, h->msg, h->ber,
			    &bv, &h->values);
			h->value = h->values;

			if (rc == LDAP_SUCCESS && bv.bv_val)
				continue;
			}

		h->release_message();

		rc = ldap_result(h->ldap,
		    LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &h->msg);

		if (!h->msg)
			throw ldap_error(rc);

		msgtype = ldap_msgtype(h->msg);

		switch (msgtype) {

		case LDAP_RES_SEARCH_RESULT:
			rc = ldap_parse_result(h->ldap, h->msg, &code,
			    NULL, NULL, NULL, NULL, 0);

			if (rc != LDAP_SUCCESS)
				throw ldap_error(rc);

			if (code != LDAP_SUCCESS)
				throw ldap_error(code);

			return "";

		case LDAP_RES_SEARCH_ENTRY:
			break;

		default:
			continue;
			}

		rc = ldap_get_dn_ber(h->ldap, h->msg, &h->ber, &bv);

		if (rc != LDAP_SUCCESS)
			throw ldap_error(rc);
		}

	return "";
}
Beispiel #5
0
static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
                         size_t len, CURLcode *err)
{
  ldapconninfo *li = conn->proto.generic;
  struct SessionHandle *data = conn->data;
  ldapreqinfo *lr = data->req.protop;
  int rc, ret;
  LDAPMessage *msg = NULL;
  LDAPMessage *ent;
  BerElement *ber = NULL;
  struct timeval tv = {0, 1};

  (void)len;
  (void)buf;
  (void)sockindex;

  rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg);
  if(rc < 0) {
    failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc));
    *err = CURLE_RECV_ERROR;
    return -1;
  }

  *err = CURLE_AGAIN;
  ret = -1;

  /* timed out */
  if(!msg)
    return ret;

  for(ent = ldap_first_message(li->ld, msg); ent;
    ent = ldap_next_message(li->ld, ent)) {
    struct berval bv, *bvals, **bvp = &bvals;
    int binary = 0, msgtype;

    msgtype = ldap_msgtype(ent);
    if(msgtype == LDAP_RES_SEARCH_RESULT) {
      int code;
      char *info = NULL;
      rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0);
      if(rc) {
        failf(data, "LDAP local: search ldap_parse_result %s",
              ldap_err2string(rc));
        *err = CURLE_LDAP_SEARCH_FAILED;
      }
      else if(code && code != LDAP_SIZELIMIT_EXCEEDED) {
        failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc),
              info ? info : "");
        *err = CURLE_LDAP_SEARCH_FAILED;
      }
      else {
        /* successful */
        if(code == LDAP_SIZELIMIT_EXCEEDED)
          infof(data, "There are more than %d entries\n", lr->nument);
        data->req.size = data->req.bytecount;
        *err = CURLE_OK;
        ret = 0;
      }
      lr->msgid = 0;
      ldap_memfree(info);
      break;
    }
    else if(msgtype != LDAP_RES_SEARCH_ENTRY)
      continue;

    lr->nument++;
    rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
    if(rc < 0) {
      /* TODO: verify that this is really how this return code should be
         handled */
      *err = CURLE_RECV_ERROR;
      return -1;
    }
    *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
    if(*err)
      return -1;

    *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
                             bv.bv_len);
    if(*err)
      return -1;

    *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
    if(*err)
      return -1;
    data->req.bytecount += bv.bv_len + 5;

    for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
      rc == LDAP_SUCCESS;
      rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) {
      int i;

      if(bv.bv_val == NULL) break;

      if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
        binary = 1;
      else
        binary = 0;

      for(i=0; bvals[i].bv_val != NULL; i++) {
        int binval = 0;
        *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
        if(*err)
          return -1;

        *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
                                 bv.bv_len);
        if(*err)
          return -1;

        *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
        if(*err)
          return -1;
        data->req.bytecount += bv.bv_len + 2;

        if(!binary) {
          /* check for leading or trailing whitespace */
          if(ISSPACE(bvals[i].bv_val[0]) ||
              ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1]))
            binval = 1;
          else {
            /* check for unprintable characters */
            unsigned int j;
            for(j=0; j<bvals[i].bv_len; j++)
              if(!ISPRINT(bvals[i].bv_val[j])) {
                binval = 1;
                break;
              }
          }
        }
        if(binary || binval) {
          char *val_b64 = NULL;
          size_t val_b64_sz = 0;
          /* Binary value, encode to base64. */
          CURLcode error = Curl_base64_encode(data,
                                              bvals[i].bv_val,
                                              bvals[i].bv_len,
                                              &val_b64,
                                              &val_b64_sz);
          if(error) {
            ber_memfree(bvals);
            ber_free(ber, 0);
            ldap_msgfree(msg);
            *err = error;
            return -1;
          }
          *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
          if(*err)
            return -1;

          data->req.bytecount += 2;
          if(val_b64_sz > 0) {
            *err = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
                                     val_b64_sz);
            if(*err)
              return -1;
            free(val_b64);
            data->req.bytecount += val_b64_sz;
          }
        }
        else {
          *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
          if(*err)
            return -1;

          *err = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
                                   bvals[i].bv_len);
          if(*err)
            return -1;

          data->req.bytecount += bvals[i].bv_len + 1;
        }
        *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
        if(*err)
          return -1;

        data->req.bytecount++;
      }
      ber_memfree(bvals);
      *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
      if(*err)
        return -1;
      data->req.bytecount++;
    }
    *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
    if(*err)
      return -1;
    data->req.bytecount++;
    ber_free(ber, 0);
  }
  ldap_msgfree(msg);
  return ret;
}
Beispiel #6
0
static void *
my_task( void *my_num )
{
	LDAP	*ld = NULL, *sld = NULL;
	ber_int_t msgid;
	LDAPMessage *res, *msg;
	char *attrs[] = { "1.1", NULL };
	int     rc = LDAP_SUCCESS;
	int		tid = *(int *)my_num;

	ldap_initialize( &ld, uri );
	if ( ld == NULL ) {
		perror( "ldap_initialize" );
		return NULL;
	}

	{
		int version = LDAP_VERSION3;
		(void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
			&version ); 
	}
	(void) ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );

	ldap_initialize( &sld, uri );
	if ( sld == NULL ) {
		perror( "ldap_initialize" );
		return NULL;
	}

	{
		int version = LDAP_VERSION3;
		(void) ldap_set_option( sld, LDAP_OPT_PROTOCOL_VERSION,
			&version ); 
	}
	(void) ldap_set_option( sld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
	if ( binder ) {
		rc = ldap_bind_s( sld, binder, pass, LDAP_AUTH_SIMPLE );
		if ( rc != LDAP_SUCCESS ) {
			ldap_perror( sld, "ldap_bind" );
		}
	}

	r1binds[tid] = 0;

	for (;;) {
		char dn[BUFSIZ], *ptr, fstr[256];
		int j, isr1;
		
		if ( finish )
			break;

		j = rand() % 100;
		if ( j < r1per ) {
			j = rand() % r1hi;
			isr1 = 1;
		} else {
			j = rand() % (r2hi - r2lo + 1 );
			j += r2lo;
			isr1 = 0;
		}
		sprintf(fstr, filter, j);

		rc = ldap_search_ext( sld, base, LDAP_SCOPE_SUB,
			fstr, attrs, 0, NULL, NULL, 0, 0, &msgid );
		if ( rc != LDAP_SUCCESS ) {
			ldap_perror( sld, "ldap_search_ex" );
			return NULL;
		}

		while (( rc=ldap_result( sld, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &res )) >0){
			BerElement *ber;
			struct berval bv;
			char *ptr;
			int done = 0;

			for (msg = ldap_first_message( sld, res ); msg;
				msg = ldap_next_message( sld, msg )) {
				switch ( ldap_msgtype( msg )) {
				case LDAP_RES_SEARCH_ENTRY:
					rc = ldap_get_dn_ber( sld, msg, &ber, &bv );
					strcpy(dn, bv.bv_val );
					ber_free( ber, 0 );
					break;
				case LDAP_RES_SEARCH_RESULT:
					done = 1;
					break;
				}
				if ( done )
					break;
			}
			ldap_msgfree( res );
			if ( done ) break;
		}

		rc = ldap_bind_s( ld, dn, pass, LDAP_AUTH_SIMPLE );
		if ( rc != LDAP_SUCCESS ) {
			ldap_perror( ld, "ldap_bind" );
		}
		if ( isr1 )
			r1binds[tid]++;
		else
			r2binds[tid]++;
	}

	ldap_unbind( sld );
	ldap_unbind( ld );

	return NULL;
}