Exemple #1
0
int
main( int argc, char **argv )
{
	LDAP		*ld;
	LDAPMessage	*result, *e;
	BerElement	*ber;
	char		*a, *dn;
	char		**vals;
	int		i;

	/* Initialize the client */
	if ( ldapssl_client_init( MY_CERTDB_PATH, NULL ) < 0 ) {
		perror( "ldapssl_client_init" );
		return( 1 );
	}

	/* set the max I/O timeout option to 10 seconds */
	if ( prldap_set_session_option( NULL, NULL, PRLDAP_OPT_IO_MAX_TIMEOUT,
	    10000 /* 10 secs */ ) != LDAP_SUCCESS ) {
		ldap_perror( NULL,
		    "prldap_set_session_option PRLDAP_OPT_IO_MAX_TIMEOUT" );
		exit( 1 );
	}

	/* get a handle to an LDAP connection */
	if ( (ld = ldapssl_init( MY_HOST, MY_SSL_PORT, 1 )) == NULL ) {
		perror( "ldapssl_init" );
		return( 1 );
	}

	/* use LDAPv3 */
	i = LDAP_VERSION3;
	if ( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &i ) < 0 ) {
		ldap_perror( ld, "ldap_set_option LDAPv3" );
		ldap_unbind( ld );
		return( 1 );
	}

	/* search for all entries with surname of Jensen */
	if ( ldap_search_s( ld, PEOPLE_BASE, LDAP_SCOPE_SUBTREE,
		"(sn=jensen)", NULL, 0, &result ) != LDAP_SUCCESS ) {
		ldap_perror( ld, "ldap_search_s" );
		if ( result == NULL ) {
			ldap_unbind( ld );
			return( 1 );
		}
	}
	/* 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 ) {
		    printf( "dn: %s\n", dn );
		    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++ ) {
				    printf( "%s: %s\n", a, vals[i] );
				}
				ldap_value_free( vals );
			}
			ldap_memfree( a );
		}
		if ( ber != NULL ) {
			ber_free( ber, 0 );
		}
		printf( "\n" );
	}
	ldap_msgfree( result );
	ldap_unbind( ld );
	return( 0 );
}
/*
 * Converts an LDAP message into a Python structure.
 *
 * On success, returns a list of dictionaries.
 * On failure, returns NULL, and sets an error.
 *
 * The message m is always freed, regardless of return value.
 */
PyObject *
LDAPmessage_to_python(LDAP *ld, LDAPMessage *m)
{
    /* we convert an LDAP message into a python structure.
     * It is always a list of dictionaries.
     * We always free m.
     */

    PyObject* result;
    LDAPMessage* entry;

    result = PyList_New(0);
    if (result == NULL) {
        ldap_msgfree( m );
        return NULL;
    }

    for(entry = ldap_first_entry(ld,m);
            entry != NULL;
            entry = ldap_next_entry(ld,entry))
    {
        char *dn;
        char *attr;
        BerElement *ber = NULL;
        PyObject* entrytuple;
        PyObject* attrdict;

        dn = ldap_get_dn( ld, entry );
        if (dn == NULL)  {
            Py_DECREF(result);
            ldap_msgfree( m );
            return LDAPerror( ld, "ldap_get_dn" );
        }

        attrdict = PyDict_New();
        if (attrdict == NULL) {
            Py_DECREF(result);
            ldap_msgfree( m );
            ldap_memfree(dn);
            return NULL;
        }

        /* Fill attrdict with lists */
        for( attr = ldap_first_attribute( ld, entry, &ber );
                attr != NULL;
                attr = ldap_next_attribute( ld, entry, ber )
           ) {
            PyObject* valuelist;
            struct berval ** bvals =
                ldap_get_values_len( ld, entry, attr );

            /* Find which list to append to */
            if ( PyMapping_HasKeyString( attrdict, attr ) ) {
                valuelist = PyMapping_GetItemString( attrdict, attr );
            } else {
                valuelist = PyList_New(0);
                if (valuelist != NULL && PyMapping_SetItemString(attrdict,
                        attr, valuelist) == -1) {
                    Py_DECREF(valuelist);
                    valuelist = NULL;	/* catch error later */
                }
            }

            if (valuelist == NULL) {
                Py_DECREF(attrdict);
                Py_DECREF(result);
                if (ber != NULL)
                    ber_free(ber, 0);
                ldap_msgfree( m );
                ldap_memfree(attr);
                ldap_memfree(dn);
                return NULL;
            }

            if (bvals != NULL) {
                Py_ssize_t i;
                for (i=0; bvals[i]; i++) {
                    PyObject *valuestr;

                    valuestr = LDAPberval_to_object(bvals[i]);
                    if (PyList_Append( valuelist, valuestr ) == -1) {
                        Py_DECREF(attrdict);
                        Py_DECREF(result);
                        Py_DECREF(valuestr);
                        Py_DECREF(valuelist);
                        if (ber != NULL)
                            ber_free(ber, 0);
                        ldap_msgfree( m );
                        ldap_memfree(attr);
                        ldap_memfree(dn);
                        return NULL;
                    }
                    Py_DECREF(valuestr);
                }
                ldap_value_free_len(bvals);
            }
            Py_DECREF( valuelist );
            ldap_memfree(attr);
        }

        entrytuple = Py_BuildValue("(sO)", dn, attrdict);
        ldap_memfree(dn);
        Py_DECREF(attrdict);
        PyList_Append(result, entrytuple);
        Py_DECREF(entrytuple);
        if (ber != NULL)
            ber_free(ber, 0);
    }
    for(entry = ldap_first_reference(ld,m);
            entry != NULL;
            entry = ldap_next_reference(ld,entry))
    {
        char **refs = NULL;
        PyObject* entrytuple;
        PyObject* reflist = PyList_New(0);

        if (reflist == NULL)  {
            Py_DECREF(result);
            ldap_msgfree( m );
            return NULL;
        }
        if (ldap_parse_reference(ld, entry, &refs, NULL, 0) != LDAP_SUCCESS) {
            Py_DECREF(result);
            ldap_msgfree( m );
            return LDAPerror( ld, "ldap_parse_reference" );
        }
        if (refs) {
            Py_ssize_t i;
            for (i=0; refs[i] != NULL; i++) {
                PyObject *refstr = PyString_FromString(refs[i]);
                PyList_Append(reflist, refstr);
                Py_DECREF(refstr);
            }
            ber_memvfree( (void **) refs );
        }
        entrytuple = Py_BuildValue("(sO)", NULL, reflist);
        Py_DECREF(reflist);
        PyList_Append(result, entrytuple);
        Py_DECREF(entrytuple);
    }
    ldap_msgfree( m );
    return result;
}
int
main( int argc, char **argv )
{
    LDAP	    	*ld;
    LDAPMessage	    	*result, *e;
    BerElement	    	*ber;
    char	    	*host, *a, *dn;
    char	  	**vals;
    int		    	i;
    int		   	rc;
    int			finished;
    int			msgid;
    int			num_entries = 0;
    struct timeval	zerotime;

    if ( argc > 1 ) {
	host = argv[1];
    } else {
	host = MY_HOST;
    }

    zerotime.tv_sec = zerotime.tv_usec = 0L;

    if ( prldap_install_routines( NULL, 1 /* shared */ ) != LDAP_SUCCESS ) {
	ldap_perror( NULL, "prldap_install_routines" );
	return( 1 );
    }

    /* get a handle to an LDAP connection */
    if ( (ld = ldap_init( host, MY_PORT )) == NULL ) {
	perror( host );
	return( 1 );
    }

    /* authenticate to the directory as nobody */
    if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
	ldap_perror( ld, "ldap_simple_bind_s" );
	return( 1 );
    }
    /* search for all entries with surname of Jensen */
    if (( msgid = ldap_search( ld, MY_SEARCHBASE, LDAP_SCOPE_SUBTREE,
	    MY_FILTER, NULL, 0 )) < 0 ) {
	ldap_perror( ld, "ldap_search" );
	return( 1 );
    }

    /* Loop, polling for results until finished */
    finished = 0;
    while ( !finished ) {
	/*
	 * Poll for results.   We call ldap_result with the "all" argument
	 * set to LDAP_MSG_ONE.  This causes ldap_result() to return exactly one
	 * entry if at least one entry is available.  This allows us to
	 * display the entries as they are received.
	 */
	result = NULL;
	rc = ldap_result( ld, msgid, LDAP_MSG_ONE, &zerotime, &result );
	switch ( rc ) {
	case -1:
	    /* some error occurred */
	    ldap_perror( ld, "ldap_result" );
	    return( 1 );
	case 0:
	    /* Timeout was exceeded.  No entries are ready for retrieval. */
	    if ( result != NULL ) {
		ldap_msgfree( result );
	    }
	    break;
	default:
	    /*
	     * Either an entry is ready for retrieval, or all entries have
	     * been retrieved.
	     */
	    if (( e = ldap_first_entry( ld, result )) == NULL ) {
		/* All done */
		finished = 1;
		if ( result != NULL ) {
		    ldap_msgfree( result );
		}
		continue;
	    }
	    /* for each entry print out name + all attrs and values */
	    num_entries++;
	    if (( dn = ldap_get_dn( ld, e )) != NULL ) {
		printf( "dn: %s\n", dn );
		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++ ) {
			printf( "%s: %s\n", a, vals[ i ] );
		    }
		    ldap_value_free( vals );
		}
		ldap_memfree( a );
	    }
	    if ( ber != NULL ) {
		ber_free( ber, 0 );
	    }
	    printf( "\n" );
	    ldap_msgfree( result );
	}
	/* Do other work here while you are waiting... */
	do_other_work();
    }

    /* All done.  Print a summary. */
    printf( "%d entries retrieved.  I counted to %ld "
	    "while I was waiting.\n", num_entries,
	    global_counter );
    ldap_unbind( ld );
    return( 0 );
}
Exemple #4
0
/*
 * handle the LDAP_RES_SEARCH_RESULT response
 */
static int
ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res )
{
	int		err;
	char		*matched = NULL,
			*msg = NULL;
	LDAPControl	**ctrls = NULL;
	int		rc;
	int		refreshDeletes = -1;

#ifdef LDAP_SYNC_TRACE
	fprintf( stderr, "\tgot LDAP_RES_SEARCH_RESULT\n" );
#endif /* LDAP_SYNC_TRACE */

	assert( ls != NULL );
	assert( res != NULL );

	/* should not happen in refreshAndPersist... */
	rc = ldap_parse_result( ls->ls_ld,
		res, &err, &matched, &msg, NULL, &ctrls, 0 );
#ifdef LDAP_SYNC_TRACE
	fprintf( stderr,
		"\tldap_parse_result(%d, \"%s\", \"%s\") == %d\n",
		err,
		matched ? matched : "",
		msg ? msg : "",
		rc );
#endif /* LDAP_SYNC_TRACE */
	if ( rc == LDAP_SUCCESS ) {
		rc = err;
	}

	ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE;

	switch ( rc ) {
	case LDAP_SUCCESS: {
		int		i;
		BerElement	*ber = NULL;
		ber_len_t	len;
		struct berval	cookie = { 0 };

		rc = LDAP_OTHER;

		/* deal with control; then fallthru to handler */
		if ( ctrls == NULL ) {
			goto done;
		}

		/* lookup the sync state control */
		for ( i = 0; ctrls[ i ] != NULL; i++ ) {
			if ( strcmp( ctrls[ i ]->ldctl_oid,
				LDAP_CONTROL_SYNC_DONE ) == 0 )
			{
				break;
			}
		}

		/* control must be present; there might be other... */
		if ( ctrls[ i ] == NULL ) {
			goto done;
		}

		/* extract data */
		ber = ber_init( &ctrls[ i ]->ldctl_value );
		if ( ber == NULL ) {
			goto done;
		}

		if ( ber_scanf( ber, "{" /*"}"*/) == LBER_ERROR ) {
			goto ber_done;
		}
		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
			if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) {
				goto ber_done;
			}
			if ( cookie.bv_val != NULL ) {
				ber_bvreplace( &ls->ls_cookie, &cookie );
			}
#ifdef LDAP_SYNC_TRACE
			fprintf( stderr, "\t\tgot cookie=%s\n",
				cookie.bv_val ? cookie.bv_val : "(null)" );
#endif /* LDAP_SYNC_TRACE */
		}

		refreshDeletes = 0;
		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) {
			if ( ber_scanf( ber, "b", &refreshDeletes ) == LBER_ERROR ) {
				goto ber_done;
			}
			if ( refreshDeletes ) {
				refreshDeletes = 1;
			}
		}

		if ( ber_scanf( ber, /*"{"*/ "}" ) != LBER_ERROR ) {
			rc = LDAP_SUCCESS;
		}

	ber_done:;
		ber_free( ber, 1 );
		if ( rc != LDAP_SUCCESS ) {
			break;
		}

#ifdef LDAP_SYNC_TRACE
		fprintf( stderr, "\t\tgot refreshDeletes=%s\n",
			refreshDeletes ? "TRUE" : "FALSE" );
#endif /* LDAP_SYNC_TRACE */

		/* FIXME: what should we do with the refreshDelete? */
		switch ( refreshDeletes ) {
		case 0:
			ls->ls_refreshPhase = LDAP_SYNC_CAPI_PRESENTS;
			break;

		default:
			ls->ls_refreshPhase = LDAP_SYNC_CAPI_DELETES;
			break;
		}

		} /* fallthru */

	case LDAP_SYNC_REFRESH_REQUIRED:
		/* TODO: check for Sync Done Control */
		/* FIXME: perhaps the handler should be called
		 * also in case of failure; we'll deal with this 
		 * later when implementing refreshOnly */
		if ( ls->ls_search_result ) {
			err = ls->ls_search_result( ls, res, refreshDeletes );
		}
		break;
	}

done:;
	if ( matched != NULL ) {
		ldap_memfree( matched );
	}

	if ( msg != NULL ) {
		ldap_memfree( msg );
	}

	if ( ctrls != NULL ) {
		ldap_controls_free( ctrls );
	}

	ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE;

	return rc;
}
Exemple #5
0
int asyncmeta_handle_common_result(LDAPMessage *msg, a_metaconn_t *mc, bm_context_t *bc, int candidate)
{
	a_metainfo_t	*mi;
	a_metatarget_t	*mt;
	a_metasingleconn_t *msc;
	const char	*save_text = NULL,
		*save_matched = NULL;
	BerVarray	save_ref = NULL;
	LDAPControl	**save_ctrls = NULL;
	void		*matched_ctx = NULL;

	char		*matched = NULL;
	char		*text = NULL;
	char		**refs = NULL;
	LDAPControl	**ctrls = NULL;
	Operation *op;
	SlapReply *rs;
	int		rc;

	mi = mc->mc_info;
	mt = mi->mi_targets[ candidate ];
	msc = &mc->mc_conns[ candidate ];

	op = bc->op;
	rs = &bc->rs;
	save_text = rs->sr_text,
	save_matched = rs->sr_matched;
	save_ref = rs->sr_ref;
	save_ctrls = rs->sr_ctrls;
	rs->sr_text = NULL;
	rs->sr_matched = NULL;
	rs->sr_ref = NULL;
	rs->sr_ctrls = NULL;

	/* only touch when activity actually took place... */
	if ( mi->mi_idle_timeout != 0 ) {
		asyncmeta_set_msc_time(msc);
	}

	rc = ldap_parse_result( msc->msc_ldr, msg, &rs->sr_err,
				&matched, &text, &refs, &ctrls, 0 );

	if ( rc == LDAP_SUCCESS ) {
		rs->sr_text = text;
	} else {
		rs->sr_err = rc;
	}
	rs->sr_err = slap_map_api2result( rs );

	/* RFC 4511: referrals can only appear
	 * if result code is LDAP_REFERRAL */
	if ( refs != NULL
	     && refs[ 0 ] != NULL
	     && refs[ 0 ][ 0 ] != '\0' )
	{
		if ( rs->sr_err != LDAP_REFERRAL ) {
			Debug( LDAP_DEBUG_ANY,
			       "%s asyncmeta_handle_common_result[%d]: "
			       "got referrals with err=%d\n",
			       op->o_log_prefix,
			       candidate, rs->sr_err );

		} else {
			int	i;

			for ( i = 0; refs[ i ] != NULL; i++ )
				/* count */ ;
			rs->sr_ref = op->o_tmpalloc( sizeof( struct berval ) * ( i + 1 ),
						     op->o_tmpmemctx );
			for ( i = 0; refs[ i ] != NULL; i++ ) {
				ber_str2bv( refs[ i ], 0, 0, &rs->sr_ref[ i ] );
			}
			BER_BVZERO( &rs->sr_ref[ i ] );
		}

	} else if ( rs->sr_err == LDAP_REFERRAL ) {
		Debug( LDAP_DEBUG_ANY,
		       "%s asyncmeta_handle_common_result[%d]: "
		       "got err=%d with null "
		       "or empty referrals\n",
		       op->o_log_prefix,
		       candidate, rs->sr_err );

		rs->sr_err = LDAP_NO_SUCH_OBJECT;
	}

	if ( ctrls != NULL ) {
		rs->sr_ctrls = ctrls;
	}

	/* if the error in the reply structure is not
	 * LDAP_SUCCESS, try to map it from client
	 * to server error */
	if ( !LDAP_ERR_OK( rs->sr_err ) ) {
		rs->sr_err = slap_map_api2result( rs );

		/* internal ops ( op->o_conn == NULL )
		 * must not reply to client */
		if ( op->o_conn && !op->o_do_not_cache && matched ) {

			/* record the (massaged) matched
			 * DN into the reply structure */
			rs->sr_matched = matched;
		}
	}

	if ( META_BACK_TGT_QUARANTINE( mt ) ) {
		asyncmeta_quarantine( op, mi, rs, candidate );
	}

	if ( matched != NULL ) {
		struct berval	dn, pdn;

		ber_str2bv( matched, 0, 0, &dn );
		if ( dnPretty( NULL, &dn, &pdn, op->o_tmpmemctx ) == LDAP_SUCCESS ) {
			ldap_memfree( matched );
			matched_ctx = op->o_tmpmemctx;
			matched = pdn.bv_val;
		}
		rs->sr_matched = matched;
	}

	if ( rs->sr_err == LDAP_UNAVAILABLE || rs->sr_err == LDAP_SERVER_DOWN ) {
		if ( rs->sr_text == NULL ) {
				rs->sr_text = "Target is unavailable";
			}
	}

	ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
	asyncmeta_drop_bc( mc, bc);
	ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );

	if ( op->o_conn ) {
		asyncmeta_send_ldap_result(bc, op, rs);
	}

	if ( matched ) {
		op->o_tmpfree( (char *)rs->sr_matched, matched_ctx );
	}
	if ( text ) {
		ldap_memfree( text );
	}
	if ( rs->sr_ref ) {
		op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx );
		rs->sr_ref = NULL;
	}
	if ( refs ) {
		ber_memvfree( (void **)refs );
	}
	if ( ctrls ) {
		assert( rs->sr_ctrls != NULL );
		ldap_controls_free( ctrls );
	}

	rs->sr_text = save_text;
	rs->sr_matched = save_matched;
	rs->sr_ref = save_ref;
	rs->sr_ctrls = save_ctrls;
	rc = (LDAP_ERR_OK( rs->sr_err ) ? LDAP_SUCCESS : rs->sr_err);
	ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
	asyncmeta_clear_bm_context(bc);
	ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );
	return rc;
}
Exemple #6
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;
}
Exemple #7
0
/*
 * This function will look in ldap id the token correspond to the
 * requested user. It will returns 0 for failure and 1 for success.
 *
 * For the moment ldaps is not supported. ldap serve can be on a
 * remote host.
 *
 * You need the following parameters in you pam config:
 * ldapserver=  OR ldap_uri=
 * ldapdn=
 * user_attr=
 * yubi_attr=
 *
 */
static int
authorize_user_token_ldap (struct cfg *cfg,
                           const char *user,
                           const char *token_id)
{
    DBG(("called"));
    int retval = 0;
    int protocol;
#ifdef HAVE_LIBLDAP
    LDAP *ld = NULL;
    LDAPMessage *result = NULL, *e;
    BerElement *ber;
    char *a;
    char *attrs[2] = {NULL, NULL};

    struct berval **vals;
    int i, rc;

    char *find = NULL, *sr = NULL;

    if (cfg->user_attr == NULL) {
        DBG (("Trying to look up user to YubiKey mapping in LDAP, but user_attr not set!"));
        return 0;
    }
    if (cfg->yubi_attr == NULL) {
        DBG (("Trying to look up user to YubiKey mapping in LDAP, but yubi_attr not set!"));
        return 0;
    }
    if (cfg->ldapdn == NULL) {
        DBG (("Trying to look up user to YubiKey mapping in LDAP, but ldapdn not set!"));
        return 0;
    }

    /* Get a handle to an LDAP connection. */
    if (cfg->ldap_uri)
    {
        rc = ldap_initialize (&ld, cfg->ldap_uri);
        if (rc != LDAP_SUCCESS)
        {
            DBG (("ldap_init: %s", ldap_err2string (rc)));
            retval = 0;
            goto done;
        }
    }
    else
    {
        if ((ld = ldap_init (cfg->ldapserver, PORT_NUMBER)) == NULL)
        {
            DBG (("ldap_init"));
            retval = 0;
            goto done;
        }
    }

    /* LDAPv2 is historical -- RFC3494. */
    protocol = LDAP_VERSION3;
    ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &protocol);

    /* Bind anonymously to the LDAP server. */
    rc = ldap_simple_bind_s (ld, NULL, NULL);
    if (rc != LDAP_SUCCESS)
    {
        DBG (("ldap_simple_bind_s: %s", ldap_err2string (rc)));
        retval = 0;
        goto done;
    }

    /* Allocation of memory for search strings depending on input size */
    find = malloc((strlen(cfg->user_attr)+strlen(cfg->ldapdn)+strlen(user)+3)*sizeof(char));

    sprintf (find, "%s=%s,%s", cfg->user_attr, user, cfg->ldapdn);

    attrs[0] = (char *) cfg->yubi_attr;

    DBG(("LDAP : look up object '%s', ask for attribute '%s'", find, cfg->yubi_attr));

    /* Search for the entry. */
    if ((rc = ldap_search_ext_s (ld, find, LDAP_SCOPE_BASE,
                                 NULL, attrs, 0, NULL, NULL, LDAP_NO_LIMIT,
                                 LDAP_NO_LIMIT, &result)) != LDAP_SUCCESS)
    {
        DBG (("ldap_search_ext_s: %s", ldap_err2string (rc)));

        retval = 0;
        goto done;
    }

    e = ldap_first_entry (ld, result);
    if (e == NULL)
    {
        DBG (("No result from LDAP search"));
    }
    else
    {
        /* Iterate through each returned attribute. */
        for (a = ldap_first_attribute (ld, e, &ber);
                a != NULL; a = ldap_next_attribute (ld, e, ber))
        {
            if ((vals = ldap_get_values_len (ld, e, a)) != NULL)
            {
                /* Compare each value for the attribute against the token id. */
                for (i = 0; vals[i] != NULL; i++)
                {
                    if (!strncmp (token_id, vals[i]->bv_val, strlen (token_id)))
                    {
                        DBG (("Token Found :: %s", vals[i]->bv_val));
                        retval = 1;
                    }
                    else
                    {
                        DBG (("No match : (%s) %s != %s", a, vals[i]->bv_val, token_id));
                    }
                }
                ldap_value_free_len (vals);
            }
            ldap_memfree (a);
        }
        if (ber != NULL)
            ber_free (ber, 0);
    }

done:
    if (result != NULL)
        ldap_msgfree (result);
    if (ld != NULL)
        ldap_unbind (ld);

    /* free memory allocated for search strings */
    if (find != NULL)
        free(find);
    if (sr != NULL)
        free(sr);

#else
    DBG (("Trying to use LDAP, but this function is not compiled in pam_yubico!!"));
    DBG (("Install libldap-dev and then recompile pam_yubico."));
#endif
    return retval;
}
Exemple #8
0
static GdaLdapEntry *
worker_gdaprov_ldap_describe_entry (WorkerLdapDescrEntryData *data, GError **error)
{
	if (! gda_ldap_ensure_bound (data->cnc, error))
		return NULL;

	gda_ldap_execution_slowdown (data->cnc);

	int res;
	LDAPMessage *msg = NULL;
	const gchar *real_dn;
	real_dn = data->dn ? data->dn : data->cdata->base_dn;
 retry:
	res = ldap_search_ext_s (data->cdata->handle, real_dn, LDAP_SCOPE_BASE,
				 "(objectClass=*)", NULL, 0,
				 NULL, NULL, NULL, -1,
				 &msg);
	switch (res) {
	case LDAP_SUCCESS:
	case LDAP_NO_SUCH_OBJECT: {
		gint nb_entries;
		LDAPMessage *ldap_row;
		char *attr;
		BerElement* ber;
		GdaLdapEntry *lentry;
		GArray *array = NULL;

		nb_entries = ldap_count_entries (data->cdata->handle, msg);
		if (nb_entries == 0) {
			ldap_msgfree (msg);
			gda_ldap_may_unbind (data->cnc);
			return NULL;
		}
		else if (nb_entries > 1) {
			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
				     GDA_SERVER_PROVIDER_INTERNAL_ERROR,
				     _("LDAP server returned more than one entry with DN '%s'"),
				     real_dn);
			gda_ldap_may_unbind (data->cnc);
			return NULL;
		}

		lentry = g_new0 (GdaLdapEntry, 1);
		lentry->dn = g_strdup (real_dn);
		lentry->attributes_hash = g_hash_table_new (g_str_hash, g_str_equal);
		array = g_array_new (TRUE, FALSE, sizeof (GdaLdapAttribute*));
		ldap_row = ldap_first_entry (data->cdata->handle, msg);
		for (attr = ldap_first_attribute (data->cdata->handle, ldap_row, &ber);
		     attr;
		     attr = ldap_next_attribute (data->cdata->handle, ldap_row, ber)) {
			BerValue **bvals;
			GArray *varray = NULL;
			bvals = ldap_get_values_len (data->cdata->handle, ldap_row, attr);
			if (bvals) {
				gint i;
				for (i = 0; bvals [i]; i++) {
					if (!varray)
						varray = g_array_new (TRUE, FALSE, sizeof (GValue *));
					GValue *value;
					GType type;
					type = gda_ldap_get_g_type (data->cnc, data->cdata, attr, NULL);
					/*g_print ("Type for attr %s is %s\n", attr, gda_g_type_to_string (type)); */
					value = gda_ldap_attr_value_to_g_value (data->cdata, type, bvals[i]);
					g_array_append_val (varray, value);
				}
				ldap_value_free_len (bvals);
			}
			if (varray) {
				GdaLdapAttribute *lattr = NULL;
				lattr = g_new0 (GdaLdapAttribute, 1);
				lattr->attr_name = g_strdup (attr);
				lattr->values = (GValue**) varray->data;
				lattr->nb_values = varray->len;
				g_array_free (varray, FALSE);

				g_array_append_val (array, lattr);
				g_hash_table_insert (lentry->attributes_hash, lattr->attr_name, lattr);
			}
			ldap_memfree (attr);
		}
		if (ber)
			ber_free (ber, 0);
		ldap_msgfree (msg);
		if (array) {
			g_array_sort (array, (GCompareFunc) attr_array_sort_func);
			lentry->attributes = (GdaLdapAttribute**) array->data;
			lentry->nb_attributes = array->len;
			g_array_free (array, FALSE);
		}
		gda_ldap_may_unbind (data->cnc);
		return lentry;
	}
	case LDAP_SERVER_DOWN:
	default: {
		if (res == LDAP_SERVER_DOWN) {
			gint i;
			for (i = 0; i < 5; i++) {
				if (gda_ldap_rebind (data->cnc, NULL))
					goto retry;
				g_usleep (G_USEC_PER_SEC * 2);
			}
		}
		/* error */
		int ldap_errno;
		ldap_get_option (data->cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno);
		g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR,
			     "%s", ldap_err2string(ldap_errno));
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}
	}
}
Exemple #9
0
static LdapAttribute *
worker_gda_ldap_get_attr_info (WorkerLdapAttrInfoData *data, GError **error)
{
	LdapAttribute *retval = NULL;

	if (data->cdata->attributes_hash)
		return g_hash_table_lookup (data->cdata->attributes_hash, data->attribute);

	/* initialize known types */
	data->cdata->attributes_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
							NULL,
							(GDestroyNotify) ldap_attribute_free);
	

	if (data->cdata->attributes_cache_file) {
		/* try to load from cache file, which must contain one line per attribute:
		 * <syntax oid>,0|1,<attribute name>
		 */
		gchar *fdata;
		if (g_file_get_contents (data->cdata->attributes_cache_file, &fdata, NULL, NULL)) {
			gchar *start, *ptr;
			gchar **array;
			start = fdata;
			while (1) {
				gboolean done = FALSE;
				for (ptr = start; *ptr && (*ptr != '\n'); ptr++);
				if (*ptr == '\n')
					*ptr = 0;
				else
					done = TRUE;
				
				if (*start && (*start != '#')) {
					array = g_strsplit (start, ",", 3);
					if (array[0] && array[1] && array[2]) {
						LdapAttribute *lat;
						lat = g_new (LdapAttribute, 1);
						lat->name = g_strdup (array[2]);
						lat->type = gda_ldap_get_type_info (array[0]);
						lat->single_value = (*array[1] == '0' ? FALSE : TRUE);
						g_hash_table_insert (data->cdata->attributes_hash,
								     lat->name, lat);
						/*g_print ("CACHE ADDED [%s][%p][%d] for OID %s\n",
						  lat->name, lat->type, lat->single_value,
						  array[0]);*/
					}
					g_strfreev (array);
				}
				if (done)
					break;
				else
					start = ptr+1;
			}
			g_free (fdata);
			return g_hash_table_lookup (data->cdata->attributes_hash, data->attribute);
		}
	}

	GString *string = NULL;
	LDAPMessage *msg, *entry;
	int res;
	gchar *subschema = NULL;

	char *subschemasubentry[] = {"subschemaSubentry", NULL};
	char *schema_attrs[] = {"attributeTypes", NULL};
	
	/* look for subschema */
	if (! gda_ldap_ensure_bound (data->cnc, NULL))
		return NULL;

	gda_ldap_execution_slowdown (data->cnc);
	res = ldap_search_ext_s (data->cdata->handle, "", LDAP_SCOPE_BASE,
				 "(objectclass=*)",
				 subschemasubentry, 0,
				 NULL, NULL, NULL, 0,
				 &msg);
	if (res != LDAP_SUCCESS) {
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}

	if ((entry = ldap_first_entry (data->cdata->handle, msg))) {
		char *attr;
		BerElement *ber;
		if ((attr = ldap_first_attribute (data->cdata->handle, entry, &ber))) {
			BerValue **bvals;
			if ((bvals = ldap_get_values_len (data->cdata->handle, entry, attr))) {
				subschema = g_strdup (bvals[0]->bv_val);
				ldap_value_free_len (bvals);
			}
			ldap_memfree (attr);
		}
		if (ber)
			ber_free (ber, 0);
	}
	ldap_msgfree (msg);

	if (! subschema) {
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}

	/* look for attributeTypes */
	gda_ldap_execution_slowdown (data->cnc);
	res = ldap_search_ext_s (data->cdata->handle, subschema, LDAP_SCOPE_BASE,
				 "(objectclass=*)",
				 schema_attrs, 0,
				 NULL, NULL, NULL, 0,
				 &msg);
	g_free (subschema);
	if (res != LDAP_SUCCESS) {
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}

	if (data->cdata->attributes_cache_file)
		string = g_string_new ("# Cache file. This file can safely be removed, in this case\n"
				       "# it will be automatically recreated.\n"
				       "# DO NOT MODIFY\n");
	for (entry = ldap_first_entry (data->cdata->handle, msg);
	     entry;
	     entry = ldap_next_entry (data->cdata->handle, msg)) {
		char *attr;
		BerElement *ber;
		for (attr = ldap_first_attribute (data->cdata->handle, msg, &ber);
		     attr;
		     attr = ldap_next_attribute (data->cdata->handle, msg, ber)) {
			if (strcasecmp(attr, "attributeTypes")) {
				ldap_memfree (attr);
				continue;
			}

			BerValue **bvals;
			bvals = ldap_get_values_len (data->cdata->handle, entry, attr);
			if (bvals) {
				gint i;
				for (i = 0; bvals[i]; i++) {
					LDAPAttributeType *at;
					const char *errp;
					int retcode;
					at = ldap_str2attributetype (bvals[i]->bv_val, &retcode,
								     &errp,
								     LDAP_SCHEMA_ALLOW_ALL);
					if (at && at->at_names && at->at_syntax_oid &&
					    at->at_names[0] && *(at->at_names[0])) {
						LdapAttribute *lat;
						lat = g_new (LdapAttribute, 1);
						lat->name = g_strdup (at->at_names [0]);
						lat->type = gda_ldap_get_type_info (at->at_syntax_oid);
						lat->single_value = (at->at_single_value == 0 ? FALSE : TRUE);
						g_hash_table_insert (data->cdata->attributes_hash,
								     lat->name, lat);
						/*g_print ("ADDED [%s][%p][%d] for OID %s\n",
						  lat->name, lat->type, lat->single_value,
						  at->at_syntax_oid);*/
						if (string)
							g_string_append_printf (string, "%s,%d,%s\n",
										at->at_syntax_oid,
										lat->single_value,
										lat->name);
									  
					}
					if (at)
						ldap_memfree (at);
				}
				ldap_value_free_len (bvals);
			}
			  
			ldap_memfree (attr);
		}
		if (ber)
			ber_free (ber, 0);
	}
	ldap_msgfree (msg);

	if (string) {
		if (! g_file_set_contents (data->cdata->attributes_cache_file, string->str, -1, NULL)) {
			gchar *dirname;
			dirname = g_path_get_dirname (data->cdata->attributes_cache_file);
			g_mkdir_with_parents (dirname, 0700);
			g_free (dirname);
			g_file_set_contents (data->cdata->attributes_cache_file, string->str, -1, NULL);
		}
		g_string_free (string, TRUE);
	}

	gda_ldap_may_unbind (data->cnc);
	retval = g_hash_table_lookup (data->cdata->attributes_hash, data->attribute);
	return retval;
}
Exemple #10
0
/** Convert group membership information into attributes
 *
 * @param[in] inst rlm_ldap configuration.
 * @param[in] request Current request.
 * @param[in,out] pconn to use. May change as this function calls functions which auto re-connect.
 * @return One of the RLM_MODULE_* values.
 */
rlm_rcode_t rlm_ldap_cacheable_groupobj(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn)
{
	rlm_rcode_t rcode = RLM_MODULE_OK;
	ldap_rcode_t status;
	int ldap_errno;

	char **vals;

	LDAPMessage *result = NULL;
	LDAPMessage *entry;

	char base_dn[LDAP_MAX_DN_STR_LEN];

	char const *filters[] = { inst->groupobj_filter, inst->groupobj_membership_filter };
	char filter[LDAP_MAX_FILTER_STR_LEN + 1];

	char const *attrs[] = { inst->groupobj_name_attr, NULL };

	char *dn;

	rad_assert(inst->groupobj_base_dn);

	if (!inst->groupobj_membership_filter) {
		RDEBUG2("Skipping caching group objects as directive 'group.membership_filter' is not set");

		return RLM_MODULE_OK;
	}

	if (rlm_ldap_xlat_filter(request,
				 filters, sizeof(filters) / sizeof(*filters),
				 filter, sizeof(filter)) < 0) {
		return RLM_MODULE_INVALID;
	}

	if (radius_xlat(base_dn, sizeof(base_dn), request, inst->groupobj_base_dn, rlm_ldap_escape_func, NULL) < 0) {
		REDEBUG("Failed creating base_dn");

		return RLM_MODULE_INVALID;
	}

	status = rlm_ldap_search(inst, request, pconn, base_dn, inst->groupobj_scope, filter, attrs, &result);
	switch (status) {
		case LDAP_PROC_SUCCESS:
			break;
		case LDAP_PROC_NO_RESULT:
			RDEBUG2("No cacheable group memberships found in group objects");
		default:
			goto finish;
	}

	entry = ldap_first_entry((*pconn)->handle, result);
	if (!entry) {
		ldap_get_option((*pconn)->handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
		REDEBUG("Failed retrieving entry: %s", ldap_err2string(ldap_errno));

		goto finish;
	}

	do {
		if (inst->cacheable_group_dn) {
			dn = ldap_get_dn((*pconn)->handle, entry);
			pairmake(request, &request->config_items, inst->cache_da->name, dn, T_OP_ADD);
			RDEBUG("Added %s with value \"%s\" to control list", inst->cache_da->name, dn);
			ldap_memfree(dn);
		}

		if (inst->cacheable_group_name) {
			vals = ldap_get_values((*pconn)->handle, entry, inst->groupobj_name_attr);
			if (!vals) {
				continue;
			}

			pairmake(request, &request->config_items, inst->cache_da->name, *vals, T_OP_ADD);
			RDEBUG("Added %s with value \"%s\" to control list", inst->cache_da->name, *vals);

			ldap_value_free(vals);
		}
	} while((entry = ldap_next_entry((*pconn)->handle, entry)));

	finish:
	if (result) {
		ldap_msgfree(result);
	}

	return rcode;
}
Exemple #11
0
/** Convert multiple group names into a DNs
 *
 * Given an array of group names, builds a filter matching all names, then retrieves all group objects
 * and stores the DN associated with each group object.
 *
 * @param[in] inst rlm_ldap configuration.
 * @param[in] request Current request.
 * @param[in,out] pconn to use. May change as this function calls functions which auto re-connect.
 * @param[in] names to covert to DNs (NULL terminated).
 * @param[out] out Where to write the DNs. DNs must be freed with ldap_memfree(). Will be NULL terminated.
 * @param[in] outlen Size of out.
 * @return One of the RLM_MODULE_* values.
 */
static rlm_rcode_t rlm_ldap_group_name2dn(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn,
					  char **names, char **out, size_t outlen)
{
	rlm_rcode_t rcode = RLM_MODULE_OK;
	ldap_rcode_t status;
	int ldap_errno;

	unsigned int name_cnt = 0;
	unsigned int entry_cnt;
	char const *attrs[] = { NULL };

	LDAPMessage *result = NULL, *entry;

	char **name = names;
	char **dn = out;
	char buffer[LDAP_MAX_GROUP_NAME_LEN + 1];

	char *filter;

	*dn = NULL;

	if (!*names) {
		return RLM_MODULE_OK;
	}

	if (!inst->groupobj_name_attr) {
		REDEBUG("Told to convert group names to DNs but missing 'group.name_attribute' directive");

		return RLM_MODULE_INVALID;
	}

	RDEBUG("Converting group name(s) to group DN(s)");

	/*
	 *	It'll probably only save a few ms in network latency, but it means we can send a query
	 *	for the entire group list at once.
	 */
	filter = talloc_asprintf(request, "%s%s%s",
				 inst->groupobj_filter ? "(&" : "",
				 inst->groupobj_filter ? inst->groupobj_filter : "",
				 names[0] && names[1] ? "(|" : "");
	while (*name) {
		rlm_ldap_escape_func(request, buffer, sizeof(buffer), *name++, NULL);
		filter = talloc_asprintf_append_buffer(filter, "(%s=%s)", inst->groupobj_name_attr, buffer);

		name_cnt++;
	}
	filter = talloc_asprintf_append_buffer(filter, "%s%s",
					       inst->groupobj_filter ? ")" : "",
					       names[0] && names[1] ? ")" : "");

	status = rlm_ldap_search(inst, request, pconn, inst->groupobj_base_dn, inst->groupobj_scope,
				 filter, attrs, &result);
	switch (status) {
		case LDAP_PROC_SUCCESS:
			break;
		case LDAP_PROC_NO_RESULT:
			RDEBUG("Tried to resolve group name(s) to DNs but got no results");
			goto finish;
		default:
			rcode = RLM_MODULE_FAIL;
			goto finish;
	}

	entry_cnt = ldap_count_entries((*pconn)->handle, result);
	if (entry_cnt > name_cnt) {
		REDEBUG("Number of DNs exceeds number of names, group and/or dn should be more restrictive");
		rcode = RLM_MODULE_INVALID;

		goto finish;
	}

	if (entry_cnt > (outlen - 1)) {
		REDEBUG("Number of DNs exceeds limit (%zu)", outlen - 1);
		rcode = RLM_MODULE_INVALID;

		goto finish;
	}

	if (entry_cnt < name_cnt) {
		RWDEBUG("Got partial mapping of group names (%i) to DNs (%i), membership information may be incomplete",
			name_cnt, entry_cnt);
	}

	entry = ldap_first_entry((*pconn)->handle, result);
	if (!entry) {
		ldap_get_option((*pconn)->handle, LDAP_OPT_RESULT_CODE, &ldap_errno);
		REDEBUG("Failed retrieving entry: %s", ldap_err2string(ldap_errno));

		rcode = RLM_MODULE_FAIL;
		goto finish;
	}

	do {
		*dn = ldap_get_dn((*pconn)->handle, entry);
		RDEBUG("Got group DN \"%s\"", *dn);
		dn++;
	} while((entry = ldap_next_entry((*pconn)->handle, entry)));

	*dn = NULL;

	finish:
	talloc_free(filter);
	if (result) {
		ldap_msgfree(result);
	}

	/*
	 *	Be nice and cleanup the output array if we error out.
	 */
	if (rcode != RLM_MODULE_OK) {
		dn = out;
		while(*dn) ldap_memfree(*dn++);
		*dn = NULL;
	}

	return rcode;
}
Exemple #12
0
/** Convert group membership information into attributes
 *
 * @param[in] inst rlm_ldap configuration.
 * @param[in] request Current request.
 * @param[in,out] pconn to use. May change as this function calls functions which auto re-connect.
 * @param[in] entry retrieved by rlm_ldap_find_user or rlm_ldap_search.
 * @param[in] attr membership attribute to look for in the entry.
 * @return One of the RLM_MODULE_* values.
 */
rlm_rcode_t rlm_ldap_cacheable_userobj(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn,
				       LDAPMessage *entry, char const *attr)
{
	rlm_rcode_t rcode = RLM_MODULE_OK;

	char **vals;

	char *group_name[LDAP_MAX_CACHEABLE + 1];
	char **name_p = group_name;

	char *group_dn[LDAP_MAX_CACHEABLE + 1];
	char **dn_p;

	char *name;

	int is_dn, i;

	rad_assert(entry);
	rad_assert(attr);

	/*
	 *	Parse the membership information we got in the initial user query.
	 */
	vals = ldap_get_values((*pconn)->handle, entry, attr);
	if (!vals) {
		RDEBUG2("No cacheable group memberships found in user object");

		return RLM_MODULE_OK;
	}

	for (i = 0; (vals[i] != NULL) && (i < LDAP_MAX_CACHEABLE); i++) {
		is_dn = rlm_ldap_is_dn(vals[i]);

		if (inst->cacheable_group_dn) {
			/*
			 *	The easy case, were caching DNs and we got a DN.
			 */
			if (is_dn) {
				pairmake(request, &request->config_items, inst->cache_da->name, vals[i], T_OP_ADD);
				RDEBUG("Added %s with value \"%s\" to control list", inst->cache_da->name, vals[i]);

			/*
			 *	We were told to cache DNs but we got a name, we now need to resolve
			 *	this to a DN. Store all the group names in an array so we can do one query.
			 */
			} else {
				*name_p++ = vals[i];
			}
		}

		if (inst->cacheable_group_name) {
			/*
			 *	The easy case, were caching names and we got a name.
			 */
			if (!is_dn) {
				pairmake(request, &request->config_items, inst->cache_da->name, vals[i], T_OP_ADD);
				RDEBUG("Added %s with value \"%s\" to control list", inst->cache_da->name, vals[i]);
			/*
			 *	We were told to cache names but we got a DN, we now need to resolve
			 *	this to a name.
			 *	Only Active Directory supports filtering on DN, so we have to search
			 *	for each individual group.
			 */
			} else {
				rcode = rlm_ldap_group_dn2name(inst, request, pconn, vals[i], &name);
				if (rcode != RLM_MODULE_OK) {
					ldap_value_free(vals);

					return rcode;
				}

				pairmake(request, &request->config_items, inst->cache_da->name, name, T_OP_ADD);
				RDEBUG("Added %s with value \"%s\" to control list", inst->cache_da->name, name);
				talloc_free(name);
			}
		}
	}
	*name_p = NULL;

	rcode = rlm_ldap_group_name2dn(inst, request, pconn, group_name, group_dn, sizeof(group_dn));

	ldap_value_free(vals);

	if (rcode != RLM_MODULE_OK) {
		return rcode;
	}

	dn_p = group_dn;
	while(*dn_p) {
		pairmake(request, &request->config_items, inst->cache_da->name, *dn_p, T_OP_ADD);
		RDEBUG("Added %s with value \"%s\" to control list", inst->cache_da->name, *dn_p);
		ldap_memfree(*dn_p);

		dn_p++;
	}

	return rcode;
}
Exemple #13
0
OPENLDAP::Book::Book (Ekiga::ServiceCore &_core,
		      boost::shared_ptr<xmlDoc> _doc,
		      xmlNodePtr _node):
  saslform(NULL), core(_core), doc(_doc), node(_node),
  name_node(NULL), uri_node(NULL), authcID_node(NULL), password_node(NULL),
  ldap_context(NULL), patience(0)
{
  xmlChar *xml_str;
  bool upgrade_config = false;

  /* for previous config */
  std::string hostname="", port="", base="", scope="", call_attribute="";
  xmlNodePtr hostname_node = NULL, port_node = NULL, base_node = NULL,
    scope_node = NULL, call_attribute_node = NULL;

  bookinfo.name = "";
  bookinfo.uri = "";
  bookinfo.authcID = "";
  bookinfo.password = "";
  bookinfo.saslMech = "";
  bookinfo.sasl = false;
  bookinfo.starttls = false;

  for (xmlNodePtr child = node->children ;
       child != NULL;
       child = child->next) {

    if (child->type == XML_ELEMENT_NODE
	&& child->name != NULL) {

      if (xmlStrEqual (BAD_CAST ("name"), child->name)) {

	xml_str = xmlNodeGetContent (child);
	bookinfo.name = (const char *)xml_str;
	xmlFree (xml_str);
	name_node = child;
	continue;
      }

      if (xmlStrEqual (BAD_CAST ("uri"), child->name)) {

	xml_str = xmlNodeGetContent (child);
	bookinfo.uri = (const char *)xml_str;
	xmlFree (xml_str);
	uri_node = child;
	continue;
      }

      if (xmlStrEqual (BAD_CAST ("hostname"), child->name)) {

	xml_str = xmlNodeGetContent (child);
	hostname = (const char *)xml_str;
	hostname_node = child;
	xmlFree (xml_str);
	upgrade_config = true;
	continue;
      }
      if (xmlStrEqual (BAD_CAST ("port"), child->name)) {

	xml_str = xmlNodeGetContent (child);
	port = (const char *)xml_str;
	port_node = child;
	xmlFree (xml_str);
	upgrade_config = true;
	continue;
      }

      if (xmlStrEqual (BAD_CAST ("base"), child->name)) {

	xml_str = xmlNodeGetContent (child);
	base = (const char *)xml_str;
	base_node = child;
	xmlFree (xml_str);
	upgrade_config = true;
	continue;
      }

      if (xmlStrEqual (BAD_CAST ("scope"), child->name)) {

	xml_str = xmlNodeGetContent (child);
	scope = (const char *)xml_str;
	scope_node = child;
	xmlFree (xml_str);
	upgrade_config = true;
	continue;
      }

      if (xmlStrEqual (BAD_CAST ("call_attribute"), child->name)) {

	xml_str = xmlNodeGetContent (child);
	call_attribute = (const char *)xml_str;
	call_attribute_node = child;
	xmlFree (xml_str);
	upgrade_config = true;
	continue;
      }

      if (xmlStrEqual (BAD_CAST ("authcID"), child->name)) {

	xml_str = xmlNodeGetContent (child);
	bookinfo.authcID = (const char *)xml_str;
	authcID_node = child;
	xmlFree (xml_str);
	continue;
      }

      if (xmlStrEqual (BAD_CAST ("password"), child->name)) {

	xml_str = xmlNodeGetContent (child);
	bookinfo.password = (const char *)xml_str;
	password_node = child;
	xmlFree (xml_str);
	continue;
      }
    }
  }
  if (upgrade_config) {

    if (!uri_node) {

      LDAPURLDesc *url_tmp = NULL;
      char *url_str;
      std::string new_uri;
      if (hostname.empty())
        hostname="localhost";
      new_uri = std::string("ldap://") + hostname;
      if (!port.empty())
        new_uri += std::string(":") + port;
      new_uri += "/?cn," + call_attribute + "?" + scope;
      ldap_url_parse (new_uri.c_str(), &url_tmp);
      url_tmp->lud_dn = (char *)base.c_str();
      url_str = ldap_url_desc2str (url_tmp);
      bookinfo.uri = std::string(url_str);
      ldap_memfree (url_str);
      robust_xmlNodeSetContent (node, &uri_node, "uri", bookinfo.uri);
      url_tmp->lud_dn = NULL;
      ldap_free_urldesc (url_tmp);
    }
    if (hostname_node) {

      xmlUnlinkNode (hostname_node);
      xmlFreeNode (hostname_node);
    }
    if (port_node) {

      xmlUnlinkNode (port_node);
      xmlFreeNode (port_node);
    }
    if (base_node) {

      xmlUnlinkNode (base_node);
      xmlFreeNode (base_node);
    }
    if (scope_node) {

      xmlUnlinkNode (scope_node);
      xmlFreeNode (scope_node);
    }
    if (call_attribute_node) {

      xmlUnlinkNode (call_attribute_node);
      xmlFreeNode (call_attribute_node);
    }
    trigger_saving ();
  }
  OPENLDAP::BookInfoParse (bookinfo);
  if (bookinfo.uri_host == EKIGA_NET_URI)
    I_am_an_ekiga_net_book = true;
  else
    I_am_an_ekiga_net_book = false;

  /* Actor stuff */
  add_action (Ekiga::ActionPtr (new Ekiga::Action ("edit-book", _("_Edit"),
                                                   boost::bind (&OPENLDAP::Book::edit, this))));
  add_action (Ekiga::ActionPtr (new Ekiga::Action ("remove-book", _("_Remove"),
                                                   boost::bind (&OPENLDAP::Book::remove, this))));
  add_action (Ekiga::ActionPtr (new Ekiga::Action ("refresh-book", _("_Refresh"),
                                                   boost::bind (&OPENLDAP::Book::refresh, this))));
}
Exemple #14
0
int
OPENLDAP::BookFormInfo (Ekiga::Form &result,
			struct BookInfo &bookinfo,
			std::string &errmsg)
{
  LDAPURLDesc *url_base = NULL, *url_host = NULL;
  char *url_str;

  std::string name = result.text ("name");
  std::string uri = result.text ("uri");
  std::string nameAttr = result.text ("nameAttr");
  std::string callAttr = result.text ("callAttr");
  std::string filter = result.text ("filter");

  errmsg = "";

  if (name.empty())
    errmsg += _("Please provide a Book Name for this directory\n");

  if (uri.empty())
    errmsg += _("Please provide a Server URI\n");

  if (nameAttr.empty())
    errmsg += _("Please provide a DisplayName attribute\n");

  if (callAttr.empty())
    errmsg += _("Please provide a Call attribute\n");

  if (ldap_url_parse (uri.c_str(), &url_host))
    errmsg += _("Invalid Server URI\n");

  if (!errmsg.empty()) {
    return -1;
  }

  if (filter.empty())
    filter = "(cn=$)";

  bookinfo.name = name;
  std::string base = result.text ("base");
  std::string new_bits = "ldap:///?" +
    result.text ("nameAttr") + "," +
    result.text ("callAttr") + "?" +
    result.single_choice ("scope") + "?" +
    result.text ("filter");
  bookinfo.authcID = result.text ("authcID");
  bookinfo.password = result.text ("password");
  bookinfo.starttls = result.boolean ("startTLS");
  bookinfo.sasl = result.boolean ("sasl");
  bookinfo.saslMech = result.single_choice ("saslMech");

  if (bookinfo.sasl || bookinfo.starttls) {
    new_bits += "?";
    if (bookinfo.starttls)
      new_bits += "StartTLS";
    if (bookinfo.sasl) {
      if (bookinfo.starttls)
        new_bits += ",";
      new_bits += "SASL";
      if (!bookinfo.saslMech.empty())
        new_bits += "=" + bookinfo.saslMech;
    }
  }

  if (ldap_url_parse (new_bits.c_str(), &url_base))
    errmsg += _("Invalid Server URI\n");

  if (!errmsg.empty()) {
    return -1;
  }

  url_host->lud_dn = ldap_strdup (base.c_str());
  url_host->lud_attrs = url_base->lud_attrs;
  url_host->lud_scope = url_base->lud_scope;
  url_host->lud_filter = url_base->lud_filter;
  if (!url_host->lud_exts) {
    url_host->lud_exts = url_base->lud_exts;
    url_base->lud_exts = NULL;
  }
  url_base->lud_attrs = NULL;
  url_base->lud_filter = NULL;
  ldap_free_urldesc (url_base);

  bookinfo.urld = boost::shared_ptr<LDAPURLDesc> (url_host, ldap_url_desc_deleter ());
  url_str = ldap_url_desc2str (url_host);
  bookinfo.uri = std::string(url_str);
  ldap_memfree (url_str);

  {
    size_t pos;
    pos = bookinfo.uri.find ('/', strlen(url_host->lud_scheme) + 3);
    if (pos != std::string::npos)
      bookinfo.uri_host = bookinfo.uri.substr (0,pos);
    else
      bookinfo.uri_host = bookinfo.uri;
  }
  return 0;
}
Exemple #15
0
void kuhl_m_sid_displayMessage(PLDAP ld, PLDAPMessage pMessage)
{
	PLDAPMessage pEntry;
	PWCHAR pAttribute, name, domain;
	BerElement* pBer = NULL;
	PBERVAL *pBerVal;
	DWORD i;
	SID_NAME_USE nameUse;

	for(pEntry = ldap_first_entry(ld, pMessage); pEntry; pEntry = ldap_next_entry(ld, pEntry))
	{
		kprintf(L"\n%s\n", ldap_get_dn(ld, pEntry));
		for(pAttribute = ldap_first_attribute(ld, pEntry, &pBer); pAttribute; pAttribute = ldap_next_attribute(ld, pEntry, pBer))
		{
			kprintf(L"  %s: ", pAttribute);
			if(pBerVal = ldap_get_values_len(ld, pEntry, pAttribute))
			{
				if(
					(_wcsicmp(pAttribute, L"name") == 0) ||
					(_wcsicmp(pAttribute, L"sAMAccountName") == 0)
					)
				{
					kprintf(L"%*S\n", pBerVal[0]->bv_len, pBerVal[0]->bv_val);
				}
				else if((_wcsicmp(pAttribute, L"objectSid") == 0))
				{
					kull_m_string_displaySID(pBerVal[0]->bv_val);
					kprintf(L"\n");
				}
				else if((_wcsicmp(pAttribute, L"objectGUID") == 0))
				{
					kull_m_string_displayGUID((LPGUID) pBerVal[0]->bv_val);
					kprintf(L"\n");
				}
				else 
				{
					for(i = 0; pBerVal[i]; i++)
					{
						kprintf(L"\n   [%u] ", i);
						if((_wcsicmp(pAttribute, L"sIDHistory") == 0))
						{
							kull_m_string_displaySID(pBerVal[i]->bv_val);
							if(kull_m_token_getNameDomainFromSID(pBerVal[i]->bv_val, &name, &domain, &nameUse, NULL))
							{
								kprintf(L" ( %s -- %s\\%s )", kull_m_token_getSidNameUse(nameUse), domain, name);
								LocalFree(name);
								LocalFree(domain);
							}
						}
						else kull_m_string_wprintf_hex(pBerVal[i]->bv_val, pBerVal[i]->bv_len, 1);
					}
					kprintf(L"\n");
				}
				ldap_value_free_len(pBerVal);
			}
			ldap_memfree(pAttribute);
		}
		if(pBer)
			ber_free(pBer, 0);
	}
}
Exemple #16
0
static GdaLdapClass *
worker_gdaprov_ldap_get_class_info (WorkerLdapClassInfoData *data, GError **error)
{
	GdaLdapClass *retval = NULL;

	/* initialize known classes */
	data->cdata->classes_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
							   NULL,
							   (GDestroyNotify) ldap_class_free);

	LDAPMessage *msg, *entry;
	int res;
	gchar *subschema = NULL;

	char *subschemasubentry[] = {"subschemaSubentry", NULL};
	char *schema_attrs[] = {"objectClasses", NULL};
	
	/* look for subschema */
	if (! gda_ldap_ensure_bound (data->cnc, NULL))
		return NULL;

	gda_ldap_execution_slowdown (data->cnc);
	res = ldap_search_ext_s (data->cdata->handle, "", LDAP_SCOPE_BASE,
				 "(objectclass=*)",
				 subschemasubentry, 0,
				 NULL, NULL, NULL, 0,
				 &msg);
	if (res != LDAP_SUCCESS) {
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}

	if ((entry = ldap_first_entry (data->cdata->handle, msg))) {
		char *attr;
		BerElement *ber;
		if ((attr = ldap_first_attribute (data->cdata->handle, entry, &ber))) {
			BerValue **bvals;
			if ((bvals = ldap_get_values_len (data->cdata->handle, entry, attr))) {
				subschema = g_strdup (bvals[0]->bv_val);
				ldap_value_free_len (bvals);
			}
			ldap_memfree (attr);
		}
		if (ber)
			ber_free (ber, 0);
	}
	ldap_msgfree (msg);

	if (! subschema) {
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}

	/* look for attributeTypes */
	gda_ldap_execution_slowdown (data->cnc);
	res = ldap_search_ext_s (data->cdata->handle, subschema, LDAP_SCOPE_BASE,
				 "(objectclass=*)",
				 schema_attrs, 0,
				 NULL, NULL, NULL, 0,
				 &msg);
	g_free (subschema);
	if (res != LDAP_SUCCESS) {
		gda_ldap_may_unbind (data->cnc);
		return NULL;
	}

	GHashTable *h_refs;
	h_refs = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_strfreev);
	for (entry = ldap_first_entry (data->cdata->handle, msg);
	     entry;
	     entry = ldap_next_entry (data->cdata->handle, msg)) {
		char *attr;
		BerElement *ber;
		for (attr = ldap_first_attribute (data->cdata->handle, msg, &ber);
		     attr;
		     attr = ldap_next_attribute (data->cdata->handle, msg, ber)) {
			if (strcasecmp(attr, "objectClasses")) {
				ldap_memfree (attr);
				continue;
			}

			BerValue **bvals;
			bvals = ldap_get_values_len (data->cdata->handle, entry, attr);
			if (bvals) {
				gint i;
				for (i = 0; bvals[i]; i++) {
					LDAPObjectClass *oc;
					const char *errp;
					int retcode;
					oc = ldap_str2objectclass (bvals[i]->bv_val, &retcode,
								   &errp,
								   LDAP_SCHEMA_ALLOW_ALL);
					if (oc && oc->oc_oid && oc->oc_names && oc->oc_names[0]) {
						GdaLdapClass *lcl;
						guint k;
						lcl = g_new0 (GdaLdapClass, 1);
						lcl->oid = g_strdup (oc->oc_oid);
//#define CLASS_DEBUG
#ifdef CLASS_DEBUG
						g_print ("FOUND CLASS\n");
#endif
						lcl->names = make_array_from_strv (oc->oc_names,
										   &(lcl->nb_names));
						for (k = 0; lcl->names[k]; k++) {
#ifdef CLASS_DEBUG
							g_print ("  oc_names[%d] = %s\n",
								 k, lcl->names[k]);
#endif
							g_hash_table_insert (data->cdata->classes_hash,
									     lcl->names[k],
									     lcl);
						}
						if (oc->oc_desc) {
#ifdef CLASS_DEBUG
							g_print ("  oc_desc = %s\n", oc->oc_desc);
#endif
							lcl->description = g_strdup (oc->oc_desc);
						}
#ifdef CLASS_DEBUG
						g_print ("  oc_kind = %d\n", oc->oc_kind);
#endif
						switch (oc->oc_kind) {
						case 0:
							lcl->kind = GDA_LDAP_CLASS_KIND_ABSTRACT;
							break;
						case 1:
							lcl->kind = GDA_LDAP_CLASS_KIND_STRUTURAL;
							break;
						case 2:
							lcl->kind = GDA_LDAP_CLASS_KIND_AUXILIARY;
							break;
						default:
							lcl->kind = GDA_LDAP_CLASS_KIND_UNKNOWN;
							break;
						}
						lcl->obsolete = oc->oc_obsolete;
#ifdef CLASS_DEBUG
						g_print ("  oc_obsolete = %d\n", oc->oc_obsolete);

#endif
						gchar **refs;
						refs = make_array_from_strv (oc->oc_sup_oids, NULL);
						if (refs)
							g_hash_table_insert (h_refs, lcl, refs);
						else
							data->cdata->top_classes = g_slist_insert_sorted (data->cdata->top_classes,
									     lcl, (GCompareFunc) classes_sort);
#ifdef CLASS_DEBUG
						for (k = 0; oc->oc_sup_oids && oc->oc_sup_oids[k]; k++)
							g_print ("  oc_sup_oids[0] = %s\n",
								 oc->oc_sup_oids[k]);
#endif

						lcl->req_attributes =
							make_array_from_strv (oc->oc_at_oids_must,
									      &(lcl->nb_req_attributes));
#ifdef CLASS_DEBUG
						for (k = 0; oc->oc_at_oids_must && oc->oc_at_oids_must[k]; k++)
							g_print ("  oc_at_oids_must[0] = %s\n",
								 oc->oc_at_oids_must[k]);
#endif
						lcl->opt_attributes =
							make_array_from_strv (oc->oc_at_oids_may,
									      &(lcl->nb_opt_attributes));
#ifdef CLASS_DEBUG
						for (k = 0; oc->oc_at_oids_may && oc->oc_at_oids_may[k]; k++)
							g_print ("  oc_at_oids_may[0] = %s\n",
								 oc->oc_at_oids_may[k]);
#endif
						  
					}
					if (oc)
						ldap_memfree (oc);
				}
				ldap_value_free_len (bvals);
			}
			  
			ldap_memfree (attr);
		}
		if (ber)
			ber_free (ber, 0);
	}
	ldap_msgfree (msg);

	/* create hierarchy */
	g_hash_table_foreach (h_refs, (GHFunc) classes_h_func, data->cdata);
	g_hash_table_destroy (h_refs);

	retval = g_hash_table_lookup (data->cdata->classes_hash, data->classname);
	gda_ldap_may_unbind (data->cnc);
	return retval;
}
Exemple #17
0
static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
{
  ldapconninfo *li = conn->proto.generic;
  struct SessionHandle *data = conn->data;
  LDAPMessage *msg = NULL;
  struct timeval tv = {0, 1}, *tvp;
  int rc, err;
  char *info = NULL;

#ifdef USE_SSL
  if(conn->handler->flags & PROTOPT_SSL) {
    /* Is the SSL handshake complete yet? */
    if(!li->ssldone) {
      CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
                                                     &li->ssldone);
      if(result || !li->ssldone)
        return result;
    }

    /* Have we installed the libcurl SSL handlers into the sockbuf yet? */
    if(!li->sslinst) {
      Sockbuf *sb;
      ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
      ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn);
      li->sslinst = TRUE;
      li->recv = conn->recv[FIRSTSOCKET];
      li->send = conn->send[FIRSTSOCKET];
    }
  }
#endif

  tvp = &tv;

retry:
  if(!li->didbind) {
    char *binddn;
    struct berval passwd;

    if(conn->bits.user_passwd) {
      binddn = conn->user;
      passwd.bv_val = conn->passwd;
      passwd.bv_len = strlen(passwd.bv_val);
    }
    else {
      binddn = NULL;
      passwd.bv_val = NULL;
      passwd.bv_len = 0;
    }
    rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd,
                        NULL, NULL, &li->msgid);
    if(rc)
      return CURLE_LDAP_CANNOT_BIND;
    li->didbind = TRUE;
    if(tvp)
      return CURLE_OK;
  }

  rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg);
  if(rc < 0) {
    failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc));
    return CURLE_LDAP_CANNOT_BIND;
  }
  if(rc == 0) {
    /* timed out */
    return CURLE_OK;
  }

  rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1);
  if(rc) {
    failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc));
    return CURLE_LDAP_CANNOT_BIND;
  }

  /* Try to fallback to LDAPv2? */
  if(err == LDAP_PROTOCOL_ERROR) {
    int proto;
    ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
    if(proto == LDAP_VERSION3) {
      if(info) {
        ldap_memfree(info);
        info = NULL;
      }
      proto = LDAP_VERSION2;
      ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
      li->didbind = FALSE;
      goto retry;
    }
  }

  if(err) {
    failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc),
          info ? info : "");
    if(info)
      ldap_memfree(info);
    return CURLE_LOGIN_DENIED;
  }

  if(info)
    ldap_memfree(info);
  conn->recv[FIRSTSOCKET] = ldap_recv;
  *done = TRUE;

  return CURLE_OK;
}
Exemple #18
0
CURLcode Curl_ldap(struct connectdata *conn)
{
  CURLcode status = CURLE_OK;
  int rc;
  void *(*ldap_init)(char *, int);
  int (*ldap_simple_bind_s)(void *, char *, char *);
  int (*ldap_unbind_s)(void *);
  int (*ldap_url_parse)(char *, LDAPURLDesc **);
  void (*ldap_free_urldesc)(void *);
  int (*ldap_search_s)(void *, char *, int, char *, char **, int, void **);
  int (*ldap_search_st)(void *, char *, int, char *, char **, int, void *, void **);
  void *(*ldap_first_entry)(void *, void *);
  void *(*ldap_next_entry)(void *, void *);
  char *(*ldap_err2string)(int);
  char *(*ldap_get_dn)(void *, void *);
  char *(*ldap_first_attribute)(void *, void *, void **);
  char *(*ldap_next_attribute)(void *, void *, void *);
  char **(*ldap_get_values)(void *, void *, char *);
  void (*ldap_value_free)(char **);
  void (*ldap_memfree)(void *);
  void (*ber_free)(void *, int);
 
  void *server;
  LDAPURLDesc *ludp;
  void *result;
  void *entryIterator;
  void *ber;
  void *attribute;

  struct SessionHandle *data=conn->data;
  
  infof(data, "LDAP: %s\n", data->change.url);

  DynaOpen();
  if (libldap == NULL) {
    failf(data, "The needed LDAP library/libraries couldn't be opened");
    return CURLE_LIBRARY_NOT_FOUND;
  }

  /* The types are needed because ANSI C distinguishes between
   * pointer-to-object (data) and pointer-to-function.
   */
  DYNA_GET_FUNCTION(void *(*)(char *, int), ldap_init);
  DYNA_GET_FUNCTION(int (*)(void *, char *, char *), ldap_simple_bind_s);
  DYNA_GET_FUNCTION(int (*)(void *), ldap_unbind_s);
  DYNA_GET_FUNCTION(int (*)(char *, LDAPURLDesc **), ldap_url_parse);
  DYNA_GET_FUNCTION(void (*)(void *), ldap_free_urldesc);
  DYNA_GET_FUNCTION(int (*)(void *, char *, int, char *, char **, int, void **), ldap_search_s);
  DYNA_GET_FUNCTION(int (*)(void *, char *, int, char *, char **, int, void *, void **), ldap_search_st);
  DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_first_entry);
  DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_next_entry);
  DYNA_GET_FUNCTION(char *(*)(int), ldap_err2string);
  DYNA_GET_FUNCTION(char *(*)(void *, void *), ldap_get_dn);
  DYNA_GET_FUNCTION(char *(*)(void *, void *, void **), ldap_first_attribute);
  DYNA_GET_FUNCTION(char *(*)(void *, void *, void *), ldap_next_attribute);
  DYNA_GET_FUNCTION(char **(*)(void *, void *, char *), ldap_get_values);
  DYNA_GET_FUNCTION(void (*)(char **), ldap_value_free);
  DYNA_GET_FUNCTION(void (*)(void *), ldap_memfree);
  DYNA_GET_FUNCTION(void (*)(void *, int), ber_free);
  
  server = ldap_init(conn->hostname, conn->port);
  if (server == NULL) {
    failf(data, "LDAP: Cannot connect to %s:%d",
	  conn->hostname, conn->port);
    status = CURLE_COULDNT_CONNECT;
  }
  else {
    rc = ldap_simple_bind_s(server,
                            conn->bits.user_passwd?conn->user:NULL,
                            conn->bits.user_passwd?conn->passwd:NULL);
    if (rc != 0) {
      failf(data, "LDAP: %s", ldap_err2string(rc));
      status = CURLE_LDAP_CANNOT_BIND;
    }
    else {
      rc = ldap_url_parse(data->change.url, &ludp);
      if (rc != 0) {
	failf(data, "LDAP: %s", ldap_err2string(rc));
	status = CURLE_LDAP_INVALID_URL;
      }
      else {
	rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
                           ludp->lud_filter, ludp->lud_attrs, 0, &result);
	if (rc != 0) {
	  failf(data, "LDAP: %s", ldap_err2string(rc));
	  status = CURLE_LDAP_SEARCH_FAILED;
	}
	else {
	  for (entryIterator = ldap_first_entry(server, result);
	       entryIterator;
	       entryIterator = ldap_next_entry(server, entryIterator)) {
            char *dn = ldap_get_dn(server, entryIterator);
            char **vals;
            int i;
            
            Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4);
            Curl_client_write(data, CLIENTWRITE_BODY, dn, 0);
            Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
            for(attribute = ldap_first_attribute(server, entryIterator,
                                                 &ber); 
                attribute; 
                attribute = ldap_next_attribute(server, entryIterator,
                                                ber) ) {
              vals = ldap_get_values(server, entryIterator, attribute);
              if (vals != NULL) {
                for(i = 0; (vals[i] != NULL); i++) {
                  Curl_client_write(data, CLIENTWRITE_BODY, (char*)"\t", 1);
                  Curl_client_write(data, CLIENTWRITE_BODY, attribute, 0);
                  Curl_client_write(data, CLIENTWRITE_BODY, (char *)": ", 2);
                  Curl_client_write(data, CLIENTWRITE_BODY, vals[i], 0);
                  Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
                }
              }

              /* Free memory used to store values */
              ldap_value_free(vals);
            }
            Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
            
            ldap_memfree(attribute);
            ldap_memfree(dn);
            if (ber) ber_free(ber, 0);
          }
	}

	ldap_free_urldesc(ludp);
      }
      ldap_unbind_s(server);
    }
  }
  DynaClose();

  /* no data to transfer */
  Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
  
  return status;
}
Exemple #19
0
/* Convert an LDAP error into an informative python exception */
PyObject*
LDAPerror( LDAP*l, char*msg ) 
{
	if (l == NULL) {
		PyErr_SetFromErrno( LDAPexception_class );
		return NULL;
	}
	else {
		int errnum;
		PyObject *errobj;
		PyObject *info;
		PyObject *str;

		char *matched, *error;
		if (ldap_get_option(l, LDAP_OPT_ERROR_NUMBER, &errnum) < 0)
			errobj = LDAPexception_class;	/* unknown error XXX */
		else
			errobj = errobjects[errnum+LDAP_ERROR_OFFSET];
		
		if (errnum == LDAP_NO_MEMORY)
			return PyErr_NoMemory();

		info = PyDict_New();
		if (info == NULL)
			return NULL;

		str = PyBytes_FromString(ldap_err2string(errnum));
		if (str)
			PyDict_SetItemString( info, "desc", str );
		Py_XDECREF(str);

		if (ldap_get_option(l, LDAP_OPT_MATCHED_DN, &matched) >= 0
			&& matched != NULL) {
		    if (*matched != '\0') {
			str = PyBytes_FromString(matched);
			if (str)
			    PyDict_SetItemString( info, "matched", str );
			Py_XDECREF(str);
		    }
		    ldap_memfree(matched);
		}
		
		if (errnum == LDAP_REFERRAL) {
		    str = PyBytes_FromString(msg);
		    if (str)
			PyDict_SetItemString( info, "info", str );
		    Py_XDECREF(str);
		} else if (ldap_get_option(l, LDAP_OPT_ERROR_STRING, &error) >= 0
			&& error != NULL) {
		    if (error != '\0') {
			str = PyBytes_FromString(error);
			if (str)
			    PyDict_SetItemString( info, "info", str );
			Py_XDECREF(str);
		    }
		    ldap_memfree(error);
		}
		PyErr_SetObject( errobj, info );
		Py_DECREF(info);
		return NULL;
	}
}
Exemple #20
0
/** Perform basic parsing of multiple types of messages, checking for error conditions
 *
 * @note Error messages should be retrieved with fr_strerror() and fr_strerror_pop()
 *
 * @param[out] ctrls	Server ctrls returned to the client.  May be NULL if not required.
 *			Must be freed with ldap_free_ctrls.
 * @param[in] conn	the message was received on.
 * @param[in] msg	we're parsing.
 * @param[in] dn	if processing the result from a search request.
 * @return One of the LDAP_PROC_* (#fr_ldap_rcode_t) values.
 */
fr_ldap_rcode_t fr_ldap_error_check(LDAPControl ***ctrls, fr_ldap_connection_t const *conn, LDAPMessage *msg, char const *dn)
{
	fr_ldap_rcode_t status = LDAP_PROC_SUCCESS;

	int msg_type;
	int lib_errno = LDAP_SUCCESS;	/* errno returned by the library */
	int srv_errno = LDAP_SUCCESS;	/* errno in the result message */

	char *part_dn = NULL;		/* Partial DN match */
	char *srv_err = NULL;		/* Server's extended error message */

	ssize_t len;

	if (ctrls) *ctrls = NULL;

	if (!msg) {
		ldap_get_option(conn->handle, LDAP_OPT_ERROR_NUMBER, &lib_errno);
		if (lib_errno != LDAP_SUCCESS) goto process_error;

		fr_strerror_printf("No result available");
		return LDAP_PROC_NO_RESULT;
	}

	msg_type = ldap_msgtype(msg);
	switch (msg_type) {
	/*
	 *	Parse the result and check for errors sent by the server
	 */
	case LDAP_RES_SEARCH_RESULT:	/* The result of a search */
	case LDAP_RES_BIND:		/* The result of a bind operation */
	case LDAP_RES_EXTENDED:
		lib_errno = ldap_parse_result(conn->handle, msg,
					      &srv_errno, &part_dn, &srv_err,
					      NULL, ctrls, 0);
		break;

	/*
	 *	These are messages containing objects so unless they're
	 *	malformed they can't contain errors.
	 */
	case LDAP_RES_SEARCH_ENTRY:
		if (ctrls) lib_errno = ldap_get_entry_controls(conn->handle, msg, ctrls);
		break;

	/*
	 *	An intermediate message updating us on the result of an operation
	 */
	case LDAP_RES_INTERMEDIATE:
		lib_errno = ldap_parse_intermediate(conn->handle, msg, NULL, NULL, ctrls, 0);
		break;

	/*
	 *	Can't extract any more useful information.
	 */
	default:
		return LDAP_PROC_SUCCESS;
	}

	/*
	 *	Stupid messy API
	 */
	if (lib_errno != LDAP_SUCCESS) {
		rad_assert(!ctrls || !*ctrls);
		ldap_get_option(conn->handle, LDAP_OPT_ERROR_NUMBER, &lib_errno);
	}

process_error:
	if ((lib_errno == LDAP_SUCCESS) && (srv_errno != LDAP_SUCCESS)) {
		lib_errno = srv_errno;
	} else if ((lib_errno != LDAP_SUCCESS) && (srv_errno == LDAP_SUCCESS)) {
		srv_errno = lib_errno;
	}

	switch (lib_errno) {
	case LDAP_SUCCESS:
		fr_strerror_printf("Success");
		break;

	case LDAP_SASL_BIND_IN_PROGRESS:
		fr_strerror_printf("Continuing");
		status = LDAP_PROC_CONTINUE;
		break;

	case LDAP_NO_SUCH_OBJECT:
		fr_strerror_printf("The specified DN wasn't found");
		status = LDAP_PROC_BAD_DN;

		/*
		 *	Build our own internal diagnostic string
		 */
		if (dn && part_dn) {
			char *spaces;
			char *text;

			len = fr_ldap_common_dn(dn, part_dn);
			if (len < 0) break;

			fr_canonicalize_error(NULL, &spaces, &text, -len, dn);
			fr_strerror_printf_push("%s", text);
			fr_strerror_printf_push("%s^ %s", spaces, "match stopped here");

			talloc_free(spaces);
			talloc_free(text);
		}
		goto error_string;

	case LDAP_INSUFFICIENT_ACCESS:
		fr_strerror_printf("Insufficient access. Check the identity and password configuration directives");
		status = LDAP_PROC_NOT_PERMITTED;
		break;

	case LDAP_UNWILLING_TO_PERFORM:
		fr_strerror_printf("Server was unwilling to perform");
		status = LDAP_PROC_NOT_PERMITTED;
		break;

	case LDAP_FILTER_ERROR:
		fr_strerror_printf("Bad search filter");
		status = LDAP_PROC_ERROR;
		break;

	case LDAP_TIMEOUT:
		fr_strerror_printf("Timed out while waiting for server to respond");
		status = LDAP_PROC_TIMEOUT;
		break;

	case LDAP_TIMELIMIT_EXCEEDED:
		fr_strerror_printf("Time limit exceeded");
		status = LDAP_PROC_TIMEOUT;
		break;

	case LDAP_BUSY:
	case LDAP_UNAVAILABLE:
	case LDAP_SERVER_DOWN:
		status = LDAP_PROC_BAD_CONN;
		goto error_string;

	case LDAP_INVALID_CREDENTIALS:
	case LDAP_CONSTRAINT_VIOLATION:
		status = LDAP_PROC_REJECT;
		goto error_string;

	case LDAP_OPERATIONS_ERROR:
		fr_strerror_printf("Please set 'chase_referrals=yes' and 'rebind=yes'. "
				   "See the ldap module configuration for details");

		/* FALL-THROUGH */
	default:
		status = LDAP_PROC_ERROR;

	error_string:
		if (lib_errno == srv_errno) {
			fr_strerror_printf("lib error: %s (%u)", ldap_err2string(lib_errno), lib_errno);
		} else {
			fr_strerror_printf("lib error: %s (%u), srv error: %s (%u)",
					   ldap_err2string(lib_errno), lib_errno,
					   ldap_err2string(srv_errno), srv_errno);
		}

		if (srv_err) fr_strerror_printf_push("Server said: %s", srv_err);

		break;
	}

	/*
	 *	Cleanup memory
	 */
	if (srv_err) ldap_memfree(srv_err);
	if (part_dn) ldap_memfree(part_dn);

	return status;
}
Exemple #21
0
int
parse_at(
	struct config_args_s *c,
	AttributeType	**sat,
	AttributeType	*prev )
{
	LDAPAttributeType *at;
	int		code;
	const char	*err;
	char *line = strchr( c->line, '(' );

	at = ldap_str2attributetype( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
	if ( !at ) {
		snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s before %s",
			c->argv[0], ldap_scherr2str(code), err );
		Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
			"%s %s\n", c->log, c->cr_msg );
		at_usage();
		return 1;
	}

	if ( at->at_oid == NULL ) {
		snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: OID is missing",
			c->argv[0] );
		Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
			"%s %s\n", c->log, c->cr_msg );
		at_usage();
		code = 1;
		goto done;
	}

	/* operational attributes should be defined internally */
	if ( at->at_usage ) {
		snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: \"%s\" is operational",
			c->argv[0], at->at_oid );
		Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
			"%s %s\n", c->log, c->cr_msg );
		code = 1;
		goto done;
	}

	code = at_add( at, 1, sat, prev, &err);
	if ( code ) {
		snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s: \"%s\"",
			c->argv[0], scherr2str(code), err);
		Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
			"%s %s\n", c->log, c->cr_msg );
		code = 1;
		goto done;
	}

done:;
	if ( code ) {
		ldap_attributetype_free( at );

	} else {
		ldap_memfree( at );
	}

	return code;
}
Exemple #22
0
/** Initialise libldap and check library versions
 *
 * @return
 *	- 0 on success.
 *	- -1 on failure.
 */
int fr_ldap_init(void)
{
	int			ldap_errno;
	static LDAPAPIInfo	info = { .ldapai_info_version = LDAP_API_INFO_VERSION };	/* static to quiet valgrind about this being uninitialised */
	fr_ldap_config_t	*handle_config = &ldap_global_handle_config;

	if (instance_count > 0) {
		instance_count++;
		return 0;
	}

	/*
	 *	Only needs to be done once, prevents races in environment
	 *	initialisation within libldap.
	 *
	 *	See: https://github.com/arr2036/ldapperf/issues/2
	 */
#ifdef HAVE_LDAP_INITIALIZE
	ldap_initialize(&ldap_global_handle, "");
#else
	ldap_global_handle = ldap_init("", 0);
#endif
	if (!ldap_global_handle) {
		ERROR("Failed initialising global LDAP handle");
		return -1;
	}

	ldap_errno = ldap_get_option(NULL, LDAP_OPT_API_INFO, &info);
	if (ldap_errno == LDAP_OPT_SUCCESS) {
		/*
		 *	Don't generate warnings if the compile type vendor name
		 *	is found within the link time vendor name.
		 *
		 *	This allows the server to be built against OpenLDAP but
		 *	run with Symas OpenLDAP.
		 */
		if (strcasestr(info.ldapai_vendor_name, LDAP_VENDOR_NAME) == NULL) {
			WARN("ldap - libldap vendor changed since the server was built");
			WARN("ldap - linked: %s, built: %s", info.ldapai_vendor_name, LDAP_VENDOR_NAME);
		}

		if (info.ldapai_vendor_version < LDAP_VENDOR_VERSION) {
			WARN("ldap - libldap older than the version the server was built against");
			WARN("ldap - linked: %i, built: %i",
			     info.ldapai_vendor_version, LDAP_VENDOR_VERSION);
		}

		INFO("ldap - libldap vendor: %s, version: %i", info.ldapai_vendor_name,
		     info.ldapai_vendor_version);

		if (info.ldapai_extensions) {
			char **p;

			for (p = info.ldapai_extensions; *p != NULL; p++) {
				INFO("ldap - extension: %s", *p);
				ldap_memfree(*p);
			}

			ldap_memfree(info.ldapai_extensions);
		}

		ldap_memfree(info.ldapai_vendor_name);

	} else {
		DEBUG("ldap - Falling back to build time libldap version info.  Query for LDAP_OPT_API_INFO "
		      "returned: %i", ldap_errno);
		INFO("ldap - libldap vendor: %s, version: %i.%i.%i", LDAP_VENDOR_NAME,
		     LDAP_VENDOR_VERSION_MAJOR, LDAP_VENDOR_VERSION_MINOR, LDAP_VENDOR_VERSION_PATCH);
	}

	instance_count++;

	return 0;
}
Exemple #23
0
/*
 * handle the LDAP_RES_INTERMEDIATE response
 */
static int
ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDone )
{
	int			rc;
	char			*retoid = NULL;
        struct berval		*retdata = NULL;
	BerElement		*ber = NULL;
	ber_len_t		len;
	ber_tag_t		syncinfo_tag;
	struct berval		cookie;
	int			refreshDeletes = 0;
	BerVarray		syncUUIDs = NULL;
	ldap_sync_refresh_t	phase;

#ifdef LDAP_SYNC_TRACE
	fprintf( stderr, "\tgot LDAP_RES_INTERMEDIATE\n" );
#endif /* LDAP_SYNC_TRACE */

	assert( ls != NULL );
	assert( res != NULL );
	assert( refreshDone != NULL );

	*refreshDone = 0;

	rc = ldap_parse_intermediate( ls->ls_ld, res,
		&retoid, &retdata, NULL, 0 );
#ifdef LDAP_SYNC_TRACE
	fprintf( stderr, "\t%sldap_parse_intermediate(%s) == %d\n",
		rc != LDAP_SUCCESS ? "!!! " : "",
		retoid == NULL ? "\"\"" : retoid,
		rc );
#endif /* LDAP_SYNC_TRACE */
	/* parsing must be successful, and yield the OID
	 * of the sync info intermediate response */
	if ( rc != LDAP_SUCCESS ) {
		goto done;
	}

	rc = LDAP_OTHER;

	if ( retoid == NULL || strcmp( retoid, LDAP_SYNC_INFO ) != 0 ) {
		goto done;
	}

	/* init ber using the value in the response */
	ber = ber_init( retdata );
	if ( ber == NULL ) {
		goto done;
	}

	syncinfo_tag = ber_peek_tag( ber, &len );
	switch ( syncinfo_tag ) {
	case LDAP_TAG_SYNC_NEW_COOKIE:
		if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) {
			goto done;
		}
		if ( cookie.bv_val != NULL ) {
			ber_bvreplace( &ls->ls_cookie, &cookie );
		}
#ifdef LDAP_SYNC_TRACE
		fprintf( stderr, "\t\tgot cookie=%s\n",
			cookie.bv_val ? cookie.bv_val : "(null)" );
#endif /* LDAP_SYNC_TRACE */
		break;

	case LDAP_TAG_SYNC_REFRESH_DELETE:
	case LDAP_TAG_SYNC_REFRESH_PRESENT:
		if ( syncinfo_tag == LDAP_TAG_SYNC_REFRESH_DELETE ) {
#ifdef LDAP_SYNC_TRACE
			fprintf( stderr, "\t\tgot refreshDelete\n" );
#endif /* LDAP_SYNC_TRACE */
			switch ( ls->ls_refreshPhase ) {
			case LDAP_SYNC_CAPI_NONE:
			case LDAP_SYNC_CAPI_PRESENTS:
				ls->ls_refreshPhase = LDAP_SYNC_CAPI_DELETES;
				break;

			default:
				/* TODO: impossible; handle */
				goto done;
			}

		} else {
#ifdef LDAP_SYNC_TRACE
			fprintf( stderr, "\t\tgot refreshPresent\n" );
#endif /* LDAP_SYNC_TRACE */
			switch ( ls->ls_refreshPhase ) {
			case LDAP_SYNC_CAPI_NONE:
				ls->ls_refreshPhase = LDAP_SYNC_CAPI_PRESENTS;
				break;

			default:
				/* TODO: impossible; handle */
				goto done;
			}
		}

		if ( ber_scanf( ber, "{" /*"}"*/ ) == LBER_ERROR ) {
			goto done;
		}
		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
			if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) {
				goto done;
			}
			if ( cookie.bv_val != NULL ) {
				ber_bvreplace( &ls->ls_cookie, &cookie );
			}
#ifdef LDAP_SYNC_TRACE
			fprintf( stderr, "\t\tgot cookie=%s\n",
				cookie.bv_val ? cookie.bv_val : "(null)" );
#endif /* LDAP_SYNC_TRACE */
		}

		*refreshDone = 1;
		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDONE ) {
			if ( ber_scanf( ber, "b", refreshDone ) == LBER_ERROR ) {
				goto done;
			}
		}

#ifdef LDAP_SYNC_TRACE
		fprintf( stderr, "\t\tgot refreshDone=%s\n",
			*refreshDone ? "TRUE" : "FALSE" );
#endif /* LDAP_SYNC_TRACE */

		if ( ber_scanf( ber, /*"{"*/ "}" ) == LBER_ERROR ) {
			goto done;
		}

		if ( *refreshDone ) {
			ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE;
		}

		if ( ls->ls_intermediate ) {
			ls->ls_intermediate( ls, res, NULL, ls->ls_refreshPhase );
		}

		break;

	case LDAP_TAG_SYNC_ID_SET:
#ifdef LDAP_SYNC_TRACE
		fprintf( stderr, "\t\tgot syncIdSet\n" );
#endif /* LDAP_SYNC_TRACE */
		if ( ber_scanf( ber, "{" /*"}"*/ ) == LBER_ERROR ) {
			goto done;
		}
		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) {
			if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) {
				goto done;
			}
			if ( cookie.bv_val != NULL ) {
				ber_bvreplace( &ls->ls_cookie, &cookie );
			}
#ifdef LDAP_SYNC_TRACE
			fprintf( stderr, "\t\tgot cookie=%s\n",
				cookie.bv_val ? cookie.bv_val : "(null)" );
#endif /* LDAP_SYNC_TRACE */
		}

		if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) {
			if ( ber_scanf( ber, "b", &refreshDeletes ) == LBER_ERROR ) {
				goto done;
			}
		}

		if ( ber_scanf( ber, /*"{"*/ "[W]}", &syncUUIDs ) == LBER_ERROR
			|| syncUUIDs == NULL )
		{
			goto done;
		}

#ifdef LDAP_SYNC_TRACE
		{
			int	i;

			fprintf( stderr, "\t\tgot refreshDeletes=%s\n",
				refreshDeletes ? "TRUE" : "FALSE" );
			for ( i = 0; syncUUIDs[ i ].bv_val != NULL; i++ ) {
				char	buf[ BUFSIZ ];
				fprintf( stderr, "\t\t%s\n", 
					lutil_uuidstr_from_normalized(
						syncUUIDs[ i ].bv_val, syncUUIDs[ i ].bv_len,
						buf, sizeof( buf ) ) );
			}
		}
#endif /* LDAP_SYNC_TRACE */

		if ( refreshDeletes ) {
			phase = LDAP_SYNC_CAPI_DELETES_IDSET;

		} else {
			phase = LDAP_SYNC_CAPI_PRESENTS_IDSET;
		}

		/* FIXME: should touch ls->ls_refreshPhase? */
		if ( ls->ls_intermediate ) {
			ls->ls_intermediate( ls, res, syncUUIDs, phase );
		}

		ber_bvarray_free( syncUUIDs );
		break;

	default:
#ifdef LDAP_SYNC_TRACE
		fprintf( stderr, "\t\tunknown tag!\n" );
#endif /* LDAP_SYNC_TRACE */
		goto done;
	}

	rc = LDAP_SUCCESS;

done:;
	if ( ber != NULL ) {
		ber_free( ber, 1 );
	}

	if ( retoid != NULL ) {
		ldap_memfree( retoid );
	}

	if ( retdata != NULL ) {
		ber_bvfree( retdata );
	}

	return rc;
}
Exemple #24
0
static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
				       const struct id_map *map)
{
	NTSTATUS ret;
	TALLOC_CTX *memctx;
	struct idmap_ldap_context *ctx;
	LDAPMessage *entry = NULL;
	LDAPMod **mods = NULL;
	const char *type;
	char *id_str;
	char *sid;
	char *dn;
	int rc = -1;

	/* Only do query if we are online */
	if (idmap_is_offline())	{
		return NT_STATUS_FILE_IS_OFFLINE;
	}

	ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);

	switch(map->xid.type) {
	case ID_TYPE_UID:
		type = get_attr_key2string(sidmap_attr_list,
					   LDAP_ATTR_UIDNUMBER);
		break;

	case ID_TYPE_GID:
		type = get_attr_key2string(sidmap_attr_list,
					   LDAP_ATTR_GIDNUMBER);
		break;

	default:
		return NT_STATUS_INVALID_PARAMETER;
	}

	memctx = talloc_new(ctx);
	if ( ! memctx) {
		DEBUG(0, ("Out of memory!\n"));
		return NT_STATUS_NO_MEMORY;
	}

	id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id);
	CHECK_ALLOC_DONE(id_str);

	sid = talloc_strdup(memctx, sid_string_talloc(memctx, map->sid));
	CHECK_ALLOC_DONE(sid);

	dn = talloc_asprintf(memctx, "%s=%s,%s",
			get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
			sid,
			ctx->suffix);
	CHECK_ALLOC_DONE(dn);

	smbldap_set_mod(&mods, LDAP_MOD_ADD,
			"objectClass", LDAP_OBJ_IDMAP_ENTRY);

	smbldap_make_mod(ctx->smbldap_state->ldap_struct,
			 entry, &mods, type, id_str);

	smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods,
			 get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),
			 sid);

	if ( ! mods) {
		DEBUG(2, ("ERROR: No mods?\n"));
		ret = NT_STATUS_UNSUCCESSFUL;
		goto done;
	}

	/* TODO: remove conflicting mappings! */

	smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY);

	DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str));

	rc = smbldap_add(ctx->smbldap_state, dn, mods);
	ldap_mods_free(mods, True);

	if (rc != LDAP_SUCCESS) {
		char *ld_error = NULL;
		ldap_get_option(ctx->smbldap_state->ldap_struct,
				LDAP_OPT_ERROR_STRING, &ld_error);
		DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "
			 "mapping [%s]\n", sid,
			 (unsigned long)map->xid.id, type));
		DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",
			ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
		if (ld_error) {
			ldap_memfree(ld_error);
		}
		ret = NT_STATUS_UNSUCCESSFUL;
		goto done;
	}

	DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "
		  "%lu [%s]\n",	sid, (unsigned long)map->xid.id, type));

	ret = NT_STATUS_OK;

done:
	talloc_free(memctx);
	return ret;
}
Exemple #25
0
int
asyncmeta_handle_search_msg(LDAPMessage *res, a_metaconn_t *mc, bm_context_t *bc, int candidate)
{
	a_metainfo_t	*mi;
	a_metatarget_t	*mt;
	a_metasingleconn_t *msc;
	Operation *op = bc->op;
	SlapReply *rs;
	int	   i, rc = LDAP_SUCCESS, sres;
	SlapReply *candidates;
	char		**references = NULL;
	LDAPControl	**ctrls = NULL;
	a_dncookie dc;
	LDAPMessage *msg;
	ber_int_t id;

	rs = &bc->rs;
	mi = mc->mc_info;
	mt = mi->mi_targets[ candidate ];
	msc = &mc->mc_conns[ candidate ];
	dc.op = op;
	dc.target = mt;
	dc.to_from = MASSAGE_REP;
	id = ldap_msgid(res);


	candidates = bc->candidates;
	i = candidate;

	while (res && !META_BACK_CONN_INVALID(msc)) {
	for (msg = ldap_first_message(msc->msc_ldr, res); msg; msg = ldap_next_message(msc->msc_ldr, msg)) {
		switch(ldap_msgtype(msg)) {
		case LDAP_RES_SEARCH_ENTRY:
			Debug( LDAP_DEBUG_TRACE,
				"%s asyncmeta_handle_search_msg: msc %p entry\n",
				op->o_log_prefix, msc );
			if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
				/* don't retry any more... */
				candidates[ i ].sr_type = REP_RESULT;
			}
			/* count entries returned by target */
			candidates[ i ].sr_nentries++;
			if (bc->c_peer_name.bv_val == op->o_conn->c_peer_name.bv_val && !op->o_abandon) {
				rs->sr_err = asyncmeta_send_entry( &bc->copy_op, rs, mc, i, msg );
			} else {
				goto err_cleanup;
			}
			switch ( rs->sr_err ) {
			case LDAP_SIZELIMIT_EXCEEDED:
				asyncmeta_send_ldap_result(bc, op, rs);
				rs->sr_err = LDAP_SUCCESS;
				goto err_cleanup;
			case LDAP_UNAVAILABLE:
				rs->sr_err = LDAP_OTHER;
				break;
			default:
				break;
			}
			bc->is_ok++;
			break;

		case LDAP_RES_SEARCH_REFERENCE:
			if ( META_BACK_TGT_NOREFS( mt ) ) {
				rs->sr_err = LDAP_OTHER;
				asyncmeta_send_ldap_result(bc, op, rs);
				goto err_cleanup;
			}
			if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
				/* don't retry any more... */
				candidates[ i ].sr_type = REP_RESULT;
			}
			bc->is_ok++;
			rc = ldap_parse_reference( msc->msc_ldr, msg,
				   &references, &rs->sr_ctrls, 0 );

			if ( rc != LDAP_SUCCESS || references == NULL ) {
				rs->sr_err = LDAP_OTHER;
				asyncmeta_send_ldap_result(bc, op, rs);
				goto err_cleanup;
			}

			/* FIXME: merge all and return at the end */

			{
				int cnt;
				for ( cnt = 0; references[ cnt ]; cnt++ )
					;

				rs->sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ),
								 op->o_tmpmemctx );

				for ( cnt = 0; references[ cnt ]; cnt++ ) {
					ber_str2bv_x( references[ cnt ], 0, 1, &rs->sr_ref[ cnt ],
							  op->o_tmpmemctx );
				}
				BER_BVZERO( &rs->sr_ref[ cnt ] );
			}

			{
				dc.memctx = op->o_tmpmemctx;
				( void )asyncmeta_referral_result_rewrite( &dc, rs->sr_ref );
			}

			if ( rs->sr_ref != NULL ) {
				if (!BER_BVISNULL( &rs->sr_ref[ 0 ] ) ) {
					/* ignore return value by now */
					( void )send_search_reference( op, rs );
				}

				ber_bvarray_free_x( rs->sr_ref, op->o_tmpmemctx );
				rs->sr_ref = NULL;
			}

			/* cleanup */
			if ( references ) {
				ber_memvfree( (void **)references );
			}

			if ( rs->sr_ctrls ) {
				ldap_controls_free( rs->sr_ctrls );
				rs->sr_ctrls = NULL;
			}
			break;

		case LDAP_RES_INTERMEDIATE:
			if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
				/* don't retry any more... */
				candidates[ i ].sr_type = REP_RESULT;
			}
			bc->is_ok++;

			/* FIXME: response controls
			 * are passed without checks */
			rs->sr_err = ldap_parse_intermediate( msc->msc_ldr,
								  msg,
								  (char **)&rs->sr_rspoid,
								  &rs->sr_rspdata,
								  &rs->sr_ctrls,
								  0 );
			if ( rs->sr_err != LDAP_SUCCESS ) {
				candidates[ i ].sr_type = REP_RESULT;
				rs->sr_err = LDAP_OTHER;
				asyncmeta_send_ldap_result(bc, op, rs);
				goto err_cleanup;
			}

			slap_send_ldap_intermediate( op, rs );

			if ( rs->sr_rspoid != NULL ) {
				ber_memfree( (char *)rs->sr_rspoid );
				rs->sr_rspoid = NULL;
			}

			if ( rs->sr_rspdata != NULL ) {
				ber_bvfree( rs->sr_rspdata );
				rs->sr_rspdata = NULL;
			}

			if ( rs->sr_ctrls != NULL ) {
				ldap_controls_free( rs->sr_ctrls );
				rs->sr_ctrls = NULL;
			}
			break;

		case LDAP_RES_SEARCH_RESULT:
			if ( mi->mi_idle_timeout != 0 ) {
				asyncmeta_set_msc_time(msc);
			}
			Debug( LDAP_DEBUG_TRACE,
			       "%s asyncmeta_handle_search_msg: msc %p result\n",
			       op->o_log_prefix, msc );
			candidates[ i ].sr_type = REP_RESULT;
			candidates[ i ].sr_msgid = META_MSGID_IGNORE;
			/* NOTE: ignores response controls
			 * (and intermediate response controls
			 * as well, except for those with search
			 * references); this may not be correct,
			 * but if they're not ignored then
			 * back-meta would need to merge them
			 * consistently (think of pagedResults...)
			 */
			/* FIXME: response controls? */
			rs->sr_err = ldap_parse_result( msc->msc_ldr,
							msg,
							&candidates[ i ].sr_err,
								(char **)&candidates[ i ].sr_matched,
							(char **)&candidates[ i ].sr_text,
							&references,
							&ctrls /* &candidates[ i ].sr_ctrls (unused) */ ,
							0 );
			if ( rs->sr_err != LDAP_SUCCESS ) {
				candidates[ i ].sr_err = rs->sr_err;
				sres = slap_map_api2result( &candidates[ i ] );
				candidates[ i ].sr_type = REP_RESULT;
				goto finish;
			}

			rs->sr_err = candidates[ i ].sr_err;

			/* massage matchedDN if need be */
			if ( candidates[ i ].sr_matched != NULL ) {
				struct berval	match, mmatch;

				ber_str2bv( candidates[ i ].sr_matched,
						0, 0, &match );
				candidates[ i ].sr_matched = NULL;

				dc.memctx = NULL;
				asyncmeta_dn_massage( &dc, &match, &mmatch );
				if ( mmatch.bv_val == match.bv_val ) {
					candidates[ i ].sr_matched
						= ch_strdup( mmatch.bv_val );

				} else {
					candidates[ i ].sr_matched = mmatch.bv_val;
				}

				bc->candidate_match++;
				ldap_memfree( match.bv_val );
			}

			/* add references to array */
			/* RFC 4511: referrals can only appear
			 * if result code is LDAP_REFERRAL */
			if ( references != NULL
				 && references[ 0 ] != NULL
				 && references[ 0 ][ 0 ] != '\0' )
			{
				if ( rs->sr_err != LDAP_REFERRAL ) {
					Debug( LDAP_DEBUG_ANY,
						   "%s asncmeta_search_result[%d]: "
						   "got referrals with err=%d\n",
						   op->o_log_prefix,
						   i, rs->sr_err );

				} else {
					BerVarray	sr_ref;
					int		cnt;

					for ( cnt = 0; references[ cnt ]; cnt++ )
						;

					sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ),
								 op->o_tmpmemctx );

					for ( cnt = 0; references[ cnt ]; cnt++ ) {
						ber_str2bv_x( references[ cnt ], 0, 1, &sr_ref[ cnt ],
								  op->o_tmpmemctx );
					}
					BER_BVZERO( &sr_ref[ cnt ] );

					dc.memctx = op->o_tmpmemctx;
					( void )asyncmeta_referral_result_rewrite( &dc, sr_ref );

					if ( rs->sr_v2ref == NULL ) {
						rs->sr_v2ref = sr_ref;

					} else {
						for ( cnt = 0; !BER_BVISNULL( &sr_ref[ cnt ] ); cnt++ ) {
							ber_bvarray_add_x( &rs->sr_v2ref, &sr_ref[ cnt ],
									   op->o_tmpmemctx );
						}
						ber_memfree_x( sr_ref, op->o_tmpmemctx );
					}
				}

			} else if ( rs->sr_err == LDAP_REFERRAL ) {
				Debug( LDAP_DEBUG_TRACE,
					   "%s asyncmeta_search_result[%d]: "
					   "got err=%d with null "
					   "or empty referrals\n",
					   op->o_log_prefix,
					   i, rs->sr_err );

				rs->sr_err = LDAP_NO_SUCH_OBJECT;
			}

			/* cleanup */
			ber_memvfree( (void **)references );

			sres = slap_map_api2result( rs );

			if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {
				Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_search_result[%d] "
				       "match=\"%s\" err=%ld",
				       op->o_log_prefix, i,
				       candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
				       (long) candidates[ i ].sr_err );
			} else {
					Debug( LDAP_DEBUG_ANY,  "%s asyncmeta_search_result[%d] "
				       "match=\"%s\" err=%ld (%s)",
				       op->o_log_prefix, i,
				       candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
					       (long) candidates[ i ].sr_err, ldap_err2string( candidates[ i ].sr_err ) );
			}

			switch ( sres ) {
			case LDAP_NO_SUCH_OBJECT:
				/* is_ok is touched any time a valid
				 * (even intermediate) result is
				 * returned; as a consequence, if
				 * a candidate returns noSuchObject
				 * it is ignored and the candidate
				 * is simply demoted. */
				if ( bc->is_ok ) {
					sres = LDAP_SUCCESS;
				}
				break;

			case LDAP_SUCCESS:
				if ( ctrls != NULL && ctrls[0] != NULL ) {
#ifdef SLAPD_META_CLIENT_PR
					LDAPControl *pr_c;

					pr_c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL );
					if ( pr_c != NULL ) {
						BerElementBuffer berbuf;
						BerElement *ber = (BerElement *)&berbuf;
						ber_tag_t tag;
						ber_int_t prsize;
						struct berval prcookie;

						/* unsolicited, do not accept */
						if ( mt->mt_ps == 0 ) {
							rs->sr_err = LDAP_OTHER;
							goto err_pr;
						}

						ber_init2( ber, &pr_c->ldctl_value, LBER_USE_DER );

						tag = ber_scanf( ber, "{im}", &prsize, &prcookie );
						if ( tag == LBER_ERROR ) {
							rs->sr_err = LDAP_OTHER;
							goto err_pr;
						}

						/* more pages? new search request */
						if ( !BER_BVISNULL( &prcookie ) && !BER_BVISEMPTY( &prcookie ) ) {
							if ( mt->mt_ps > 0 ) {
								/* ignore size if specified */
								prsize = 0;

							} else if ( prsize == 0 ) {
								/* guess the page size from the entries returned so far */
								prsize = candidates[ i ].sr_nentries;
							}

							candidates[ i ].sr_nentries = 0;
							candidates[ i ].sr_msgid = META_MSGID_IGNORE;
							candidates[ i ].sr_type = REP_INTERMEDIATE;

							assert( candidates[ i ].sr_matched == NULL );
							assert( candidates[ i ].sr_text == NULL );
							assert( candidates[ i ].sr_ref == NULL );

							switch ( asyncmeta_back_search_start( &bc->copy_op, rs, mc, bc, i, &prcookie, prsize, 1 ) )
							{
							case META_SEARCH_CANDIDATE:
								assert( candidates[ i ].sr_msgid >= 0 );
								ldap_controls_free( ctrls );
								//	goto free_message;

							case META_SEARCH_ERR:
							case META_SEARCH_NEED_BIND:
err_pr:;
								candidates[ i ].sr_err = rs->sr_err;
								candidates[ i ].sr_type = REP_RESULT;
								if ( META_BACK_ONERR_STOP( mi ) ) {
									asyncmeta_send_ldap_result(bc, op, rs);
									ldap_controls_free( ctrls );
									goto err_cleanup;
								}
								/* fallthru */

							case META_SEARCH_NOT_CANDIDATE:
								/* means that asyncmeta_back_search_start()
								 * failed but onerr == continue */
								candidates[ i ].sr_msgid = META_MSGID_IGNORE;
								candidates[ i ].sr_type = REP_RESULT;
								break;

							default:
								/* impossible */
								assert( 0 );
								break;
							}
							break;
						}
					}
#endif /* SLAPD_META_CLIENT_PR */

					ldap_controls_free( ctrls );
				}
				/* fallthru */

			case LDAP_REFERRAL:
				bc->is_ok++;
				break;

			case LDAP_SIZELIMIT_EXCEEDED:
				/* if a target returned sizelimitExceeded
				 * and the entry count is equal to the
				 * proxy's limit, the target would have
				 * returned more, and the error must be
				 * propagated to the client; otherwise,
				 * the target enforced a limit lower
				 * than what requested by the proxy;
				 * ignore it */
				candidates[ i ].sr_err = rs->sr_err;
				if ( rs->sr_nentries == op->ors_slimit
					 || META_BACK_ONERR_STOP( mi ) )
				{
					const char *save_text;
got_err:
					save_text = rs->sr_text;
					rs->sr_text = candidates[ i ].sr_text;
					asyncmeta_send_ldap_result(bc, op, rs);
					if (candidates[ i ].sr_text != NULL) {
						ch_free( (char *)candidates[ i ].sr_text );
						candidates[ i ].sr_text = NULL;
					}
					rs->sr_text = save_text;
					ldap_controls_free( ctrls );
					goto err_cleanup;
				}
				break;

			default:
				candidates[ i ].sr_err = rs->sr_err;
				if ( META_BACK_ONERR_STOP( mi ) ) {
					goto got_err;
				}
				break;
			}
			/* if this is the last result we will ever receive, send it back  */
			rc = rs->sr_err;
			if (asyncmeta_is_last_result(mc, bc, i) == 0) {
				Debug( LDAP_DEBUG_TRACE,
					"%s asyncmeta_handle_search_msg: msc %p last result\n",
					op->o_log_prefix, msc );
				asyncmeta_search_last_result(mc, bc, i, sres);
err_cleanup:
				rc = rs->sr_err;
				ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
				asyncmeta_drop_bc( mc, bc);
				asyncmeta_clear_bm_context(bc);
				ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );
				ldap_msgfree(res);
				return rc;
			}
finish:
			break;

		default:
			continue;
		}
	}
		ldap_msgfree(res);
		res = NULL;
		if (candidates[ i ].sr_type != REP_RESULT) {
			struct timeval	tv = {0};
			rc = ldap_result( msc->msc_ldr, id, LDAP_MSG_RECEIVED, &tv, &res );
			if (res != NULL) {
				msc->msc_result_time = slap_get_time();
			}
		}
	}
	ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
	bc->bc_active--;
	ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );

	return rc;
}
Exemple #26
0
int
main(int argc, char **argv)
{
	LDAPAPIInfo api;
	int ival;
	char *sval;

	printf("Compile time API Information\n");

#ifdef LDAP_API_INFO_VERSION
	api.ldapai_info_version = LDAP_API_INFO_VERSION;
	printf("  API Info version:  %d\n", (int) api.ldapai_info_version);
#else
	api.ldapai_info_version = 1;
	printf("  API Info version:  unknown\n");
#endif

#ifdef LDAP_FEATURE_INFO_VERSION
	printf("  Feature Info version:  %d\n", (int) LDAP_FEATURE_INFO_VERSION);
#else
	printf("  Feature Info version:  unknown\n");
	api.ldapai_info_version = 1;
#endif

#ifdef LDAP_API_VERSION
	printf("  API version:       %d\n", (int) LDAP_API_VERSION);
#else
	printf("  API version:       unknown\n");
#endif

#ifdef LDAP_VERSION
	printf("  Protocol Version:  %d\n", (int) LDAP_VERSION);
#else
	printf("  Protocol Version:  unknown\n");
#endif
#ifdef LDAP_VERSION_MIN
	printf("  Protocol Min:      %d\n", (int) LDAP_VERSION_MIN);
#else
	printf("  Protocol Min:      unknown\n");
#endif
#ifdef LDAP_VERSION_MAX
	printf("  Protocol Max:      %d\n", (int) LDAP_VERSION_MAX);
#else
	printf("  Protocol Max:      unknown\n");
#endif
#ifdef LDAP_VENDOR_NAME
	printf("  Vendor Name:       %s\n", LDAP_VENDOR_NAME);
#else
	printf("  Vendor Name:       unknown\n");
#endif
#ifdef LDAP_VENDOR_VERSION
	printf("  Vendor Version:    %d\n", (int) LDAP_VENDOR_VERSION);
#else
	printf("  Vendor Version:    unknown\n");
#endif

	if(ldap_get_option(NULL, LDAP_OPT_API_INFO, &api) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(API_INFO) failed\n", argv[0]);
		return EXIT_FAILURE;
	}

	printf("\nExecution time API Information\n");
	printf("  API Info version:  %d\n", api.ldapai_info_version);

	if (api.ldapai_info_version != LDAP_API_INFO_VERSION) {
		printf(" API INFO version mismatch: got %d, expected %d\n",
			api.ldapai_info_version, LDAP_API_INFO_VERSION);
		return EXIT_FAILURE;
	}

	printf("  API Version:       %d\n", api.ldapai_api_version);
	printf("  Protocol Max:      %d\n", api.ldapai_protocol_version);

	if(api.ldapai_extensions == NULL) {
		printf("  Extensions:        none\n");

	} else {
		int i;
		for(i=0; api.ldapai_extensions[i] != NULL; i++) /* empty */;
		printf("  Extensions:        %d\n", i);
		for(i=0; api.ldapai_extensions[i] != NULL; i++) {
#ifdef LDAP_OPT_API_FEATURE_INFO
			LDAPAPIFeatureInfo fi;
			fi.ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
			fi.ldapaif_name = api.ldapai_extensions[i];
			fi.ldapaif_version = 0;

			if( ldap_get_option(NULL, LDAP_OPT_API_FEATURE_INFO, &fi) == LDAP_SUCCESS ) {
				if(fi.ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) {
					printf("                     %s feature info mismatch: got %d, expected %d\n",
						api.ldapai_extensions[i],
						LDAP_FEATURE_INFO_VERSION,
						fi.ldapaif_info_version);

				} else {
					printf("                     %s: version %d\n",
						fi.ldapaif_name,
						fi.ldapaif_version);
				}

			} else {
				printf("                     %s (NO FEATURE INFO)\n",
					api.ldapai_extensions[i]);
			}

#else
			printf("                     %s\n",
				api.ldapai_extensions[i]);
#endif

			ldap_memfree(api.ldapai_extensions[i]);
		}
		ldap_memfree(api.ldapai_extensions);
	}

	printf("  Vendor Name:       %s\n", api.ldapai_vendor_name);
	ldap_memfree(api.ldapai_vendor_name);

	printf("  Vendor Version:    %d\n", api.ldapai_vendor_version);

	printf("\nExecution time Default Options\n");

	if(ldap_get_option(NULL, LDAP_OPT_DEREF, &ival) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(api) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	printf("  DEREF:             %d\n", ival);

	if(ldap_get_option(NULL, LDAP_OPT_SIZELIMIT, &ival) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(sizelimit) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	printf("  SIZELIMIT:         %d\n", ival);

	if(ldap_get_option(NULL, LDAP_OPT_TIMELIMIT, &ival) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(timelimit) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	printf("  TIMELIMIT:         %d\n", ival);

	if(ldap_get_option(NULL, LDAP_OPT_REFERRALS, &ival) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(referrals) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	printf("  REFERRALS:         %s\n", ival ? "on" : "off");

	if(ldap_get_option(NULL, LDAP_OPT_RESTART, &ival) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(restart) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	printf("  RESTART:           %s\n", ival ? "on" : "off");

	if(ldap_get_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ival) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(protocol version) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	printf("  PROTOCOL VERSION:  %d\n", ival);

	if(ldap_get_option(NULL, LDAP_OPT_HOST_NAME, &sval) != LDAP_SUCCESS) {
		fprintf(stderr, "%s: ldap_get_option(host name) failed\n", argv[0]);
		return EXIT_FAILURE;
	}
	if( sval != NULL ) {
		printf("  HOST NAME:         %s\n", sval);
		ldap_memfree(sval);
	} else {
		puts("  HOST NAME:         <not set>");
	}

#if 0
	/* API tests */
	{	/* bindless unbind */
		LDAP *ld;
		int rc;

		ld = ldap_init( "localhost", 389 );
		if( ld == NULL ) {
			perror("ldap_init");
			return EXIT_FAILURE;
		}

		rc = ldap_unbind( ld );
		if( rc != LDAP_SUCCESS ) {
			perror("ldap_unbind");
			return EXIT_FAILURE;
		}
	}
	{	/* bindless unbind */
		LDAP *ld;
		int rc;

		ld = ldap_init( "localhost", 389 );
		if( ld == NULL ) {
			perror("ldap_init");
			return EXIT_FAILURE;
		}

		rc = ldap_abandon_ext( ld, 0, NULL, NULL );
		if( rc != LDAP_SERVER_DOWN ) {
			ldap_debug_perror( ld, "ldap_abandon");
			return EXIT_FAILURE;
		}

		rc = ldap_unbind( ld );
		if( rc != LDAP_SUCCESS ) {
			perror("ldap_unbind");
			return EXIT_FAILURE;
		}
	}
#endif

	return EXIT_SUCCESS;
}
Exemple #27
0
static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
{
  CURLcode result = CURLE_OK;
  int rc = 0;
  LDAP *server = NULL;
  LDAPURLDesc *ludp = NULL;
  LDAPMessage *ldapmsg = NULL;
  LDAPMessage *entryIterator;
  int num = 0;
  struct SessionHandle *data=conn->data;
  int ldap_proto = LDAP_VERSION3;
  int ldap_ssl = 0;
  char *val_b64 = NULL;
  size_t val_b64_sz = 0;
  curl_off_t dlsize = 0;
#ifdef LDAP_OPT_NETWORK_TIMEOUT
  struct timeval ldap_timeout = {10,0}; /* 10 sec connection/search timeout */
#endif

  *done = TRUE; /* unconditionally */
  infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n",
          LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION);
  infof(data, "LDAP local: %s\n", data->change.url);

#ifdef HAVE_LDAP_URL_PARSE
  rc = ldap_url_parse(data->change.url, &ludp);
#else
  rc = _ldap_url_parse(conn, &ludp);
#endif
  if(rc != 0) {
    failf(data, "LDAP local: %s", ldap_err2string(rc));
    result = CURLE_LDAP_INVALID_URL;
    goto quit;
  }

  /* Get the URL scheme ( either ldap or ldaps ) */
  if(conn->given->flags & PROTOPT_SSL)
    ldap_ssl = 1;
  infof(data, "LDAP local: trying to establish %s connection\n",
          ldap_ssl ? "encrypted" : "cleartext");

#ifdef LDAP_OPT_NETWORK_TIMEOUT
  ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout);
#endif
  ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);

  if(ldap_ssl) {
#ifdef HAVE_LDAP_SSL
#ifdef CURL_LDAP_WIN
    /* Win32 LDAP SDK doesn't support insecure mode without CA! */
    server = ldap_sslinit(conn->host.name, (int)conn->port, 1);
    ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
#else
    int ldap_option;
    char* ldap_ca = data->set.str[STRING_SSL_CAFILE];
#if defined(CURL_HAS_NOVELL_LDAPSDK)
    rc = ldapssl_client_init(NULL, NULL);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ldapssl_client_init %s", ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
    if(data->set.ssl.verifypeer) {
      /* Novell SDK supports DER or BASE64 files. */
      int cert_type = LDAPSSL_CERT_FILETYPE_B64;
      if((data->set.str[STRING_CERT_TYPE]) &&
         (Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "DER")))
        cert_type = LDAPSSL_CERT_FILETYPE_DER;
      if(!ldap_ca) {
        failf(data, "LDAP local: ERROR %s CA cert not set!",
              (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"));
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      infof(data, "LDAP local: using %s CA cert '%s'\n",
              (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
              ldap_ca);
      rc = ldapssl_add_trusted_cert(ldap_ca, cert_type);
      if(rc != LDAP_SUCCESS) {
        failf(data, "LDAP local: ERROR setting %s CA cert: %s",
                (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
                ldap_err2string(rc));
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      ldap_option = LDAPSSL_VERIFY_SERVER;
    }
    else
      ldap_option = LDAPSSL_VERIFY_NONE;
    rc = ldapssl_set_verify_mode(ldap_option);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ERROR setting cert verify mode: %s",
              ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
    server = ldapssl_init(conn->host.name, (int)conn->port, 1);
    if(server == NULL) {
      failf(data, "LDAP local: Cannot connect to %s:%ld",
              conn->host.name, conn->port);
      result = CURLE_COULDNT_CONNECT;
      goto quit;
    }
#elif defined(LDAP_OPT_X_TLS)
    if(data->set.ssl.verifypeer) {
      /* OpenLDAP SDK supports BASE64 files. */
      if((data->set.str[STRING_CERT_TYPE]) &&
         (!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) {
        failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      if(!ldap_ca) {
        failf(data, "LDAP local: ERROR PEM CA cert not set!");
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      infof(data, "LDAP local: using PEM CA cert: %s\n", ldap_ca);
      rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca);
      if(rc != LDAP_SUCCESS) {
        failf(data, "LDAP local: ERROR setting PEM CA cert: %s",
                ldap_err2string(rc));
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      ldap_option = LDAP_OPT_X_TLS_DEMAND;
    }
    else
      ldap_option = LDAP_OPT_X_TLS_NEVER;

    rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ERROR setting cert verify mode: %s",
              ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
    server = ldap_init(conn->host.name, (int)conn->port);
    if(server == NULL) {
      failf(data, "LDAP local: Cannot connect to %s:%ld",
              conn->host.name, conn->port);
      result = CURLE_COULDNT_CONNECT;
      goto quit;
    }
    ldap_option = LDAP_OPT_X_TLS_HARD;
    rc = ldap_set_option(server, LDAP_OPT_X_TLS, &ldap_option);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ERROR setting SSL/TLS mode: %s",
              ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
/*
    rc = ldap_start_tls_s(server, NULL, NULL);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ERROR starting SSL/TLS mode: %s",
              ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
*/
#else
    /* we should probably never come up to here since configure
       should check in first place if we can support LDAP SSL/TLS */
    failf(data, "LDAP local: SSL/TLS not supported with this version "
            "of the OpenLDAP toolkit\n");
    result = CURLE_SSL_CERTPROBLEM;
    goto quit;
#endif
#endif
#endif /* CURL_LDAP_USE_SSL */
  }
  else {
    server = ldap_init(conn->host.name, (int)conn->port);
    if(server == NULL) {
      failf(data, "LDAP local: Cannot connect to %s:%ld",
              conn->host.name, conn->port);
      result = CURLE_COULDNT_CONNECT;
      goto quit;
    }
  }
#ifdef CURL_LDAP_WIN
  ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
#endif

  rc = ldap_simple_bind_s(server,
                          conn->bits.user_passwd ? conn->user : NULL,
                          conn->bits.user_passwd ? conn->passwd : NULL);
  if(!ldap_ssl && rc != 0) {
    ldap_proto = LDAP_VERSION2;
    ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
    rc = ldap_simple_bind_s(server,
                            conn->bits.user_passwd ? conn->user : NULL,
                            conn->bits.user_passwd ? conn->passwd : NULL);
  }
  if(rc != 0) {
    failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc));
    result = CURLE_LDAP_CANNOT_BIND;
    goto quit;
  }

  rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
                     ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg);

  if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) {
    failf(data, "LDAP remote: %s", ldap_err2string(rc));
    result = CURLE_LDAP_SEARCH_FAILED;
    goto quit;
  }

  for(num = 0, entryIterator = ldap_first_entry(server, ldapmsg);
      entryIterator;
      entryIterator = ldap_next_entry(server, entryIterator), num++) {
    BerElement *ber = NULL;
    char  *attribute;       /*! suspicious that this isn't 'const' */
    char  *dn = ldap_get_dn(server, entryIterator);
    int i;

    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
    if(result)
      goto quit;

    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)dn, 0);
    if(result)
      goto quit;

    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
    if(result)
      goto quit;

    dlsize += strlen(dn)+5;

    for(attribute = ldap_first_attribute(server, entryIterator, &ber);
        attribute;
        attribute = ldap_next_attribute(server, entryIterator, ber)) {
      BerValue **vals = ldap_get_values_len(server, entryIterator, attribute);

      if(vals != NULL) {
        for(i = 0; (vals[i] != NULL); i++) {
          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
          if(result)
            goto quit;

          result = Curl_client_write(conn, CLIENTWRITE_BODY,
                                     (char *)attribute, 0);
          if(result)
            goto quit;

          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
          if(result)
            goto quit;
          dlsize += strlen(attribute)+3;

          if((strlen(attribute) > 7) &&
              (strcmp(";binary",
                      (char *)attribute +
                      (strlen((char *)attribute) - 7)) == 0)) {
            /* Binary attribute, encode to base64. */
            CURLcode error = Curl_base64_encode(data,
                                                vals[i]->bv_val,
                                                vals[i]->bv_len,
                                                &val_b64,
                                                &val_b64_sz);
            if(error) {
              ldap_value_free_len(vals);
              ldap_memfree(attribute);
              ldap_memfree(dn);
              if(ber)
                ber_free(ber, 0);
              result = error;
              goto quit;
            }
            if(val_b64_sz > 0) {
              result = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
                                         val_b64_sz);
              free(val_b64);
              if(result)
                goto quit;
              dlsize += val_b64_sz;
            }
          }
          else {
            result = Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
                                       vals[i]->bv_len);
            if(result)
              goto quit;
            dlsize += vals[i]->bv_len;
          }
          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
          if(result)
            goto quit;
          dlsize++;
        }

        /* Free memory used to store values */
        ldap_value_free_len(vals);
      }
      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
      if(result)
        goto quit;
      dlsize++;
      Curl_pgrsSetDownloadCounter(data, dlsize);
      ldap_memfree(attribute);
    }
    ldap_memfree(dn);
    if(ber)
       ber_free(ber, 0);
  }

quit:
  if(ldapmsg) {
    ldap_msgfree(ldapmsg);
    LDAP_TRACE (("Received %d entries\n", num));
  }
  if(rc == LDAP_SIZELIMIT_EXCEEDED)
    infof(data, "There are more than %d entries\n", num);
  if(ludp)
    ldap_free_urldesc(ludp);
  if(server)
    ldap_unbind_s(server);
#if defined(HAVE_LDAP_SSL) && defined(CURL_HAS_NOVELL_LDAPSDK)
  if(ldap_ssl)
    ldapssl_client_deinit();
#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */

  /* no data to transfer */
  Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
  connclose(conn, "LDAP connection always disable re-use");

  return result;
}
Exemple #28
0
int
main( int argc, char *argv[] )
{
	int 		rc, i, debug = 0, f2 = 0;
	unsigned 	flags[ 2 ] = { 0U, 0 };
	char		*strin, *str = NULL, buf[ 1024 ];
	LDAPDN		dn, dn2 = NULL;

	while ( 1 ) {
		int opt = getopt( argc, argv, "d:" );

		if ( opt == EOF ) {
			break;
		}

		switch ( opt ) {
		case 'd':
			debug = atoi( optarg );
			break;
		}
	}

	optind--;
	argc -= optind;
	argv += optind;

	if ( argc < 2 ) {
		fprintf( stderr, "usage: dntest <dn> [flags-in[,...]] [flags-out[,...]]\n\n" );
		fprintf( stderr, "\tflags-in:   V3,V2,DCE,<flags>\n" );
		fprintf( stderr, "\tflags-out:  V3,V2,UFN,DCE,AD,<flags>\n\n" );
		fprintf( stderr, "\t<flags>: PRETTY,PEDANTIC,NOSPACES,NOONESPACE\n\n" );
		return( 0 );
	}

	if ( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
		fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
	}
	if ( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
		fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
	}

	if ( strcmp( argv[ 1 ], "-" ) == 0 ) {
		size_t len = fgets( buf, sizeof( buf ), stdin ) ? strlen( buf ) : 0;

		if ( len == 0 || buf[ --len ] == '\n' ) {
			buf[ len ] = '\0';
		}
		strin = buf;
	} else {
		strin = argv[ 1 ];
	}

	if ( argc >= 3 ) {
		for ( i = 0; i < argc - 2; i++ ) {
			char *s, *e;
			for ( s = argv[ 2 + i ]; s; s = e ) {
				e = strchr( s, ',' );
				if ( e != NULL ) {
					e[ 0 ] = '\0';
					e++;
				}
	
				if ( !strcasecmp( s, "V3" ) ) {
					flags[ i ] |= LDAP_DN_FORMAT_LDAPV3;
				} else if ( !strcasecmp( s, "V2" ) ) {
					flags[ i ] |= LDAP_DN_FORMAT_LDAPV2;
				} else if ( !strcasecmp( s, "DCE" ) ) {
					flags[ i ] |= LDAP_DN_FORMAT_DCE;
				} else if ( !strcasecmp( s, "UFN" ) ) {
					flags[ i ] |= LDAP_DN_FORMAT_UFN;
				} else if ( !strcasecmp( s, "AD" ) ) {
					flags[ i ] |= LDAP_DN_FORMAT_AD_CANONICAL;
				} else if ( !strcasecmp( s, "PRETTY" ) ) {
					flags[ i ] |= LDAP_DN_PRETTY;
				} else if ( !strcasecmp( s, "PEDANTIC" ) ) {
					flags[ i ] |= LDAP_DN_PEDANTIC;
				} else if ( !strcasecmp( s, "NOSPACES" ) ) {
					flags[ i ] |= LDAP_DN_P_NOLEADTRAILSPACES;
				} else if ( !strcasecmp( s, "NOONESPACE" ) ) {
					flags[ i ] |= LDAP_DN_P_NOSPACEAFTERRDN;
				}
			}
		}
	}

	if ( flags[ 1 ] == 0 )
		flags[ 1 ] = LDAP_DN_FORMAT_LDAPV3;

	f2 = 1;

	rc = ldap_str2dn( strin, &dn, flags[ 0 ] );

	if ( rc == LDAP_SUCCESS ) {
		int i;
		if ( dn ) {
			for ( i = 0; dn[ i ]; i++ ) {
				LDAPRDN		rdn = dn[ i ];
				char		*rstr = NULL;

				if ( ldap_rdn2str( rdn, &rstr, flags[ f2 ] ) ) {
					fprintf( stdout, "\tldap_rdn2str() failed\n" );
					continue;
				}

				fprintf( stdout, "\tldap_rdn2str() = \"%s\"\n", rstr );
				ldap_memfree( rstr );
			}
		} else {
			fprintf( stdout, "\tempty DN\n" );
		}
	}

	str = NULL;
	if ( rc == LDAP_SUCCESS &&
		ldap_dn2str( dn, &str, flags[ f2 ] ) == LDAP_SUCCESS )
	{
		char	**values, *tmp, *tmp2, *str2 = NULL;
		int	n;
		
		fprintf( stdout, "\nldap_dn2str(ldap_str2dn(\"%s\"))\n"
				"\t= \"%s\"\n", strin, str );
			
		switch ( flags[ f2 ] & LDAP_DN_FORMAT_MASK ) {
		case LDAP_DN_FORMAT_UFN:
		case LDAP_DN_FORMAT_AD_CANONICAL:
			return( 0 );

		case LDAP_DN_FORMAT_LDAPV3:
		case LDAP_DN_FORMAT_LDAPV2:
			n = ldap_dn2domain( strin, &tmp );
			if ( n ) {
				fprintf( stdout, "\nldap_dn2domain(\"%s\") FAILED\n", strin );
			} else {
				fprintf( stdout, "\nldap_dn2domain(\"%s\")\n"
					"\t= \"%s\"\n", strin, tmp ? tmp : "" );
			}
			ldap_memfree( tmp );

			tmp = ldap_dn2ufn( strin );
			fprintf( stdout, "\nldap_dn2ufn(\"%s\")\n"
					"\t= \"%s\"\n", strin, tmp ? tmp : "" );
			ldap_memfree( tmp );

			tmp = ldap_dn2dcedn( strin );
			fprintf( stdout, "\nldap_dn2dcedn(\"%s\")\n"
					"\t= \"%s\"\n", strin, tmp ? tmp : "" );
			tmp2 = ldap_dcedn2dn( tmp );
			fprintf( stdout, "\nldap_dcedn2dn(\"%s\")\n"
					"\t= \"%s\"\n",
					tmp ? tmp : "", tmp2 ? tmp2 : "" );
			ldap_memfree( tmp );
			ldap_memfree( tmp2 );

			tmp = ldap_dn2ad_canonical( strin );
			fprintf( stdout, "\nldap_dn2ad_canonical(\"%s\")\n"
					"\t= \"%s\"\n", strin, tmp ? tmp : "" );
			ldap_memfree( tmp );

			fprintf( stdout, "\nldap_explode_dn(\"%s\"):\n", str );
			values = ldap_explode_dn( str, 0 );
			for ( n = 0; values && values[ n ]; n++ ) {
				char	**vv;
				int	nn;
				
				fprintf( stdout, "\t\"%s\"\n", values[ n ] );

				fprintf( stdout, "\tldap_explode_rdn(\"%s\")\n",
						values[ n ] );
				vv = ldap_explode_rdn( values[ n ], 0 );
				for ( nn = 0; vv && vv[ nn ]; nn++ ) {
					fprintf( stdout, "\t\t'%s'\n", 
							vv[ nn ] );
				}
				LDAP_VFREE( vv );

				fprintf( stdout, "\tldap_explode_rdn(\"%s\")"
					       " (no types)\n", values[ n ] );
				vv = ldap_explode_rdn( values[ n ], 1 );
				for ( nn = 0; vv && vv[ nn ]; nn++ ) {
					fprintf( stdout, "\t\t\t\"%s\"\n", 
							vv[ nn ] );
				}
				LDAP_VFREE( vv );
				
			}
			LDAP_VFREE( values );

			fprintf( stdout, "\nldap_explode_dn(\"%s\")"
					" (no types):\n", str );
			values = ldap_explode_dn( str, 1 );
			for ( n = 0; values && values[ n ]; n++ ) {
				fprintf( stdout, "\t\"%s\"\n", values[ n ] );
			}
			LDAP_VFREE( values );

			break;
		}

		dn2 = NULL;	
		rc = ldap_str2dn( str, &dn2, flags[ f2 ] );
		str2 = NULL;
		if ( rc == LDAP_SUCCESS && 
				ldap_dn2str( dn2, &str2, flags[ f2 ] )
				== LDAP_SUCCESS ) {
			int 	iRDN;
			
			fprintf( stdout, "\n\"%s\"\n\t == \"%s\" ? %s\n", 
				str, str2, 
				strcmp( str, str2 ) == 0 ? "yes" : "no" );

			if( dn != NULL && dn2 == NULL ) {
				fprintf( stdout, "dn mismatch\n" );
			} else if (( dn != NULL ) && (dn2 != NULL))
				for ( iRDN = 0; dn[ iRDN ] && dn2[ iRDN ]; iRDN++ )
			{
				LDAPRDN 	r = dn[ iRDN ];
				LDAPRDN 	r2 = dn2[ iRDN ];
				int 		iAVA;
				
				for ( iAVA = 0; r[ iAVA ] && r2[ iAVA ]; iAVA++ ) {
					LDAPAVA		*a = r[ iAVA ];
					LDAPAVA		*a2 = r2[ iAVA ];

					if ( a->la_attr.bv_len != a2->la_attr.bv_len ) {
						fprintf( stdout, "ava(%d), rdn(%d) attr len mismatch (%ld->%ld)\n", 
								iAVA + 1, iRDN + 1,
								a->la_attr.bv_len, a2->la_attr.bv_len );
					} else if ( memcmp( a->la_attr.bv_val, a2->la_attr.bv_val, a->la_attr.bv_len ) ) {
						fprintf( stdout, "ava(%d), rdn(%d) attr mismatch\n", 
								iAVA + 1, iRDN + 1 );
					} else if ( a->la_flags != a2->la_flags ) {
						fprintf( stdout, "ava(%d), rdn(%d) flag mismatch (%x->%x)\n", 
								iAVA + 1, iRDN + 1, a->la_flags, a2->la_flags );
					} else if ( a->la_value.bv_len != a2->la_value.bv_len ) {
						fprintf( stdout, "ava(%d), rdn(%d) value len mismatch (%ld->%ld)\n", 
								iAVA + 1, iRDN + 1, 
								a->la_value.bv_len, a2->la_value.bv_len );
					} else if ( memcmp( a->la_value.bv_val, a2->la_value.bv_val, a->la_value.bv_len ) ) {
						fprintf( stdout, "ava(%d), rdn(%d) value mismatch\n", 
								iAVA + 1, iRDN + 1 );
					}
				}
			}
			
			ldap_dnfree( dn2 );
			ldap_memfree( str2 );
		}
		ldap_memfree( str );
	}
	ldap_dnfree( dn );

	/* note: dn is not freed */

	return( 0 );
}
Exemple #29
0
// if getP is true, we get the attributes by recursing once
// (without getP set) in order to fill in *attrCount, then allocate
// and fill in the *aAttributes.  
// 
// if getP is false, just fill in *attrCount and return
// 
nsresult
nsLDAPMessage::IterateAttributes(PRUint32 *aAttrCount, char** *aAttributes, 
                 bool getP)
{
    BerElement *position;
    nsresult rv;

    if (!aAttrCount || !aAttributes ) {
        return NS_ERROR_INVALID_POINTER;
    }

    // if we've been called from GetAttributes, recurse once in order to
    // count the elements in this message.
    //
    if (getP) {
        *aAttributes = 0;
        *aAttrCount = 0;

        rv = IterateAttributes(aAttrCount, aAttributes, false);
        if (NS_FAILED(rv))
            return rv;

        // create an array of the appropriate size
        //
        *aAttributes = static_cast<char **>(nsMemory::Alloc(*aAttrCount *
                                                      sizeof(char *)));
        if (!*aAttributes) {
            return NS_ERROR_OUT_OF_MEMORY;
        }
    } 

    // get the first attribute
    //
    char *attr = ldap_first_attribute(mConnectionHandle, 
                                      mMsgHandle, 
                                      &position);
    if (!attr) {
        return IterateAttrErrHandler(ldap_get_lderrno(mConnectionHandle, 0, 0),
                                     aAttrCount, aAttributes, position);
    }

    // if we're getting attributes, try and fill in the first field
    //
    if (getP) {
        (*aAttributes)[0] = nsCRT::strdup(attr);
        if (!(*aAttributes)[0]) {
            ldap_memfree(attr);
            nsMemory::Free(*aAttributes);
            return NS_ERROR_OUT_OF_MEMORY;
        }

        // note that we start counting again, in order to keep our place in 
        // the array so that we can unwind gracefully and avoid leakage if
        // we hit an error as we're filling in the array
        //
        *aAttrCount = 1;
    } else {

        // otherwise just update the count
        //
        *aAttrCount = 1;
    }
    ldap_memfree(attr);

    while (1) {
    
        // get the next attribute
        //
        attr = ldap_next_attribute(mConnectionHandle, mMsgHandle, position);

        // check to see if there is an error, or if we're just done iterating
        //
        if (!attr) {
            
            // bail out if there's an error
            //
            PRInt32 lderrno = ldap_get_lderrno(mConnectionHandle, 0, 0);
            if (lderrno != LDAP_SUCCESS) {
                return IterateAttrErrHandler(lderrno, aAttrCount, aAttributes, 
                                             position);
            }

            // otherwise, there are no more attributes; we're done with
            // the while loop
            //
            break;

        } else if (getP) {

            // if ldap_next_attribute did return successfully, and 
            // we're supposed to fill in a value, do so.
            //
            (*aAttributes)[*aAttrCount] = nsCRT::strdup(attr);
            if (!(*aAttributes)[*aAttrCount]) {
                ldap_memfree(attr);
                return IterateAttrErrHandler(LDAP_NO_MEMORY, aAttrCount, 
                                             aAttributes, position);
            }
       
        }
        ldap_memfree(attr);

        // we're done using *aAttrCount as a c-style array index (ie starting
        // at 0).  update it to reflect the number of elements now in the array
        //
        *aAttrCount += 1;
    }

    // free the position pointer, if necessary
    //
    if (position) {
        ldap_ber_free(position, 0);
    }

    return NS_OK;
}
Exemple #30
0
int
main( int argc, char **argv )
{
	char		*rbuf = NULL, *rejbuf = NULL;
	FILE		*rejfp;
	struct LDIFFP *ldiffp = NULL, ldifdummy = {0};
	char		*matched_msg, *error_msg;
	int		rc, retval, ldifrc;
	int		len;
	int		i = 0, lmax = 0;
	unsigned long	lineno, nextline = 0;
	LDAPControl	c[1];

	prog = lutil_progname( "ldapmodify", argc, argv );

	/* strncmp instead of strcmp since NT binaries carry .exe extension */
	ldapadd = ( strncasecmp( prog, "ldapadd", sizeof("ldapadd")-1 ) == 0 );

	tool_init( ldapadd ? TOOL_ADD : TOOL_MODIFY );

	tool_args( argc, argv );

	if ( argc != optind ) usage();

	if ( rejfile != NULL ) {
		if (( rejfp = fopen( rejfile, "w" )) == NULL ) {
			perror( rejfile );
			retval = EXIT_FAILURE;
			goto fail;
		}
	} else {
		rejfp = NULL;
	}

	if ( infile != NULL ) {
		if (( ldiffp = ldif_open( infile, "r" )) == NULL ) {
			perror( infile );
			retval = EXIT_FAILURE;
			goto fail;
		}
	} else {
		ldifdummy.fp = stdin;
		ldiffp = &ldifdummy;
	}

	if ( debug ) ldif_debug = debug;

	ld = tool_conn_setup( dont, 0 );

	if ( !dont ) {
		tool_bind( ld );
	}

#ifdef LDAP_X_TXN
	if( txn ) {
		/* start transaction */
		rc = ldap_txn_start_s( ld, NULL, NULL, &txn_id );
		if( rc != LDAP_SUCCESS ) {
			tool_perror( "ldap_txn_start_s", rc, NULL, NULL, NULL, NULL );
			if( txn > 1 ) {
				retval = EXIT_FAILURE;
				goto fail;
			}
			txn = 0;
		}
	}
#endif

	if ( 0
#ifdef LDAP_X_TXN
		|| txn
#endif
		)
	{
#ifdef LDAP_X_TXN
		if( txn ) {
			c[i].ldctl_oid = LDAP_CONTROL_X_TXN_SPEC;
			c[i].ldctl_value = *txn_id;
			c[i].ldctl_iscritical = 1;
			i++;
		}
#endif
	}

	tool_server_controls( ld, c, i );

	rc = 0;
	retval = 0;
	lineno = 1;
	while (( rc == 0 || contoper ) && ( ldifrc = ldif_read_record( ldiffp, &nextline,
		&rbuf, &lmax )) > 0 )
	{
		if ( rejfp ) {
			len = strlen( rbuf );
			if (( rejbuf = (char *)ber_memalloc( len+1 )) == NULL ) {
				perror( "malloc" );
				retval = EXIT_FAILURE;
				goto fail;
			}
			memcpy( rejbuf, rbuf, len+1 );
		}

		rc = process_ldif_rec( rbuf, lineno );
		lineno = nextline+1;

		if ( rc ) retval = rc;
		if ( rc && rejfp ) {
			fprintf(rejfp, _("# Error: %s (%d)"), ldap_err2string(rc), rc);

			matched_msg = NULL;
			ldap_get_option(ld, LDAP_OPT_MATCHED_DN, &matched_msg);
			if ( matched_msg != NULL ) {
				if ( *matched_msg != '\0' ) {
					fprintf( rejfp, _(", matched DN: %s"), matched_msg );
				}
				ldap_memfree( matched_msg );
			}

			error_msg = NULL;
			ldap_get_option(ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, &error_msg);
			if ( error_msg != NULL ) {
				if ( *error_msg != '\0' ) {
					fprintf( rejfp, _(", additional info: %s"), error_msg );
				}
				ldap_memfree( error_msg );
			}
			fprintf( rejfp, "\n%s\n", rejbuf );
		}

		if (rejfp) ber_memfree( rejbuf );
	}
	ber_memfree( rbuf );

	if ( ldifrc < 0 )
		retval = LDAP_OTHER;

#ifdef LDAP_X_TXN
	if( retval == 0 && txn ) {
		rc = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, NULL );
		if ( rc != LDAP_OPT_SUCCESS ) {
			fprintf( stderr, "Could not unset controls for ldap_txn_end\n");
		}

		/* create transaction */
		rc = ldap_txn_end_s( ld, !txnabort, txn_id, NULL, NULL, NULL );
		if( rc != LDAP_SUCCESS ) {
			tool_perror( "ldap_txn_end_s", rc, NULL, NULL, NULL, NULL );
			retval = rc;
		}
	}
#endif

fail:;
	if ( rejfp != NULL ) {
		fclose( rejfp );
	}

	if ( ldiffp != NULL && ldiffp != &ldifdummy ) {
		ldif_close( ldiffp );
	}

	tool_exit( ld, retval );
}