Beispiel #1
0
void uwsgi_ldap_config(char *url) {

	LDAP *ldp;
	LDAPMessage *results, *entry;
	BerElement *ber;
	struct berval **bervalues;
	char *attr;
	char *uwsgi_attr;

	char *url_slash;

	int desired_version = LDAP_VERSION3;
	int ret;

	LDAPURLDesc *ldap_url;

	if (!ldap_is_ldap_url(url)) {
		uwsgi_log("invalid LDAP url.\n");
		exit(1);
	}

	if (ldap_url_parse(url, &ldap_url) != LDAP_SUCCESS) {
		uwsgi_log("unable to parse LDAP url.\n");
		exit(1);
	}

	uwsgi_log("[uWSGI] getting LDAP configuration from %s\n", url);

	url_slash = strchr(url, '/');
	url_slash = strchr(url_slash + 1, '/');

	url_slash = strchr(url_slash + 1, '/');
	if (url_slash) {
		url_slash[0] = 0;
	}

#ifdef UWSGI_DEBUG
	uwsgi_debug("LDAP URL: %s\n", url);
	uwsgi_debug("LDAP BASE DN: %s\n", ldap_url->lud_dn);
#endif

#if LDAP_API_VERSION >= 3000
	if ((ret = ldap_initialize(&ldp, url)) != LDAP_SUCCESS) {
		uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
		exit(1);
	}
#else
	if ((ldp = ldap_init(ldap_url->lud_host, ldap_url->lud_port)) == NULL) {
		uwsgi_error("ldap_init()");
		exit(1);
	}
#endif


	if ((ret = ldap_set_option(ldp, LDAP_OPT_PROTOCOL_VERSION, &desired_version)) != LDAP_OPT_SUCCESS) {
		uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
		exit(1);
	}


	if ((ret = ldap_search_ext_s(ldp, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, NULL, 0, NULL, NULL, NULL, 1, &results)) != LDAP_SUCCESS) {
		uwsgi_log("LDAP: %s\n", ldap_err2string(ret));
		exit(1);
	}

#ifdef UWSGI_DEBUG
	uwsgi_debug("LDAP connection initialized %p\n", ldp);
#endif

	free(ldap_url);

	if (ldap_count_entries(ldp, results) < 1) {
		uwsgi_log("no LDAP entry found\n");
		exit(1);
	}

	entry = ldap_first_entry(ldp, results);

	int found = 0;
	for (attr = ldap_first_attribute(ldp, entry, &ber); attr != NULL; attr = ldap_next_attribute(ldp, entry, ber)) {
		if (!strncmp(attr, "uWSGI", 5)) {

			found = 1;
			uwsgi_attr = malloc(calc_ldap_name(attr) + 1);
			if (!uwsgi_attr) {
				uwsgi_error("malloc()");
				exit(1);
			}

			ldap2uwsgi(attr + 5, uwsgi_attr);

#ifdef UWSGI_DEBUG
			uwsgi_debug("LDAP attribute: %s = --%s\n", attr, uwsgi_attr);
#endif
			bervalues = ldap_get_values_len(ldp, entry, attr);
			if (bervalues) {
				// do not free uwsgi_attr/uwsgi_val;
				char *uwsgi_val = malloc(bervalues[0]->bv_len + 1);
				if (!uwsgi_val) {
					uwsgi_error("malloc()");
					exit(1);
				}

				memcpy(uwsgi_val, bervalues[0]->bv_val, bervalues[0]->bv_len);
				uwsgi_val[bervalues[0]->bv_len] = 0;

				add_exported_option((char *) uwsgi_attr, uwsgi_val, 0);
				free(bervalues);
			}
			else {
				free(uwsgi_attr);
			}
		}
		free(attr);
	}

	if (!found) {
		uwsgi_log("no uWSGI LDAP entry found\n");
		exit(1);
	}

	free(ber);
	free(results);

	ldap_unbind_ext_s(ldp, NULL, NULL);

}
Beispiel #2
0
void ldapMessage(struct threadInfo * ti, int fatalError, char *infoMessage, char *ldapString) {
	if(ldapString != NULL && ldapString[0] != 0) {
		if((ti->directoryInfo.l != NULL) && (ldap_get_option(ti->directoryInfo.l, LDAP_OPT_RESULT_CODE, (int *) &ti->directoryInfo.i) == LDAP_OPT_SUCCESS)) {
			snprintf(ti->directoryInfo.errorString, sizeof(ti->directoryInfo.errorString), "%s: %s: %s%c", infoMessage, ldapString, ldap_err2string(ti->directoryInfo.i), 0);
		}
		else {
			snprintf(ti->directoryInfo.errorString, sizeof(ti->directoryInfo.errorString), "%s: %s%c", infoMessage, ldapString, 0);
		}
	}
	else {
		if((ti->directoryInfo.l != NULL) && (ldap_get_option(ti->directoryInfo.l, LDAP_OPT_RESULT_CODE, (int *) &ti->directoryInfo.i) == LDAP_OPT_SUCCESS)) {
			snprintf(ti->directoryInfo.errorString, sizeof(ti->directoryInfo.errorString), "%s: %s%c", infoMessage, ldap_err2string(ti->directoryInfo.i), 0);
		}
		else {
			snprintf(ti->directoryInfo.errorString, sizeof(ti->directoryInfo.errorString), "%s%c", infoMessage, 0);
		}
	}

	warningThread(fatalError, ti->directoryInfo.errorString, ti->directoryInfo.errorSpace, sizeof(ti->directoryInfo.errorSpace), ti->directoryInfo.a, &ti->directoryInfo.i);
}
Beispiel #3
0
/*
 * sets last_ldap_result and last_ldap_handle
 */
int lds_search(
	char* _lds_name,
	char* _dn,
	int _scope,
	char* _filter,
	char** _attrs,
	struct timeval* _search_timeout,
	int* _ld_result_count,
	int* _ld_error)
{
	struct ld_session* lds;
#ifdef LDAP_PERF
	struct timeval before_search = { 0, 0 }, after_search = { 0, 0 };
#endif

	/*
	 * get ld_handle
	 */
	if (get_connected_ldap_session(_lds_name, &lds) != 0)
	{
		LM_ERR("[%s]: couldn't get ldap session\n", _lds_name);
		return -1;
	}

	/*
	 * free last_ldap_result
	 */
        if (last_ldap_result != NULL) {
                ldap_msgfree(last_ldap_result);
                last_ldap_result = NULL;
        }

	
	LM_DBG(	"[%s]: performing LDAP search: dn [%s],"
		" scope [%d], filter [%s], client_timeout [%d] usecs\n",
		_lds_name,
		_dn,
		_scope,
		_filter,
		(int)(lds->client_search_timeout.tv_sec * 1000000 
			+ lds->client_search_timeout.tv_usec));
	
#ifdef LDAP_PERF
	gettimeofday(&before_search, NULL);
#endif

	/*
	 * perform ldap search
	 */
	*_ld_error = ldap_search_ext_s(
		lds->handle,
		_dn,
		_scope,
		_filter,
		_attrs,
		0,
		NULL,
		NULL,
		&lds->client_search_timeout,
		0,
		&last_ldap_result);

#ifdef LDAP_PERF
	gettimeofday(&after_search, NULL);

	LM_INFO("[%s]: LDAP search took [%d] usecs\n",
		_lds_name,
		(int)((after_search.tv_sec * 1000000 + after_search.tv_usec)
		- (before_search.tv_sec * 1000000 + before_search.tv_usec)));
#endif

	if (*_ld_error != LDAP_SUCCESS)
	{
		if (last_ldap_result != NULL)
		{
			ldap_msgfree(last_ldap_result);
			last_ldap_result = NULL;
		}

		if (LDAP_API_ERROR(*_ld_error))
		{
			ldap_disconnect(_lds_name);
		}
		
		LM_DBG( "[%s]: ldap_search_ext_st failed: %s\n",
			_lds_name,
			ldap_err2string(*_ld_error));
		return -1;
	}

	last_ldap_handle = lds->handle;
	*_ld_result_count = ldap_count_entries(lds->handle, last_ldap_result);
	if (*_ld_result_count < 0)
	{
		LM_DBG("[%s]: ldap_count_entries failed\n", _lds_name);
		return -1;
	}

	return 0;
}
static void *add_thread(char *id) {
  LDAPMod mod[4];
  LDAPMod *mods[5];
  char dn[BUFSIZ], name[40];
  char *cnvals[2], *snvals[2], *pwdvals[2], *ocvals[3];
  int i, rc, opcount;
  void *voidrc = (void *)0;

  printf("Starting add_thread %s.\n", id);
  opcount = 0;
  tsd_setup();

  for (i = 0; i < 4; i++) {
    mods[i] = &mod[i];
  }

  mods[4] = NULL;

  mod[0].mod_op = 0;
  mod[0].mod_type = "cn";
  mod[0].mod_values = cnvals;
  cnvals[1] = NULL;
  mod[1].mod_op = 0;
  mod[1].mod_type = "sn";
  mod[1].mod_values = snvals;
  snvals[1] = NULL;
  mod[2].mod_op = 0;
  mod[2].mod_type = "objectclass";
  mod[2].mod_values = ocvals;
  ocvals[0] = "top";
  ocvals[1] = "person";
  ocvals[2] = NULL;
  mod[3].mod_op = 0;
  mod[3].mod_type = "userPassword";
  mod[3].mod_values = pwdvals;
  pwdvals[1] = NULL;
  mods[4] = NULL;

  for (;;) {
    sprintf(name, "%d", get_random_id());
    sprintf(dn, "cn=%s, " BASE, name);
    cnvals[0] = name;
    snvals[0] = name;
    pwdvals[0] = name;

    printf("Thread %s: Adding entry (%s)\n", id, dn);
    rc = ldap_add_ext_s(ld, dn, mods, NULL, NULL);
    if (rc != LDAP_SUCCESS) {
      fprintf(stderr, "ldap_add_ext_s: %s\n", ldap_err2string(rc));
      if (rc == LDAP_SERVER_DOWN) {
        perror("ldap_add_ext_s");
        voidrc = (void *)1;
        goto add_cleanup_and_return;
      }
    }

    ++opcount;
    if (maxops != 0 && opcount >= maxops) {
      break;
    }
  }

add_cleanup_and_return:
  printf("Thread %s: attempted %d add operations\n", id, opcount);
  set_ld_error(0, NULL, NULL, NULL); /* disposes of memory */
  tsd_cleanup();
  free(id);
  return voidrc;
}
main(int argc, char **argv)

{
  pthread_attr_t attr;
  pthread_t *threadids;
  void *status;
  struct ldap_thread_fns tfns;
  struct ldap_extra_thread_fns extrafns;
  int rc, c, errflg, i, inited_attr;
  int doadd, dodelete, domodify, docompare, dosearch, dobind;
  int option_extthreads, option_restart;
  int each_thread_count, thread_count;
  extern int optind;
  extern char *optarg;

  doadd = dodelete = domodify = docompare = dobind = dosearch = 0;
  option_extthreads = option_restart = 0;
  inited_attr = 0;
  errflg = 0;
  each_thread_count = 1; /* how many of each type of thread? */
  rc = LDAP_SUCCESS;     /* optimistic */

  while ((c = getopt(argc, argv, "abcdmrsERi:n:o:S:")) != EOF) {
    switch (c) {
      case 'a': /* perform add operations */
        ++doadd;
        break;
      case 'b': /* perform bind operations */
        ++dobind;
        break;
      case 'c': /* perform compare operations */
        ++docompare;
        break;
      case 'd': /* perform delete operations */
        ++dodelete;
        break;
      case 'm': /* perform modify operations */
        ++domodify;
        break;
      case 'r': /* use range filters in searches */
        ++range_filters;
        break;
      case 's': /* perform search operations */
        ++dosearch;
        break;
      case 'E': /* use extended thread functions */
        ++option_extthreads;
        break;
      case 'R': /* turn on LDAP_OPT_RESTART */
        ++option_restart;
        break;
      case 'i': /* highest # used for entry names */
        maxid = atoi(optarg);
        break;
      case 'n': /* # threads for each operation */
        if ((each_thread_count = atoi(optarg)) < 1) {
          fprintf(stderr, "thread count must be > 0\n");
          ++errflg;
        }
        break;
      case 'o': /* operations to perform per thread */
        if ((maxops = atoi(optarg)) < 0) {
          fprintf(stderr, "operation limit must be >= 0\n");
          ++errflg;
        }
        break;
      case 'S': /* random number seed */
        if (*optarg == 'r') {
          int seed = (int)time((time_t *)0);
          srandom(seed);
          printf("Random seed: %d\n", seed);
        } else {
          srandom(atoi(optarg));
        }
        break;
      default:
        ++errflg;
        break;
    }
  }

  /* Check command-line syntax. */
  thread_count = each_thread_count *
                 (doadd + dodelete + domodify + dobind + docompare + dosearch);
  if (thread_count < 1) {
    fprintf(stderr, "Specify at least one of -a, -b, -c, -d, -m, or -s\n");
    ++errflg;
  }

  if (errflg || argc - optind != 2) {
    fprintf(stderr,
            "usage: %s [-abcdmrsER] [-i id] [-n thr]"
            " [-o oplim] [-S sd] host port\n",
            argv[0]);
    fputs(
        "\nWhere:\n"
        "\t\"id\" is the highest entry id (name) to use"
        " (default is MAXINT)\n"
        "\t\"thr\" is the number of threads for each operation"
        " (default is 1)\n"
        "\t\"oplim\" is the number of ops done by each thread"
        " (default is infinite)\n"
        "\t\"sd\" is a random() number seed (default is 1).  Use"
        " the letter r for\n"
        "\t\tsd to seed random() using time of day.\n"
        "\t\"host\" is the hostname of an LDAP directory server\n"
        "\t\"port\" is the TCP port of the LDAP directory server\n",
        stderr);
    fputs(
        "\nAnd the single character options are:\n"
        "\t-a\tstart thread(s) to perform add operations\n"
        "\t-b\tstart thread(s) to perform bind operations\n"
        "\t-c\tstart thread(s) to perform compare operations\n"
        "\t-d\tstart thread(s) to perform delete operations\n"
        "\t-m\tstart thread(s) to perform modify operations\n"
        "\t-s\tstart thread(s) to perform search operations\n"
        "\t-r\tuse range filters in searches\n"
        "\t-E\tinstall LDAP_OPT_EXTRA_THREAD_FN_PTRS\n"
        "\t-R\tturn on LDAP_OPT_RESTART\n",
        stderr);

    return (LDAP_PARAM_ERROR);
  }

  /* Create a key. */
  if (pthread_key_create(&key, free) != 0) {
    perror("pthread_key_create");
  }
  tsd_setup();

  /* Allocate space for thread ids */
  if ((threadids = (pthread_t *)calloc(thread_count, sizeof(pthread_t))) ==
      NULL) {
    rc = LDAP_LOCAL_ERROR;
    goto clean_up_and_return;
  }

  /* Initialize the LDAP session. */
  if ((ld = ldap_init(argv[optind], atoi(argv[optind + 1]))) == NULL) {
    perror("ldap_init");
    rc = LDAP_LOCAL_ERROR;
    goto clean_up_and_return;
  }

  /* Set the function pointers for dealing with mutexes
     and error information. */
  memset(&tfns, '\0', sizeof(struct ldap_thread_fns));
  tfns.ltf_mutex_alloc = (void *(*)(void))my_mutex_alloc;
  tfns.ltf_mutex_free = (void (*)(void *))my_mutex_free;
  tfns.ltf_mutex_lock = (int (*)(void *))pthread_mutex_lock;
  tfns.ltf_mutex_unlock = (int (*)(void *))pthread_mutex_unlock;
  tfns.ltf_get_errno = get_errno;
  tfns.ltf_set_errno = set_errno;
  tfns.ltf_get_lderrno = get_ld_error;
  tfns.ltf_set_lderrno = set_ld_error;
  tfns.ltf_lderrno_arg = NULL;

  /* Set up this session to use those function pointers. */

  rc = ldap_set_option(ld, LDAP_OPT_THREAD_FN_PTRS, (void *)&tfns);
  if (rc < 0) {
    rc = ldap_get_lderrno(ld, NULL, NULL);
    fprintf(stderr, "ldap_set_option (LDAP_OPT_THREAD_FN_PTRS): %s\n",
            ldap_err2string(rc));
    goto clean_up_and_return;
  }

  if (option_extthreads) {
    /* Set the function pointers for working with semaphores. */

    memset(&extrafns, '\0', sizeof(struct ldap_extra_thread_fns));
    extrafns.ltf_mutex_trylock = (int (*)(void *))pthread_mutex_trylock;
    extrafns.ltf_sema_alloc = (void *(*)(void))my_sema_alloc;
    extrafns.ltf_sema_free = (void (*)(void *))my_sema_free;
    extrafns.ltf_sema_wait = (int (*)(void *))my_sema_wait;
    extrafns.ltf_sema_post = (int (*)(void *))my_sema_post;

    /* Set up this session to use those function pointers. */

    if (ldap_set_option(ld, LDAP_OPT_EXTRA_THREAD_FN_PTRS, (void *)&extrafns) !=
        0) {
      rc = ldap_get_lderrno(ld, NULL, NULL);
      ldap_perror(ld,
                  "ldap_set_option"
                  " (LDAP_OPT_EXTRA_THREAD_FN_PTRS)");
      goto clean_up_and_return;
    }
  }

  if (option_restart &&
      ldap_set_option(ld, LDAP_OPT_RESTART, LDAP_OPT_ON) != 0) {
    rc = ldap_get_lderrno(ld, NULL, NULL);
    ldap_perror(ld, "ldap_set_option(LDAP_OPT_RESTART)");
    goto clean_up_and_return;
  }

  /* Attempt to bind to the server. */
  rc = ldap_simple_bind_s(ld, NAME, PASSWORD);
  if (rc != LDAP_SUCCESS) {
    fprintf(stderr, "ldap_simple_bind_s: %s\n", ldap_err2string(rc));
    goto clean_up_and_return;
  }

  /* Initialize the attribute. */
  if (pthread_attr_init(&attr) != 0) {
    perror("pthread_attr_init");
    rc = LDAP_LOCAL_ERROR;
    goto clean_up_and_return;
  }
  ++inited_attr;

  /* Specify that the threads are joinable. */
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

  /* Create all the requested threads */
  thread_count = 0;
  if (domodify) {
    for (i = 0; i < each_thread_count; ++i) {
      if (pthread_create(&threadids[thread_count], &attr, modify_thread,
                         get_id_str(thread_count)) != 0) {
        perror("pthread_create modify_thread");
        rc = LDAP_LOCAL_ERROR;
        goto clean_up_and_return;
      }
      ++thread_count;
    }
  }

  if (doadd) {
    for (i = 0; i < each_thread_count; ++i) {
      if (pthread_create(&threadids[thread_count], &attr, add_thread,
                         get_id_str(thread_count)) != 0) {
        perror("pthread_create add_thread");
        rc = LDAP_LOCAL_ERROR;
        goto clean_up_and_return;
      }
      ++thread_count;
    }
  }

  if (dodelete) {
    for (i = 0; i < each_thread_count; ++i) {
      if (pthread_create(&threadids[thread_count], &attr, delete_thread,
                         get_id_str(thread_count)) != 0) {
        perror("pthread_create delete_thread");
        rc = LDAP_LOCAL_ERROR;
        goto clean_up_and_return;
      }
      ++thread_count;
    }
  }

  if (dobind) {
    for (i = 0; i < each_thread_count; ++i) {
      if (pthread_create(&threadids[thread_count], &attr, bind_thread,
                         get_id_str(thread_count)) != 0) {
        perror("pthread_create bind_thread");
        rc = LDAP_LOCAL_ERROR;
        goto clean_up_and_return;
      }
      ++thread_count;
    }
  }

  if (docompare) {
    for (i = 0; i < each_thread_count; ++i) {
      if (pthread_create(&threadids[thread_count], &attr, compare_thread,
                         get_id_str(thread_count)) != 0) {
        perror("pthread_create compare_thread");
        rc = LDAP_LOCAL_ERROR;
        goto clean_up_and_return;
      }
      ++thread_count;
    }
  }

  if (dosearch) {
    for (i = 0; i < each_thread_count; ++i) {
      if (pthread_create(&threadids[thread_count], &attr, search_thread,
                         get_id_str(thread_count)) != 0) {
        perror("pthread_create search_thread");
        rc = LDAP_LOCAL_ERROR;
        goto clean_up_and_return;
      }
      ++thread_count;
    }
  }

  /* Wait until these threads exit. */
  for (i = 0; i < thread_count; ++i) {
    pthread_join(threadids[i], &status);
  }

clean_up_and_return:
  if (ld != NULL) {
    set_ld_error(0, NULL, NULL, NULL); /* disposes of memory */
    ldap_unbind(ld);
  }
  if (threadids != NULL) {
    free(threadids);
  }
  if (inited_attr) {
    pthread_attr_destroy(&attr);
  }
  tsd_cleanup();

  return (rc);
}
Beispiel #6
0
/*%
 * This function is the real core of the driver.   Zone, record
 * and client strings are passed in (or NULL is passed if the
 * string is not available).  The type of query we want to run
 * is indicated by the query flag, and the dbdata object is passed
 * passed in to.  dbdata really holds either:
 *        1) a list of database instances (in multithreaded mode) OR
 *        2) a single database instance (in single threaded mode)
 * The function will construct the query and obtain an available
 * database instance (DBI).  It will then run the query and hopefully
 * obtain a result set.
 */
static isc_result_t
ldap_get_results (const char *zone, const char *record, const char *client, unsigned int query, void *dbdata, void *ptr)
{
    isc_result_t result;

    dbinstance_t *dbi = NULL;

    char *querystring = NULL;

    LDAPURLDesc *ldap_url = NULL;

    int ldap_result = 0;

    LDAPMessage *ldap_msg = NULL;

    int i;

    int entries;

    /* get db instance / connection */
#ifdef ISC_PLATFORM_USETHREADS

    /* find an available DBI from the list */
    dbi = ldap_find_avail_conn ((db_list_t *) ((ldap_instance_t *) dbdata)->db);

#else                            /* ISC_PLATFORM_USETHREADS */

    /*
     * only 1 DBI - no need to lock instance lock either
     * only 1 thread in the whole process, no possible contention.
     */
    dbi = (dbinstance_t *) ((ldap_instance_t *) dbdata)->db;

#endif                            /* ISC_PLATFORM_USETHREADS */

    /* if DBI is null, can't do anything else */
    if (dbi == NULL)
        return (ISC_R_FAILURE);

    /* set fields */
    if (zone != NULL)
    {
        dbi->zone = isc_mem_strdup (ns_g_mctx, zone);
        if (dbi->zone == NULL)
        {
            result = ISC_R_NOMEMORY;
            goto cleanup;
        }
    }
    else
    {
        dbi->zone = NULL;
    }
    if (record != NULL)
    {
        dbi->record = isc_mem_strdup (ns_g_mctx, record);
        if (dbi->record == NULL)
        {
            result = ISC_R_NOMEMORY;
            goto cleanup;
        }
    }
    else
    {
        dbi->record = NULL;
    }
    if (client != NULL)
    {
        dbi->client = isc_mem_strdup (ns_g_mctx, client);
        if (dbi->client == NULL)
        {
            result = ISC_R_NOMEMORY;
            goto cleanup;
        }
    }
    else
    {
        dbi->client = NULL;
    }

    /* what type of query are we going to run? */
    switch (query)
    {
        case ALLNODES:
            /*
             * if the query was not passed in from the config file
             * then we can't run it.  return not_implemented, so
             * it's like the code for that operation was never
             * built into the driver.... AHHH flexibility!!!
             */
            if (dbi->allnodes_q == NULL)
            {
                result = ISC_R_NOTIMPLEMENTED;
                goto cleanup;
            }
            else
            {
                querystring = build_querystring (ns_g_mctx, dbi->allnodes_q);
            }
            break;
        case ALLOWXFR:
            /* same as comments as ALLNODES */
            if (dbi->allowxfr_q == NULL)
            {
                result = ISC_R_NOTIMPLEMENTED;
                goto cleanup;
            }
            else
            {
                querystring = build_querystring (ns_g_mctx, dbi->allowxfr_q);
            }
            break;
        case AUTHORITY:
            /* same as comments as ALLNODES */
            if (dbi->authority_q == NULL)
            {
                result = ISC_R_NOTIMPLEMENTED;
                goto cleanup;
            }
            else
            {
                querystring = build_querystring (ns_g_mctx, dbi->authority_q);
            }
            break;
        case FINDZONE:
            /* this is required.  It's the whole point of DLZ! */
            if (dbi->findzone_q == NULL)
            {
                isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE,
                               DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG (2),
                               "No query specified for findzone.  " "Findzone requires a query");
                result = ISC_R_FAILURE;
                goto cleanup;
            }
            else
            {
                querystring = build_querystring (ns_g_mctx, dbi->findzone_q);
            }
            break;
        case LOOKUP:
            /* this is required.  It's also a major point of DLZ! */
            if (dbi->lookup_q == NULL)
            {
                isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE,
                               DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG (2),
                               "No query specified for lookup.  " "Lookup requires a query");
                result = ISC_R_FAILURE;
                goto cleanup;
            }
            else
            {
                querystring = build_querystring (ns_g_mctx, dbi->lookup_q);
            }
            break;
        default:
            /*
             * this should never happen.  If it does, the code is
             * screwed up!
             */
            UNEXPECTED_ERROR (__FILE__, __LINE__, "Incorrect query flag passed to " "ldap_get_results");
            result = ISC_R_UNEXPECTED;
            goto cleanup;
    }

    /* if the querystring is null, Bummer, outta RAM.  UPGRADE TIME!!!   */
    if (querystring == NULL)
    {
        result = ISC_R_NOMEMORY;
        goto cleanup;
    }

    /*
     * output the full query string during debug so we can see
     * what lame error the query has.
     */
    isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE,
                   DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG (1), "\nQuery String: %s\n", querystring);

    /* break URL down into it's component parts, if error cleanup */
    ldap_result = ldap_url_parse (querystring, &ldap_url);
    if (ldap_result != LDAP_SUCCESS || ldap_url == NULL)
    {
        result = ISC_R_FAILURE;
        goto cleanup;
    }

    for (i = 0; i < 3; i++)
    {

        /*
         * dbi->dbconn may be null if trying to reconnect on a
         * previous query failed.
         */
        if (dbi->dbconn == NULL)
        {
            isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE,
                           DNS_LOGMODULE_DLZ, ISC_LOG_INFO, "LDAP driver attempting to re-connect");

            result = dlz_ldap_connect ((ldap_instance_t *) dbdata, dbi);
            if (result != ISC_R_SUCCESS)
            {
                result = ISC_R_FAILURE;
                continue;
            }
        }

        /* perform ldap search syncronously */
        ldap_result = ldap_search_s ((LDAP *) dbi->dbconn,
                                     ldap_url->lud_dn,
                                     ldap_url->lud_scope, ldap_url->lud_filter, ldap_url->lud_attrs, 0, &ldap_msg);

        /*
         * check return code.  No such object is ok, just
         * didn't find what we wanted
         */
        switch (ldap_result)
        {
            case LDAP_NO_SUCH_OBJECT:
                isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE,
                               DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG (1), "No object found matching " "query requirements");
                result = ISC_R_NOTFOUND;
                goto cleanup;
                break;
            case LDAP_SUCCESS:    /* on success do nothing */
                result = ISC_R_SUCCESS;
                i = 3;
                break;
            case LDAP_SERVER_DOWN:
                isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE,
                               DNS_LOGMODULE_DLZ, ISC_LOG_INFO, "LDAP driver attempting to re-connect");
                result = dlz_ldap_connect ((ldap_instance_t *) dbdata, dbi);
                if (result != ISC_R_SUCCESS)
                    result = ISC_R_FAILURE;
                break;
            default:
                /*
                 * other errors not ok.  Log error message and
                 * get out
                 */
                isc_log_write (dns_lctx, DNS_LOGCATEGORY_DATABASE,
                               DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "LDAP error: %s", ldap_err2string (ldap_result));
                result = ISC_R_FAILURE;
                goto cleanup;
                break;
        }                        /* close switch(ldap_result) */
    }                            /* end for (int i = 0 i < 3; i++) */

    if (result != ISC_R_SUCCESS)
        goto cleanup;

    switch (query)
    {
        case ALLNODES:
            result = ldap_process_results ((LDAP *) dbi->dbconn, ldap_msg, ldap_url->lud_attrs, ptr, isc_boolean_true);
            break;
        case AUTHORITY:
        case LOOKUP:
            result = ldap_process_results ((LDAP *) dbi->dbconn, ldap_msg, ldap_url->lud_attrs, ptr, isc_boolean_false);
            break;
        case ALLOWXFR:
            entries = ldap_count_entries ((LDAP *) dbi->dbconn, ldap_msg);
            if (entries == 0)
                result = ISC_R_NOPERM;
            else if (entries > 0)
                result = ISC_R_SUCCESS;
            else
                result = ISC_R_FAILURE;
            break;
        case FINDZONE:
            entries = ldap_count_entries ((LDAP *) dbi->dbconn, ldap_msg);
            if (entries == 0)
                result = ISC_R_NOTFOUND;
            else if (entries > 0)
                result = ISC_R_SUCCESS;
            else
                result = ISC_R_FAILURE;
            break;
        default:
            /*
             * this should never happen.  If it does, the code is
             * screwed up!
             */
            UNEXPECTED_ERROR (__FILE__, __LINE__, "Incorrect query flag passed to " "ldap_get_results");
            result = ISC_R_UNEXPECTED;
    }

  cleanup:
    /* it's always good to cleanup after yourself */

    /* if we retrieved results, free them */
    if (ldap_msg != NULL)
        ldap_msgfree (ldap_msg);

    if (ldap_url != NULL)
        ldap_free_urldesc (ldap_url);

    /* cleanup */
    if (dbi->zone != NULL)
        isc_mem_free (ns_g_mctx, dbi->zone);
    if (dbi->record != NULL)
        isc_mem_free (ns_g_mctx, dbi->record);
    if (dbi->client != NULL)
        isc_mem_free (ns_g_mctx, dbi->client);

#ifdef ISC_PLATFORM_USETHREADS

    /* release the lock so another thread can use this dbi */
    isc_mutex_unlock (&dbi->instance_lock);

#endif                            /* ISC_PLATFORM_USETHREADS */

    /* release query string */
    if (querystring != NULL)
        isc_mem_free (ns_g_mctx, querystring);

    /* return result */
    return (result);
}
int
slapschema( int argc, char **argv )
{
	ID id;
	int rc = EXIT_SUCCESS;
	const char *progname = "slapschema";
	Connection conn = { 0 };
	OperationBuffer	opbuf;
	Operation *op = NULL;
	void *thrctx;
	int requestBSF = 0;
	int doBSF = 0;

	slap_tool_init( progname, SLAPCAT, argc, argv );

	requestBSF = ( sub_ndn.bv_len || filter );

#ifdef SIGPIPE
	(void) SIGNAL( SIGPIPE, slapcat_sig );
#endif
#ifdef SIGHUP
	(void) SIGNAL( SIGHUP, slapcat_sig );
#endif
	(void) SIGNAL( SIGINT, slapcat_sig );
	(void) SIGNAL( SIGTERM, slapcat_sig );

	if( !be->be_entry_open ||
		!be->be_entry_close ||
		!( be->be_entry_first || be->be_entry_first_x ) ||
		!be->be_entry_next ||
		!be->be_entry_get )
	{
		fprintf( stderr, "%s: database doesn't support necessary operations.\n",
			progname );
		exit( EXIT_FAILURE );
	}

	if( be->be_entry_open( be, 0 ) != 0 ) {
		fprintf( stderr, "%s: could not open database.\n",
			progname );
		exit( EXIT_FAILURE );
	}

	thrctx = ldap_pvt_thread_pool_context();
	connection_fake_init( &conn, &opbuf, thrctx );
	op = &opbuf.ob_op;
	op->o_tmpmemctx = NULL;
	op->o_bd = be;


	if ( !requestBSF && be->be_entry_first ) {
		id = be->be_entry_first( be );

	} else {
		if ( be->be_entry_first_x ) {
			id = be->be_entry_first_x( be,
				sub_ndn.bv_len ? &sub_ndn : NULL, scope, filter );

		} else {
			assert( be->be_entry_first != NULL );
			doBSF = 1;
			id = be->be_entry_first( be );
		}
	}

	for ( ; id != NOID; id = be->be_entry_next( be ) ) {
		Entry* e;
		char textbuf[SLAP_TEXT_BUFLEN];
		size_t textlen = sizeof(textbuf);
		const char *text = NULL;

		if ( gotsig )
			break;

		e = be->be_entry_get( be, id );
		if ( e == NULL ) {
			printf("# no data for entry id=%08lx\n\n", (long) id );
			rc = EXIT_FAILURE;
			if( continuemode ) continue;
			break;
		}

		if ( doBSF ) {
			if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) )
			{
				be_entry_release_r( op, e );
				continue;
			}


			if ( filter != NULL ) {
				int rc = test_filter( NULL, e, filter );
				if ( rc != LDAP_COMPARE_TRUE ) {
					be_entry_release_r( op, e );
					continue;
				}
			}
		}

		if( verbose ) {
			printf( "# id=%08lx\n", (long) id );
		}

		rc = entry_schema_check( op, e, NULL, 0, 0, NULL,
			&text, textbuf, textlen );
		if ( rc != LDAP_SUCCESS ) {
			fprintf( ldiffp->fp, "# (%d) %s%s%s\n",
				rc, ldap_err2string( rc ),
				text ? ": " : "",
				text ? text : "" );
			fprintf( ldiffp->fp, "dn: %s\n\n", e->e_name.bv_val );
		}

		be_entry_release_r( op, e );
	}

	be->be_entry_close( be );

	if ( slap_tool_destroy() )
		rc = EXIT_FAILURE;

	return rc;
}
/* Check the userid & password.
 * Return 0 on success, 1 on failure
 */
static int
checkLDAP(LDAP * persistent_ld, const char *userid, const char *password, const char *ldapServer, int port)
{
    char dn[1024];
    int ret = 0;
    LDAP *bind_ld = NULL;

    if (!*password) {
	/* LDAP can't bind with a blank password. Seen as "anonymous"
	 * and always granted access
	 */
	if (debug)
	    fprintf(stderr, "Blank password given\n");
	return 1;
    }
    if (searchfilter) {
	char filter[16384];
	char escaped_login[1024];
	LDAPMessage *res = NULL;
	LDAPMessage *entry;
	char *searchattr[] =
	{(char *)LDAP_NO_ATTRS, NULL};
	char *userdn;
	int rc;
	LDAP *search_ld = persistent_ld;

	if (!search_ld)
	    search_ld = open_ldap_connection(ldapServer, port);

	ldap_escape_value(escaped_login, sizeof(escaped_login), userid);
	if (binddn) {
	    rc = ldap_simple_bind_s(search_ld, binddn, bindpasswd);
	    if (rc != LDAP_SUCCESS) {
		fprintf(stderr, PROGRAM_NAME ": WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc));
		ret = 1;
		goto search_done;
	    }
	}
	snprintf(filter, sizeof(filter), searchfilter, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login);
	if (debug)
	    fprintf(stderr, "user filter '%s', searchbase '%s'\n", filter, basedn);
	rc = ldap_search_s(search_ld, basedn, searchscope, filter, searchattr, 1, &res);
	if (rc != LDAP_SUCCESS) {
	    if (noreferrals && rc == LDAP_PARTIAL_RESULTS) {
		/* Everything is fine. This is expected when referrals
		 * are disabled.
		 */
		if (debug)
		    fprintf(stderr, "noreferrals && rc == LDAP_PARTIAL_RESULTS\n");
	    } else {
		fprintf(stderr, PROGRAM_NAME ": WARNING, LDAP search error '%s'\n", ldap_err2string(rc));
#if defined(NETSCAPE_SSL)
		if (sslpath && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR))) {
		    int sslerr = PORT_GetError();
		    fprintf(stderr, PROGRAM_NAME ": WARNING, SSL error %d (%s)\n", sslerr, ldapssl_err2string(sslerr));
		}
#endif
		ret = 1;
		goto search_done;
	    }
	}
	entry = ldap_first_entry(search_ld, res);
	if (!entry) {
	    if (debug)
		fprintf(stderr, "Ldap search returned nothing\n");
	    ret = 1;
	    goto search_done;
	}
	userdn = ldap_get_dn(search_ld, entry);
	if (!userdn) {
	    fprintf(stderr, PROGRAM_NAME ": ERROR, could not get user DN for '%s'\n", userid);
	    ret = 1;
	    goto search_done;
	}
	snprintf(dn, sizeof(dn), "%s", userdn);
	squid_ldap_memfree(userdn);

	if (ret == 0 && (!binddn || !bind_once || passwdattr)) {
	    /* Reuse the search connection for comparing the user password attribute */
	    bind_ld = search_ld;
	    search_ld = NULL;
	}
      search_done:
	if (res) {
	    ldap_msgfree(res);
	    res = NULL;
	}
	if (search_ld && search_ld != persistent_ld) {
	    ldap_unbind(search_ld);
	    search_ld = NULL;
	}
	if (ret != 0)
	    return ret;
    } else {
	snprintf(dn, sizeof(dn), "%s=%s,%s", userattr, userid, basedn);
    }

    if (debug)
	fprintf(stderr, "attempting to authenticate user '%s'\n", dn);
    if (!bind_ld && !bind_once)
	bind_ld = persistent_ld;
    if (!bind_ld)
	bind_ld = open_ldap_connection(ldapServer, port);
    if (passwdattr) {
	if (ldap_compare_s(bind_ld, dn, passwdattr, password) != LDAP_COMPARE_TRUE) {
	    ret = 1;
	}
    } else if (ldap_simple_bind_s(bind_ld, dn, password) != LDAP_SUCCESS)
	ret = 1;
    if (bind_ld != persistent_ld) {
	ldap_unbind(bind_ld);
	bind_ld = NULL;
    }
    return ret;
}
Beispiel #9
0
int
main(int argc, char **argv)
{
    char buf[8192];
    char *user, *group, *extension_dn = NULL;
    char *ldapServer = NULL;
    LDAP *ld = NULL;
    int tryagain = 0, rc;
    int port = LDAP_PORT;
    int use_extension_dn = 0;
    int strip_nt_domain = 0;
    int strip_kerberos_realm = 0;
    int err = 0;

    setbuf(stdout, NULL);

    while (argc > 1 && argv[1][0] == '-') {
	char *value = "";
	char option = argv[1][1];
	switch (option) {
	case 'P':
	case 'R':
	case 'z':
	case 'Z':
	case 'd':
	case 'g':
	case 'S':
	    break;
	default:
	    if (strlen(argv[1]) > 2) {
		value = argv[1] + 2;
	    } else if (argc > 2) {
		value = argv[2];
		argv++;
		argc--;
	    } else
		value = "";
	    break;
	}
	argv++;
	argc--;
	switch (option) {
	case 'H':
#if !HAS_URI_SUPPORT
	    fprintf(stderr, "ERROR: Your LDAP library does not have URI support\n");
	    exit(1);
#endif
	    /* Fall thru to -h */
	case 'h':
	    if (ldapServer) {
		int len = strlen(ldapServer) + 1 + strlen(value) + 1;
		char *newhost = malloc(len);
		snprintf(newhost, len, "%s %s", ldapServer, value);
		free(ldapServer);
		ldapServer = newhost;
	    } else {
		ldapServer = strdup(value);
	    }
	    break;
	case 'b':
	    basedn = value;
	    break;
	case 'f':
	    searchfilter = value;
	    break;
	case 'B':
	    userbasedn = value;
	    break;
	case 'F':
	    usersearchfilter = value;
	    break;
	case 'u':
	    userdnattr = value;
	    break;
	case 's':
	    if (strcmp(value, "base") == 0)
		searchscope = LDAP_SCOPE_BASE;
	    else if (strcmp(value, "one") == 0)
		searchscope = LDAP_SCOPE_ONELEVEL;
	    else if (strcmp(value, "sub") == 0)
		searchscope = LDAP_SCOPE_SUBTREE;
	    else {
		fprintf(stderr, PROGRAM_NAME " ERROR: Unknown search scope '%s'\n", value);
		exit(1);
	    }
	    break;
	case 'E':
#if defined(NETSCAPE_SSL)
	    sslpath = value;
	    if (port == LDAP_PORT)
		port = LDAPS_PORT;
#else
	    fprintf(stderr, PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n");
	    exit(1);
#endif
	    break;
	case 'c':
	    connect_timeout = atoi(value);
	    break;
	case 't':
	    timelimit = atoi(value);
	    break;
	case 'a':
	    if (strcmp(value, "never") == 0)
		aliasderef = LDAP_DEREF_NEVER;
	    else if (strcmp(value, "always") == 0)
		aliasderef = LDAP_DEREF_ALWAYS;
	    else if (strcmp(value, "search") == 0)
		aliasderef = LDAP_DEREF_SEARCHING;
	    else if (strcmp(value, "find") == 0)
		aliasderef = LDAP_DEREF_FINDING;
	    else {
		fprintf(stderr, PROGRAM_NAME " ERROR: Unknown alias dereference method '%s'\n", value);
		exit(1);
	    }
	    break;
	case 'D':
	    binddn = value;
	    break;
	case 'w':
	    bindpasswd = value;
	    break;
	case 'W':
	    readSecret(value);
	    break;
	case 'P':
	    persistent = !persistent;
	    break;
	case 'p':
	    port = atoi(value);
	    break;
	case 'R':
	    noreferrals = !noreferrals;
	    break;
#ifdef LDAP_VERSION3
	case 'v':
	    switch (atoi(value)) {
	    case 2:
		version = LDAP_VERSION2;
		break;
	    case 3:
		version = LDAP_VERSION3;
		break;
	    default:
		fprintf(stderr, "Protocol version should be 2 or 3\n");
		exit(1);
	    }
	    break;
	case 'Z':
	    if (version == LDAP_VERSION2) {
		fprintf(stderr, "TLS (-Z) is incompatible with version %d\n",
		    version);
		exit(1);
	    }
	    version = LDAP_VERSION3;
	    use_tls = 1;
	    break;
#endif
	case 'd':
	    debug = 1;
	    break;
	case 'g':
	    use_extension_dn = 1;
	    break;
	case 'S':
	    strip_nt_domain = 1;
	    break;
	case 'K':
	    strip_kerberos_realm = 1;
	    break;
	default:
	    fprintf(stderr, PROGRAM_NAME " ERROR: Unknown command line option '%c'\n", option);
	    exit(1);
	}
    }

    while (argc > 1) {
	char *value = argv[1];
	if (ldapServer) {
	    int len = strlen(ldapServer) + 1 + strlen(value) + 1;
	    char *newhost = malloc(len);
	    snprintf(newhost, len, "%s %s", ldapServer, value);
	    free(ldapServer);
	    ldapServer = newhost;
	} else {
	    ldapServer = strdup(value);
	}
	argc--;
	argv++;
    }

    if (!ldapServer)
	ldapServer = "localhost";

    if (!basedn || !searchfilter) {
	fprintf(stderr, "\n" PROGRAM_NAME " version " PROGRAM_VERSION "\n\n");
	fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn -f filter [options] ldap_server_name\n\n");
	fprintf(stderr, "\t-b basedn (REQUIRED)\tbase dn under where to search for groups\n");
	fprintf(stderr, "\t-f filter (REQUIRED)\tgroup search filter pattern. %%u = user,\n\t\t\t\t%%g = group\n");
	fprintf(stderr, "\t-B basedn (REQUIRED)\tbase dn under where to search for users\n");
	fprintf(stderr, "\t-F filter (REQUIRED)\tuser search filter pattern. %%s = login\n");
	fprintf(stderr, "\t-s base|one|sub\t\tsearch scope\n");
	fprintf(stderr, "\t-D binddn\t\tDN to bind as to perform searches\n");
	fprintf(stderr, "\t-w bindpasswd\t\tpassword for binddn\n");
	fprintf(stderr, "\t-W secretfile\t\tread password for binddn from file secretfile\n");
#if HAS_URI_SUPPORT
	fprintf(stderr, "\t-H URI\t\t\tLDAPURI (defaults to ldap://localhost)\n");
#endif
	fprintf(stderr, "\t-h server\t\tLDAP server (defaults to localhost)\n");
	fprintf(stderr, "\t-p port\t\t\tLDAP server port (defaults to %d)\n", LDAP_PORT);
	fprintf(stderr, "\t-P\t\t\tpersistent LDAP connection\n");
#if defined(NETSCAPE_SSL)
	fprintf(stderr, "\t-E sslcertpath\t\tenable LDAP over SSL\n");
#endif
	fprintf(stderr, "\t-c timeout\t\tconnect timeout\n");
	fprintf(stderr, "\t-t timelimit\t\tsearch time limit\n");
	fprintf(stderr, "\t-R\t\t\tdo not follow referrals\n");
	fprintf(stderr, "\t-a never|always|search|find\n\t\t\t\twhen to dereference aliases\n");
#ifdef LDAP_VERSION3
	fprintf(stderr, "\t-v 2|3\t\t\tLDAP version\n");
	fprintf(stderr, "\t-Z\t\t\tTLS encrypt the LDAP connection, requires\n\t\t\t\tLDAP version 3\n");
#endif
	fprintf(stderr, "\t-g\t\t\tfirst query parameter is base DN extension\n\t\t\t\tfor this query\n");
	fprintf(stderr, "\t-S\t\t\tStrip NT domain from usernames\n");
	fprintf(stderr, "\t-K\t\t\tStrip Kerberos realm from usernames\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "\tIf you need to bind as a user to perform searches then use the\n\t-D binddn -w bindpasswd or -D binddn -W secretfile options\n\n");
	exit(1);
    }
/* On Windows ldap_start_tls_s is available starting from Windows XP, 
 * so we need to bind at run-time with the function entry point
 */
#ifdef _SQUID_MSWIN_
    if (use_tls) {

	HMODULE WLDAP32Handle;

	WLDAP32Handle = GetModuleHandle("wldap32");
	if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) {
	    fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n");
	    exit(1);
	}
    }
#endif

    while (fgets(buf, 256, stdin) != NULL) {
	int found = 0;
	if (!strchr(buf, '\n')) {
	    /* too large message received.. skip and deny */
	    fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], buf);
	    while (fgets(buf, sizeof(buf), stdin)) {
		fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], buf);
		if (strchr(buf, '\n') != NULL)
		    break;
	    }
	    goto error;
	}
	user = strtok(buf, " \n");
	if (!user) {
	    fprintf(stderr, "%s: Invalid request\n", argv[0]);
	    goto error;
	}
	rfc1738_unescape(user);
	if (strip_nt_domain) {
	    char *u = strrchr(user, '\\');
	    if (!u)
		u = strrchr(user, '/');
	    if (u && u[1])
		user = u + 1;
	}
	if (strip_kerberos_realm) {
	    char *u = strchr(user, '@');
	    if (u != NULL) {
		*u = '\0';
	    }
	}
	if (use_extension_dn) {
	    extension_dn = strtok(NULL, " \n");
	    if (!extension_dn) {
		fprintf(stderr, "%s: Invalid request\n", argv[0]);
		goto error;
	    }
	    rfc1738_unescape(extension_dn);
	}
	while (!found && user && (group = strtok(NULL, " \n")) != NULL) {
	    rfc1738_unescape(group);

	  recover:
	    if (ld == NULL) {
#if HAS_URI_SUPPORT
		if (strstr(ldapServer, "://") != NULL) {
		    rc = ldap_initialize(&ld, ldapServer);
		    if (rc != LDAP_SUCCESS) {
			fprintf(stderr, "\nUnable to connect to LDAPURI:%s\n", ldapServer);
			break;
		    }
		} else
#endif
#if NETSCAPE_SSL
		if (sslpath) {
		    if (!sslinit && (ldapssl_client_init(sslpath, NULL) != LDAP_SUCCESS)) {
			fprintf(stderr, "\nUnable to initialise SSL with cert path %s\n",
			    sslpath);
			exit(1);
		    } else {
			sslinit++;
		    }
		    if ((ld = ldapssl_init(ldapServer, port, 1)) == NULL) {
			fprintf(stderr, "\nUnable to connect to SSL LDAP server: %s port:%d\n",
			    ldapServer, port);
			exit(1);
		    }
		} else
#endif
		if ((ld = ldap_init(ldapServer, port)) == NULL) {
		    fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", ldapServer, port);
		    break;
		}
		if (connect_timeout)
		    squid_ldap_set_connect_timeout(ld, connect_timeout);

#ifdef LDAP_VERSION3
		if (version == -1) {
		    version = LDAP_VERSION2;
		}
		if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS) {
		    fprintf(stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
			version);
		    ldap_unbind(ld);
		    ld = NULL;
		    break;
		}
		if (use_tls) {
#ifdef LDAP_OPT_X_TLS
		    if (version != LDAP_VERSION3) {
			fprintf(stderr, "TLS requires LDAP version 3\n");
			exit(1);
		    } else if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) {
			fprintf(stderr, "Could not Activate TLS connection\n");
			ldap_unbind(ld);
			ld = NULL;
			break;
		    }
#else
		    fprintf(stderr, "TLS not supported with your LDAP library\n");
		    exit(1);
#endif
		}
#endif
		squid_ldap_set_timelimit(ld, timelimit);
		squid_ldap_set_referrals(ld, !noreferrals);
		squid_ldap_set_aliasderef(ld, aliasderef);
		if (binddn && bindpasswd && *binddn && *bindpasswd) {
		    rc = ldap_simple_bind_s(ld, binddn, bindpasswd);
		    if (rc != LDAP_SUCCESS) {
			fprintf(stderr, PROGRAM_NAME " WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc));
			ldap_unbind(ld);
			ld = NULL;
			break;
		    }
		}
		if (debug)
		    fprintf(stderr, "Connected OK\n");
	    }
	    if (searchLDAP(ld, group, user, extension_dn) == 0) {
		found = 1;
		break;
	    } else {
		if (tryagain) {
		    tryagain = 0;
		    ldap_unbind(ld);
		    ld = NULL;
		    goto recover;
		}
	    }
	}
	if (found)
	    printf("OK\n");
	else {
	  error:
	    printf("ERR\n");
	}

	if (ld != NULL) {
	    if (!persistent || (squid_ldap_errno(ld) != LDAP_SUCCESS && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS)) {
		ldap_unbind(ld);
		ld = NULL;
	    } else {
		tryagain = 1;
	    }
	}
	err = 0;
    }
    if (ld)
	ldap_unbind(ld);
    return 0;
}
Beispiel #10
0
/*
 * Look up a user in the directory to see if this is an account that can be authenticated
 */
int CtdlTryUserLDAP(char *username,
		char *found_dn, int found_dn_size,
		char *fullname, int fullname_size,
		uid_t *uid, int lookup_based_on_username)
{
	LDAP *ldserver = NULL;
	int i;
	LDAPMessage *search_result = NULL;
	LDAPMessage *entry = NULL;
	char searchstring[1024];
	struct timeval tv;
	char **values;
	char *user_dn = NULL;

	if (fullname) safestrncpy(fullname, username, fullname_size);

	if (ctdl_ldap_initialize(&ldserver) != LDAP_SUCCESS) {
		return(errno);
	}

	ldap_set_option(ldserver, LDAP_OPT_PROTOCOL_VERSION, &ctdl_require_ldap_version);
	ldap_set_option(ldserver, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF);

	striplt(CtdlGetConfigStr("c_ldap_bind_dn"));
	striplt(CtdlGetConfigStr("c_ldap_bind_pw"));
	syslog(LOG_DEBUG, "LDAP bind DN: %s", CtdlGetConfigStr("c_ldap_bind_dn"));
	i = ldap_simple_bind_s(ldserver,
		(!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_dn")) ? CtdlGetConfigStr("c_ldap_bind_dn") : NULL),
		(!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_pw")) ? CtdlGetConfigStr("c_ldap_bind_pw") : NULL)
	);
	if (i != LDAP_SUCCESS) {
		syslog(LOG_ALERT, "LDAP: Cannot bind: %s (%d)", ldap_err2string(i), i);
		return(i);
	}

	tv.tv_sec = 10;
	tv.tv_usec = 0;

	if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) {
		if (lookup_based_on_username != 0)
			snprintf(searchstring, sizeof(searchstring), "(displayName=%s)",username);
		else
			snprintf(searchstring, sizeof(searchstring), "(sAMAccountName=%s)", username);
	}
	else {
		if (lookup_based_on_username != 0)
			snprintf(searchstring, sizeof(searchstring), "(cn=%s)",username);
		else
			snprintf(searchstring, sizeof(searchstring), "(&(objectclass=posixAccount)(uid=%s))", username);
	}

	syslog(LOG_DEBUG, "LDAP search: %s", searchstring);
	(void) ldap_search_ext_s(
		ldserver,					/* ld				*/
		CtdlGetConfigStr("c_ldap_base_dn"),		/* base				*/
		LDAP_SCOPE_SUBTREE,				/* scope			*/
		searchstring,					/* filter			*/
		NULL,						/* attrs (all attributes)	*/
		0,						/* attrsonly (attrs + values)	*/
		NULL,						/* serverctrls (none)		*/
		NULL,						/* clientctrls (none)		*/
		&tv,						/* timeout			*/
		1,						/* sizelimit (1 result max)	*/
		&search_result					/* res				*/
	);

	/* Ignore the return value of ldap_search_ext_s().  Sometimes it returns an error even when
	 * the search succeeds.  Instead, we check to see whether search_result is still NULL.
	 */
	if (search_result == NULL) {
		syslog(LOG_DEBUG, "LDAP search: zero results were returned");
		ldap_unbind(ldserver);
		return(2);
	}

	/* At this point we've got at least one result from our query.  If there are multiple
	 * results, we still only look at the first one.
	 */
	entry = ldap_first_entry(ldserver, search_result);
	if (entry) {

		user_dn = ldap_get_dn(ldserver, entry);
		if (user_dn) {
			syslog(LOG_DEBUG, "dn = %s", user_dn);
		}

		if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) {
			values = ldap_get_values(ldserver, search_result, "displayName");
			if (values) {
				if (values[0]) {
					if (fullname) safestrncpy(fullname, values[0], fullname_size);
					syslog(LOG_DEBUG, "displayName = %s", values[0]);
				}
				ldap_value_free(values);
			}
		}
		else {
			values = ldap_get_values(ldserver, search_result, "cn");
			if (values) {
				if (values[0]) {
					if (fullname) safestrncpy(fullname, values[0], fullname_size);
					syslog(LOG_DEBUG, "cn = %s", values[0]);
				}
				ldap_value_free(values);
			}
		}
		/* If we know the username is the CN/displayName, we already set the uid*/
		if (lookup_based_on_username==0) {
			if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) {
				values = ldap_get_values(ldserver, search_result, "objectGUID");
				if (values) {
					if (values[0]) {
						if (uid != NULL) {
							*uid = abs(HashLittle(values[0], strlen(values[0])));
							syslog(LOG_DEBUG, "uid hashed from objectGUID = %d", *uid);
						}
					}
					ldap_value_free(values);
				}
			}
			else {
				values = ldap_get_values(ldserver, search_result, "uidNumber");
				if (values) {
					if (values[0]) {
						syslog(LOG_DEBUG, "uidNumber = %s", values[0]);
						if (uid != NULL) {
							*uid = atoi(values[0]);
						}
					}
					ldap_value_free(values);
				}
			}
		}

	}

	/* free the results */
	ldap_msgfree(search_result);

	/* unbind so we can go back in as the authenticating user */
	ldap_unbind(ldserver);

	if (!user_dn) {
		syslog(LOG_DEBUG, "No such user was found.");
		return(4);
	}

	if (found_dn) safestrncpy(found_dn, user_dn, found_dn_size);
	ldap_memfree(user_dn);
	return(0);
}
int
main(int argc, char **argv)
{
    char buf[1024];
    char *user, *passwd;
    char *ldapServer = NULL;
    LDAP *ld = NULL;
    int tryagain;
    int port = LDAP_PORT;

    setbuf(stdout, NULL);

    while (argc > 1 && argv[1][0] == '-') {
	const char *value = "";
	char option = argv[1][1];
	switch (option) {
	case 'P':
	case 'R':
	case 'z':
	case 'Z':
	case 'd':
	case 'O':
	    break;
	default:
	    if (strlen(argv[1]) > 2) {
		value = argv[1] + 2;
	    } else if (argc > 2) {
		value = argv[2];
		argv++;
		argc--;
	    } else
		value = "";
	    break;
	}
	argv++;
	argc--;
	switch (option) {
	case 'H':
#if !HAS_URI_SUPPORT
	    fprintf(stderr, "ERROR: Your LDAP library does not have URI support\n");
	    exit(1);
#endif
	    /* Fall thru to -h */
	case 'h':
	    if (ldapServer) {
		int len = strlen(ldapServer) + 1 + strlen(value) + 1;
		char *newhost = malloc(len);
		snprintf(newhost, len, "%s %s", ldapServer, value);
		free(ldapServer);
		ldapServer = newhost;
	    } else {
		ldapServer = strdup(value);
	    }
	    break;
	case 'b':
	    basedn = value;
	    break;
	case 'f':
	    searchfilter = value;
	    break;
	case 'u':
	    userattr = value;
	    break;
	case 'U':
	    passwdattr = value;
	    break;
	case 's':
	    if (strcmp(value, "base") == 0)
		searchscope = LDAP_SCOPE_BASE;
	    else if (strcmp(value, "one") == 0)
		searchscope = LDAP_SCOPE_ONELEVEL;
	    else if (strcmp(value, "sub") == 0)
		searchscope = LDAP_SCOPE_SUBTREE;
	    else {
		fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown search scope '%s'\n", value);
		exit(1);
	    }
	    break;
	case 'E':
#if defined(NETSCAPE_SSL)
	    sslpath = value;
	    if (port == LDAP_PORT)
		port = LDAPS_PORT;
#else
	    fprintf(stderr, PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n");
	    exit(1);
#endif
	    break;
	case 'c':
	    connect_timeout = atoi(value);
	    break;
	case 't':
	    timelimit = atoi(value);
	    break;
	case 'a':
	    if (strcmp(value, "never") == 0)
		aliasderef = LDAP_DEREF_NEVER;
	    else if (strcmp(value, "always") == 0)
		aliasderef = LDAP_DEREF_ALWAYS;
	    else if (strcmp(value, "search") == 0)
		aliasderef = LDAP_DEREF_SEARCHING;
	    else if (strcmp(value, "find") == 0)
		aliasderef = LDAP_DEREF_FINDING;
	    else {
		fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown alias dereference method '%s'\n", value);
		exit(1);
	    }
	    break;
	case 'D':
	    binddn = value;
	    break;
	case 'w':
	    bindpasswd = value;
	    break;
	case 'W':
	    readSecret(value);
	    break;
	case 'P':
	    persistent = !persistent;
	    break;
	case 'O':
	    bind_once = !bind_once;
	    break;
	case 'p':
	    port = atoi(value);
	    break;
	case 'R':
	    noreferrals = !noreferrals;
	    break;
#ifdef LDAP_VERSION3
	case 'v':
	    switch (atoi(value)) {
	    case 2:
		version = LDAP_VERSION2;
		break;
	    case 3:
		version = LDAP_VERSION3;
		break;
	    default:
		fprintf(stderr, "Protocol version should be 2 or 3\n");
		exit(1);
	    }
	    break;
	case 'Z':
	    if (version == LDAP_VERSION2) {
		fprintf(stderr, "TLS (-Z) is incompatible with version %d\n",
		    version);
		exit(1);
	    }
	    version = LDAP_VERSION3;
	    use_tls = 1;
	    break;
#endif
	case 'd':
	    debug++;
	    break;
	default:
	    fprintf(stderr, PROGRAM_NAME ": ERROR: Unknown command line option '%c'\n", option);
	    exit(1);
	}
    }

    while (argc > 1) {
	char *value = argv[1];
	if (ldapServer) {
	    int len = strlen(ldapServer) + 1 + strlen(value) + 1;
	    char *newhost = malloc(len);
	    snprintf(newhost, len, "%s %s", ldapServer, value);
	    free(ldapServer);
	    ldapServer = newhost;
	} else {
	    ldapServer = strdup(value);
	}
	argc--;
	argv++;
    }
    if (!ldapServer)
	ldapServer = strdup("localhost");

    if (!basedn) {
	fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn [options] [ldap_server_name[:port]]...\n\n");
	fprintf(stderr, "\t-b basedn (REQUIRED)\tbase dn under which to search\n");
	fprintf(stderr, "\t-f filter\t\tsearch filter to locate user DN\n");
	fprintf(stderr, "\t-u userattr\t\tusername DN attribute\n");
	fprintf(stderr, "\t-s base|one|sub\t\tsearch scope\n");
	fprintf(stderr, "\t-D binddn\t\tDN to bind as to perform searches\n");
	fprintf(stderr, "\t-w bindpasswd\t\tpassword for binddn\n");
	fprintf(stderr, "\t-W secretfile\t\tread password for binddn from file secretfile\n");
#if HAS_URI_SUPPORT
	fprintf(stderr, "\t-H URI\t\t\tLDAPURI (defaults to ldap://localhost)\n");
#endif
	fprintf(stderr, "\t-h server\t\tLDAP server (defaults to localhost)\n");
	fprintf(stderr, "\t-p port\t\t\tLDAP server port\n");
	fprintf(stderr, "\t-P\t\t\tpersistent LDAP connection\n");
#if defined(NETSCAPE_SSL)
	fprintf(stderr, "\t-E sslcertpath\t\tenable LDAP over SSL\n");
#endif
	fprintf(stderr, "\t-c timeout\t\tconnect timeout\n");
	fprintf(stderr, "\t-t timelimit\t\tsearch time limit\n");
	fprintf(stderr, "\t-R\t\t\tdo not follow referrals\n");
	fprintf(stderr, "\t-a never|always|search|find\n\t\t\t\twhen to dereference aliases\n");
#ifdef LDAP_VERSION3
	fprintf(stderr, "\t-v 2|3\t\t\tLDAP version\n");
	fprintf(stderr, "\t-Z\t\t\tTLS encrypt the LDAP connection, requires LDAP version 3\n");
#endif
	fprintf(stderr, "\n");
	fprintf(stderr, "\tIf no search filter is specified, then the dn <userattr>=user,basedn\n\twill be used (same as specifying a search filter of '<userattr>=',\n\tbut quicker as as there is no need to search for the user DN)\n\n");
	fprintf(stderr, "\tIf you need to bind as a user to perform searches then use the\n\t-D binddn -w bindpasswd or -D binddn -W secretfile options\n\n");
	exit(1);
    }
/* On Windows ldap_start_tls_s is available starting from Windows XP, 
 * so we need to bind at run-time with the function entry point
 */
#ifdef _SQUID_MSWIN_
    if (use_tls) {

	HMODULE WLDAP32Handle;

	WLDAP32Handle = GetModuleHandle("wldap32");
	if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) {
	    fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n");
	    exit(1);
	}
    }
#endif

    while (fgets(buf, sizeof(buf), stdin) != NULL) {
	user = strtok(buf, " \r\n");
	passwd = strtok(NULL, "\r\n");

	if (!user || !passwd || !passwd[0]) {
	    printf("ERR\n");
	    continue;
	}
	rfc1738_unescape(user);
	rfc1738_unescape(passwd);
	if (!validUsername(user)) {
	    printf("ERR No such user\n");
	    continue;
	}
	tryagain = (ld != NULL);
      recover:
	if (ld == NULL && persistent)
	    ld = open_ldap_connection(ldapServer, port);
	if (checkLDAP(ld, user, passwd, ldapServer, port) != 0) {
	    if (tryagain && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS) {
		tryagain = 0;
		ldap_unbind(ld);
		ld = NULL;
		goto recover;
	    }
	    printf("ERR %s\n", ldap_err2string(squid_ldap_errno(ld)));
	} else {
	    printf("OK\n");
	}
	if (ld && (squid_ldap_errno(ld) != LDAP_SUCCESS && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS)) {
	    ldap_unbind(ld);
	    ld = NULL;
	}
    }
    if (ld)
	ldap_unbind(ld);
    return 0;
}
Beispiel #12
0
/*
 * Learn LDAP attributes and stuff them into the vCard.
 * Returns nonzero if we changed anything.
 */
int Ctdl_LDAP_to_vCard(char *ldap_dn, struct vCard *v)
{
	int changed_something = 0;
	LDAP *ldserver = NULL;
	int i;
	struct timeval tv;
	LDAPMessage *search_result = NULL;
	LDAPMessage *entry = NULL;
	char **givenName;
	char **sn;
	char **cn;
	char **initials;
	char **o;
	char **street;
	char **l;
	char **st;
	char **postalCode;
	char **telephoneNumber;
	char **mobile;
	char **homePhone;
	char **facsimileTelephoneNumber;
	char **mail;
	char **uid;
	char **homeDirectory;
	char **uidNumber;
	char **loginShell;
	char **gidNumber;
	char **c;
	char **title;
	char **uuid;
	char *attrs[] = { "*","+",NULL};

	if (!ldap_dn) return(0);
	if (!v) return(0);

	if (ctdl_ldap_initialize(&ldserver) != LDAP_SUCCESS) {
		return(0);
	}

	ldap_set_option(ldserver, LDAP_OPT_PROTOCOL_VERSION, &ctdl_require_ldap_version);
	ldap_set_option(ldserver, LDAP_OPT_REFERRALS, (void *)LDAP_OPT_OFF);

	striplt(CtdlGetConfigStr("c_ldap_bind_dn"));
	striplt(CtdlGetConfigStr("c_ldap_bind_pw"));
	syslog(LOG_DEBUG, "LDAP bind DN: %s", CtdlGetConfigStr("c_ldap_bind_dn"));
	i = ldap_simple_bind_s(ldserver,
		(!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_dn")) ? CtdlGetConfigStr("c_ldap_bind_dn") : NULL),
		(!IsEmptyStr(CtdlGetConfigStr("c_ldap_bind_pw")) ? CtdlGetConfigStr("c_ldap_bind_pw") : NULL)
	);
	if (i != LDAP_SUCCESS) {
		syslog(LOG_ALERT, "LDAP: Cannot bind: %s (%d)", ldap_err2string(i), i);
		return(0);
	}

	tv.tv_sec = 10;
	tv.tv_usec = 0;

	syslog(LOG_DEBUG, "LDAP search: %s", ldap_dn);
	(void) ldap_search_ext_s(
		ldserver,				/* ld				*/
		ldap_dn,				/* base				*/
		LDAP_SCOPE_SUBTREE,		/* scope			*/
		NULL,					/* filter			*/
		attrs,					/* attrs (all attributes)	*/
		0,						/* attrsonly (attrs + values)	*/
		NULL,					/* serverctrls (none)		*/
		NULL,					/* clientctrls (none)		*/
		&tv,					/* timeout			*/
		1,						/* sizelimit (1 result max)	*/
		&search_result			/* res				*/
	);
	
	/* Ignore the return value of ldap_search_ext_s().  Sometimes it returns an error even when
	 * the search succeeds.  Instead, we check to see whether search_result is still NULL.
	 */
	 
	if (search_result == NULL) {
		syslog(LOG_DEBUG, "LDAP search: zero results were returned");
		ldap_unbind(ldserver);
		return(0);
	}

	/* At this point we've got at least one result from our query.  If there are multiple
	 * results, we still only look at the first one.
	 */

	entry = ldap_first_entry(ldserver, search_result);
	if (entry) {
		syslog(LOG_DEBUG, "LDAP search, got user details for vcard.");
		givenName=ldap_get_values(ldserver, search_result, "givenName");
		sn=ldap_get_values(ldserver, search_result, "sn");
		cn=ldap_get_values(ldserver, search_result, "cn");
		initials=ldap_get_values(ldserver, search_result, "initials");
		title=ldap_get_values(ldserver, search_result, "title");
		o=ldap_get_values(ldserver, search_result, "o");
		street=ldap_get_values(ldserver, search_result, "street");
		l=ldap_get_values(ldserver, search_result, "l");
		st=ldap_get_values(ldserver, search_result, "st");
		postalCode=ldap_get_values(ldserver, search_result, "postalCode");
		telephoneNumber=ldap_get_values(ldserver, search_result, "telephoneNumber");
		mobile=ldap_get_values(ldserver, search_result, "mobile");
		homePhone=ldap_get_values(ldserver, search_result, "homePhone");
		facsimileTelephoneNumber=ldap_get_values(ldserver, search_result, "facsimileTelephoneNumber");
		mail=ldap_get_values(ldserver, search_result, "mail");
		uid=ldap_get_values(ldserver, search_result, "uid");
		homeDirectory=ldap_get_values(ldserver, search_result, "homeDirectory");
		uidNumber=ldap_get_values(ldserver, search_result, "uidNumber");
		loginShell=ldap_get_values(ldserver, search_result, "loginShell");
		gidNumber=ldap_get_values(ldserver, search_result, "gidNumber");
		c=ldap_get_values(ldserver, search_result, "c");
		uuid=ldap_get_values(ldserver, search_result, "entryUUID");

		if (street && l && st && postalCode && c) changed_something |= vcard_set_one_prop_iff_different(v,"adr",";;%s;%s;%s;%s;%s",street[0],l[0],st[0],postalCode[0],c[0]);
		if (telephoneNumber) changed_something |= vcard_set_one_prop_iff_different(v,"tel;work","%s",telephoneNumber[0]);
		if (facsimileTelephoneNumber) changed_something |= vcard_set_one_prop_iff_different(v,"tel;fax","%s",facsimileTelephoneNumber[0]);
		if (mobile) changed_something |= vcard_set_one_prop_iff_different(v,"tel;cell","%s",mobile[0]);
		if (homePhone) changed_something |= vcard_set_one_prop_iff_different(v,"tel;home","%s",homePhone[0]);
		if (givenName && sn) {
			if (initials) {
				changed_something |= vcard_set_one_prop_iff_different(v,"n","%s;%s;%s",sn[0],givenName[0],initials[0]);
			}
			else {
				changed_something |= vcard_set_one_prop_iff_different(v,"n","%s;%s",sn[0],givenName[0]);
			}
		}
		if (mail) {
			changed_something |= vcard_set_props_iff_different(v,"email;internet",ldap_count_values(mail),mail);
		}
		if (uuid) changed_something |= vcard_set_one_prop_iff_different(v,"X-uuid","%s",uuid[0]);
		if (o) changed_something |= vcard_set_one_prop_iff_different(v,"org","%s",o[0]);
		if (cn) changed_something |= vcard_set_one_prop_iff_different(v,"fn","%s",cn[0]);
		if (title) changed_something |= vcard_set_one_prop_iff_different(v,"title","%s",title[0]);
		
		if (givenName) ldap_value_free(givenName);
		if (initials) ldap_value_free(initials);
		if (sn) ldap_value_free(sn);
		if (cn) ldap_value_free(cn);
		if (o) ldap_value_free(o);
		if (street) ldap_value_free(street);
		if (l) ldap_value_free(l);
		if (st) ldap_value_free(st);
		if (postalCode) ldap_value_free(postalCode);
		if (telephoneNumber) ldap_value_free(telephoneNumber);
		if (mobile) ldap_value_free(mobile);
		if (homePhone) ldap_value_free(homePhone);
		if (facsimileTelephoneNumber) ldap_value_free(facsimileTelephoneNumber);
		if (mail) ldap_value_free(mail);
		if (uid) ldap_value_free(uid);
		if (homeDirectory) ldap_value_free(homeDirectory);
		if (uidNumber) ldap_value_free(uidNumber);
		if (loginShell) ldap_value_free(loginShell);
		if (gidNumber) ldap_value_free(gidNumber);
		if (c) ldap_value_free(c);
		if (title) ldap_value_free(title);
		if (uuid) ldap_value_free(uuid);
	}
	/* free the results */
	ldap_msgfree(search_result);

	/* unbind so we can go back in as the authenticating user */
	ldap_unbind(ldserver);
	
	return(changed_something);	/* tell the caller whether we made any changes */
}
Beispiel #13
0
int
main (int argc, char *argv[])
{

	LDAP *ld;
	LDAPMessage *result;

	/* should be 	int result = STATE_UNKNOWN; */

	int status = STATE_UNKNOWN;
	long microsec;
	double elapsed_time;

	/* for ldap tls */

	int tls;
	int version=3;

	setlocale (LC_ALL, "");
	bindtextdomain (PACKAGE, LOCALEDIR);
	textdomain (PACKAGE);

	if (strstr(argv[0],"check_ldaps")) {
		xasprintf (&progname, "check_ldaps");
 	}

	/* Parse extra opts if any */
	argv=np_extra_opts (&argc, argv, progname);

	if (process_arguments (argc, argv) == ERROR)
		usage4 (_("Could not parse arguments"));

	if (strstr(argv[0],"check_ldaps") && ! starttls && ! ssl_on_connect)
		starttls = TRUE;

	/* initialize alarm signal handling */
	signal (SIGALRM, socket_timeout_alarm_handler);

	/* set socket timeout */
	alarm (timeout_interval);

	/* get the start time */
	gettimeofday (&tv, NULL);

	/* initialize ldap */
	if (ld_uri != NULL)
	{
#ifdef HAVE_LDAP_INITIALIZE
		int result = ldap_initialize(&ld, ld_uri);
		if (result != LDAP_SUCCESS)
		{
			printf ("Failed to connect to LDAP server at %s: %s\n",
				ld_uri, ldap_err2string(result));
			return STATE_CRITICAL;
		}
#else
		printf ("Sorry, this version of %s was compiled without URI support!\n",
			argv[0]);
		return STATE_CRITICAL;
#endif
	}
#ifdef HAVE_LDAP_INIT
	else if (!(ld = ldap_init (ld_host, ld_port))) {
		printf ("Could not connect to the server at port %i\n", ld_port);
		return STATE_CRITICAL;
	}
#else
	else if (!(ld = ldap_open (ld_host, ld_port))) {
		if (verbose)
			ldap_perror(ld, "ldap_open");
		printf (_("Could not connect to the server at port %i\n"), ld_port);
		return STATE_CRITICAL;
	}
#endif /* HAVE_LDAP_INIT */

#ifdef HAVE_LDAP_SET_OPTION
	/* set ldap options */
	if (ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &ld_protocol) !=
			LDAP_OPT_SUCCESS ) {
		printf(_("Could not set protocol version %d\n"), ld_protocol);
		return STATE_CRITICAL;
	}
#endif

	if (ld_port == LDAPS_PORT || ssl_on_connect) {
		xasprintf (&SERVICE, "LDAPS");
#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)
		/* ldaps: set option tls */
		tls = LDAP_OPT_X_TLS_HARD;

		if (ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
		{
			if (verbose)
				ldap_perror(ld, "ldaps_option");
			printf (_("Could not init TLS at port %i!\n"), ld_port);
			return STATE_CRITICAL;
		}
#else
		printf (_("TLS not supported by the libraries!\n"));
		return STATE_CRITICAL;
#endif /* LDAP_OPT_X_TLS */
	} else if (starttls) {
		xasprintf (&SERVICE, "LDAP-TLS");
#if defined(HAVE_LDAP_SET_OPTION) && defined(HAVE_LDAP_START_TLS_S)
		/* ldap with startTLS: set option version */
		if (ldap_get_option(ld,LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS )
		{
			if (version < LDAP_VERSION3)
			{
				version = LDAP_VERSION3;
				ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version);
			}
		}
		/* call start_tls */
		if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS)
		{
			if (verbose)
				ldap_perror(ld, "ldap_start_tls");
			printf (_("Could not init startTLS at port %i!\n"), ld_port);
			return STATE_CRITICAL;
		}
#else
		printf (_("startTLS not supported by the library, needs LDAPv3!\n"));
		return STATE_CRITICAL;
#endif /* HAVE_LDAP_START_TLS_S */
	}

	/* bind to the ldap server */
	if (ldap_bind_s (ld, ld_binddn, ld_passwd, LDAP_AUTH_SIMPLE) !=
			LDAP_SUCCESS) {
		if (verbose)
			ldap_perror(ld, "ldap_bind");
		printf (_("Could not bind to the LDAP server\n"));
		return STATE_CRITICAL;
	}

	/* do a search of all objectclasses in the base dn */
	if (ldap_search_s (ld, ld_base, LDAP_SCOPE_BASE, ld_attr, NULL, 0, &result)
			!= LDAP_SUCCESS) {
		if (verbose)
			ldap_perror(ld, "ldap_search");
		printf (_("Could not search/find objectclasses in %s\n"), ld_base);
		return STATE_CRITICAL;
	}

	/* unbind from the ldap server */
	ldap_unbind (ld);

	/* reset the alarm handler */
	alarm (0);

	/* calcutate the elapsed time and compare to thresholds */

	microsec = deltime (tv);
	elapsed_time = (double)microsec / 1.0e6;

	if (crit_time!=UNDEFINED && elapsed_time>crit_time)
		status = STATE_CRITICAL;
	else if (warn_time!=UNDEFINED && elapsed_time>warn_time)
		status = STATE_WARNING;
	else
		status = STATE_OK;

	/* print out the result */
	printf (_("LDAP %s - %.3f seconds response time|%s\n"),
	        state_text (status),
	        elapsed_time,
	        fperfdata ("time", elapsed_time, "s",
	                  (int)warn_time, warn_time,
	                  (int)crit_time, crit_time,
	                  TRUE, 0, FALSE, 0));

	return status;
}
Beispiel #14
0
int
slapauth( int argc, char **argv )
{
	int			rc = EXIT_SUCCESS;
	const char		*progname = "slapauth";
	Connection		conn = {0};
	OperationBuffer	opbuf;
	Operation		*op;
	void			*thrctx;

	slap_tool_init( progname, SLAPAUTH, argc, argv );

	argv = &argv[ optind ];
	argc -= optind;

	thrctx = ldap_pvt_thread_pool_context();
	connection_fake_init( &conn, &opbuf, thrctx );
	op = &opbuf.ob_op;

	conn.c_sasl_bind_mech = mech;

	if ( !BER_BVISNULL( &authzID ) ) {
		struct berval	authzdn;
		
		rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn,
				SLAP_GETDN_AUTHZID );
		if ( rc != LDAP_SUCCESS ) {
			fprintf( stderr, "authzID: <%s> check failed %d (%s)\n",
					authzID.bv_val, rc,
					ldap_err2string( rc ) );
			rc = 1;
			BER_BVZERO( &authzID );
			goto destroy;
		} 

		authzID = authzdn;
	}


	if ( !BER_BVISNULL( &authcID ) ) {
		if ( !BER_BVISNULL( &authzID ) || argc == 0 ) {
			rc = do_check( &conn, op, &authcID );
			goto destroy;
		}

		for ( ; argc--; argv++ ) {
			struct berval	authzdn;
		
			ber_str2bv( argv[ 0 ], 0, 0, &authzID );

			rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn,
					SLAP_GETDN_AUTHZID );
			if ( rc != LDAP_SUCCESS ) {
				fprintf( stderr, "authzID: <%s> check failed %d (%s)\n",
						authzID.bv_val, rc,
						ldap_err2string( rc ) );
				rc = -1;
				BER_BVZERO( &authzID );
				if ( !continuemode ) {
					goto destroy;
				}
			}

			authzID = authzdn;

			rc = do_check( &conn, op, &authcID );

			op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx );
			BER_BVZERO( &authzID );

			if ( rc && !continuemode ) {
				goto destroy;
			}
		}

		goto destroy;
	}

	for ( ; argc--; argv++ ) {
		struct berval	id;

		ber_str2bv( argv[ 0 ], 0, 0, &id );

		rc = do_check( &conn, op, &id );

		if ( rc && !continuemode ) {
			goto destroy;
		}
	}

destroy:;
	if ( !BER_BVISNULL( &authzID ) ) {
		op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx );
	}
	if ( slap_tool_destroy())
		rc = EXIT_FAILURE;

	return rc;
}
Beispiel #15
0
int main()
{
   LDAP *ld;			/* LDAP resource handle */
   LDAPMessage *result, *e;	/* LDAP result handle */
   BerElement *ber;		/* array of attributes */
   char *attribute;
   char **vals;

   int i,rc=0;

   char *attribs[3];		/* attribute array for search */

   attribs[0]=strdup("uid");		/* return uid and cn of entries */
   attribs[1]=strdup("cn");
   attribs[2]=NULL;		/* array must be NULL terminated */


   /* setup LDAP connection */
   if ((ld=ldap_init(LDAP_HOST, LDAP_PORT)) == NULL)
   {
      perror("ldap_init failed");
      return EXIT_FAILURE;
   }

   printf("connected to LDAP server %s on port %d\n",LDAP_HOST,LDAP_PORT);

   /* anonymous bind */
   rc = ldap_simple_bind_s(ld,BIND_USER,BIND_PW);

   if (rc != LDAP_SUCCESS)
   {
      fprintf(stderr,"LDAP error: %s\n",ldap_err2string(rc));
      return EXIT_FAILURE;
   }
   else
   {
      printf("bind successful\n");
   }

   /* perform ldap search */
   rc = ldap_search_s(ld, SEARCHBASE, SCOPE, FILTER, attribs, 0, &result);

   if (rc != LDAP_SUCCESS)
   {
      fprintf(stderr,"LDAP search error: %s\n",ldap_err2string(rc));
      return EXIT_FAILURE;
   }

   printf("Total results: %d\n", ldap_count_entries(ld, result));

   for (e = ldap_first_entry(ld, result); e != NULL; e = ldap_next_entry(ld,e))
   {
      printf("DN: %s\n", ldap_get_dn(ld,e));
	  
	  // ab hier kann abgebrochen werden für unser ftp-server
      
      /* Now print the attributes and values of each found entry */

      for (attribute = ldap_first_attribute(ld,e,&ber); attribute!=NULL; attribute = ldap_next_attribute(ld,e,ber))
      {
         if ((vals=ldap_get_values(ld,e,attribute)) != NULL)
         {
            for (i=0;vals[i]!=NULL;i++)
            {
               printf("\t%s: %s\n",attribute,vals[i]);
            }
            /* free memory used to store the values of the attribute */
            ldap_value_free(vals);
         }
         /* free memory used to store the attribute */
         ldap_memfree(attribute);
      }
      /* free memory used to store the value structure */
      if (ber != NULL) ber_free(ber,0);

      printf("\n");
   }
  
   /* free memory used for result */
   ldap_msgfree(result);
   free(attribs[0]);
   free(attribs[1]);
   printf("LDAP search suceeded\n");
   
   ldap_unbind(ld);
   return EXIT_SUCCESS;
}
Beispiel #16
0
krb5_error_code
krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry,
                        char **db_args)
{
    int                         l=0, kerberos_principal_object_type=0;
    krb5_error_code             st=0, tempst=0;
    LDAP                        *ld=NULL;
    LDAPMessage                 *result=NULL, *ent=NULL;
    char                        *user=NULL, *subtree=NULL, *principal_dn=NULL;
    char                        **values=NULL, *strval[10]={NULL}, errbuf[1024];
    char                        *filtuser=NULL;
    struct berval               **bersecretkey=NULL;
    LDAPMod                     **mods=NULL;
    krb5_boolean                create_standalone_prinicipal=FALSE;
    krb5_boolean                krb_identity_exists=FALSE, establish_links=FALSE;
    char                        *standalone_principal_dn=NULL;
    krb5_tl_data                *tl_data=NULL;
    krb5_key_data               **keys=NULL;
    kdb5_dal_handle             *dal_handle=NULL;
    krb5_ldap_context           *ldap_context=NULL;
    krb5_ldap_server_handle     *ldap_server_handle=NULL;
    osa_princ_ent_rec           princ_ent;
    xargs_t                     xargs = {0};
    char                        *polname = NULL;
    OPERATION optype;
    krb5_boolean                found_entry = FALSE;

    /* Clear the global error string */
    krb5_clear_error_message(context);

    SETUP_CONTEXT();
    if (ldap_context->lrparams == NULL || ldap_context->container_dn == NULL)
        return EINVAL;

    /* get ldap handle */
    GET_HANDLE();

    if (is_principal_in_realm(ldap_context, entry->princ) != 0) {
        st = EINVAL;
        krb5_set_error_message(context, st, _("Principal does not belong to "
                                              "the default realm"));
        goto cleanup;
    }

    /* get the principal information to act on */
    if (((st=krb5_unparse_name(context, entry->princ, &user)) != 0) ||
        ((st=krb5_ldap_unparse_principal_name(user)) != 0))
        goto cleanup;
    filtuser = ldap_filter_correct(user);
    if (filtuser == NULL) {
        st = ENOMEM;
        goto cleanup;
    }

    /* Identity the type of operation, it can be
     * add principal or modify principal.
     * hack if the entry->mask has KRB_PRINCIPAL flag set
     * then it is a add operation
     */
    if (entry->mask & KADM5_PRINCIPAL)
        optype = ADD_PRINCIPAL;
    else
        optype = MODIFY_PRINCIPAL;

    if (((st=krb5_get_princ_type(context, entry, &kerberos_principal_object_type)) != 0) ||
        ((st=krb5_get_userdn(context, entry, &principal_dn)) != 0))
        goto cleanup;

    if ((st=process_db_args(context, db_args, &xargs, optype)) != 0)
        goto cleanup;

    if (entry->mask & KADM5_LOAD) {
        unsigned int     tree = 0, ntrees = 0;
        int              numlentries = 0;
        char             **subtreelist = NULL, *filter = NULL;

        /*  A load operation is special, will do a mix-in (add krbprinc
         *  attrs to a non-krb object entry) if an object exists with a
         *  matching krbprincipalname attribute so try to find existing
         *  object and set principal_dn.  This assumes that the
         *  krbprincipalname attribute is unique (only one object entry has
         *  a particular krbprincipalname attribute).
         */
        if (asprintf(&filter, FILTER"%s))", filtuser) < 0) {
            filter = NULL;
            st = ENOMEM;
            goto cleanup;
        }

        /* get the current subtree list */
        if ((st = krb5_get_subtree_info(ldap_context, &subtreelist, &ntrees)) != 0)
            goto cleanup;

        found_entry = FALSE;
        /* search for entry with matching krbprincipalname attribute */
        for (tree = 0; found_entry == FALSE && tree < ntrees; ++tree) {
            result = NULL;
            if (principal_dn == NULL) {
                LDAP_SEARCH_1(subtreelist[tree], ldap_context->lrparams->search_scope, filter, principal_attributes, IGNORE_STATUS);
            } else {
                /* just look for entry with principal_dn */
                LDAP_SEARCH_1(principal_dn, LDAP_SCOPE_BASE, filter, principal_attributes, IGNORE_STATUS);
            }
            if (st == LDAP_SUCCESS) {
                numlentries = ldap_count_entries(ld, result);
                if (numlentries > 1) {
                    ldap_msgfree(result);
                    free(filter);
                    st = EINVAL;
                    krb5_set_error_message(context, st,
                                           _("operation can not continue, "
                                             "more than one entry with "
                                             "principal name \"%s\" found"),
                                           user);
                    goto cleanup;
                } else if (numlentries == 1) {
                    found_entry = TRUE;
                    if (principal_dn == NULL) {
                        ent = ldap_first_entry(ld, result);
                        if (ent != NULL) {
                            /* setting principal_dn will cause that entry to be modified further down */
                            if ((principal_dn = ldap_get_dn(ld, ent)) == NULL) {
                                ldap_get_option (ld, LDAP_OPT_RESULT_CODE, &st);
                                st = set_ldap_error (context, st, 0);
                                ldap_msgfree(result);
                                free(filter);
                                goto cleanup;
                            }
                        }
                    }
                }
                if (result)
                    ldap_msgfree(result);
            } else if (st != LDAP_NO_SUCH_OBJECT) {
                /* could not perform search, return with failure */
                st = set_ldap_error (context, st, 0);
                free(filter);
                goto cleanup;
            }
            /*
             * If it isn't found then assume a standalone princ entry is to
             * be created.
             */
        } /* end for (tree = 0; principal_dn == ... */

        free(filter);

        if (found_entry == FALSE && principal_dn != NULL) {
            /*
             * if principal_dn is null then there is code further down to
             * deal with setting standalone_principal_dn.  Also note that
             * this will set create_standalone_prinicipal true for
             * non-mix-in entries which is okay if loading from a dump.
             */
            create_standalone_prinicipal = TRUE;
            standalone_principal_dn = strdup(principal_dn);
            CHECK_NULL(standalone_principal_dn);
        }
    } /* end if (entry->mask & KADM5_LOAD */

    /* time to generate the DN information with the help of
     * containerdn, principalcontainerreference or
     * realmcontainerdn information
     */
    if (principal_dn == NULL && xargs.dn == NULL) { /* creation of standalone principal */
        /* get the subtree information */
        if (entry->princ->length == 2 && entry->princ->data[0].length == strlen("krbtgt") &&
            strncmp(entry->princ->data[0].data, "krbtgt", entry->princ->data[0].length) == 0) {
            /* if the principal is a inter-realm principal, always created in the realm container */
            subtree = strdup(ldap_context->lrparams->realmdn);
        } else if (xargs.containerdn) {
            if ((st=checkattributevalue(ld, xargs.containerdn, NULL, NULL, NULL)) != 0) {
                if (st == KRB5_KDB_NOENTRY || st == KRB5_KDB_CONSTRAINT_VIOLATION) {
                    int ost = st;
                    st = EINVAL;
                    snprintf(errbuf, sizeof(errbuf), _("'%s' not found: "),
                             xargs.containerdn);
                    prepend_err_str(context, errbuf, st, ost);
                }
                goto cleanup;
            }
            subtree = strdup(xargs.containerdn);
        } else if (ldap_context->lrparams->containerref && strlen(ldap_context->lrparams->containerref) != 0) {
            /*
             * Here the subtree should be changed with
             * principalcontainerreference attribute value
             */
            subtree = strdup(ldap_context->lrparams->containerref);
        } else {
            subtree = strdup(ldap_context->lrparams->realmdn);
        }
        CHECK_NULL(subtree);

        if (asprintf(&standalone_principal_dn, "krbprincipalname=%s,%s",
                     filtuser, subtree) < 0)
            standalone_principal_dn = NULL;
        CHECK_NULL(standalone_principal_dn);
        /*
         * free subtree when you are done using the subtree
         * set the boolean create_standalone_prinicipal to TRUE
         */
        create_standalone_prinicipal = TRUE;
        free(subtree);
        subtree = NULL;
    }

    /*
     * If the DN information is presented by the user, time to
     * validate the input to ensure that the DN falls under
     * any of the subtrees
     */
    if (xargs.dn_from_kbd == TRUE) {
        /* make sure the DN falls in the subtree */
        unsigned int     tre=0, ntrees=0;
        int              dnlen=0, subtreelen=0;
        char             **subtreelist=NULL;
        char             *dn=NULL;
        krb5_boolean     outofsubtree=TRUE;

        if (xargs.dn != NULL) {
            dn = xargs.dn;
        } else if (xargs.linkdn != NULL) {
            dn = xargs.linkdn;
        } else if (standalone_principal_dn != NULL) {
            /*
             * Even though the standalone_principal_dn is constructed
             * within this function, there is the containerdn input
             * from the user that can become part of the it.
             */
            dn = standalone_principal_dn;
        }

        /* get the current subtree list */
        if ((st = krb5_get_subtree_info(ldap_context, &subtreelist, &ntrees)) != 0)
            goto cleanup;

        for (tre=0; tre<ntrees; ++tre) {
            if (subtreelist[tre] == NULL || strlen(subtreelist[tre]) == 0) {
                outofsubtree = FALSE;
                break;
            } else {
                dnlen = strlen (dn);
                subtreelen = strlen(subtreelist[tre]);
                if ((dnlen >= subtreelen) && (strcasecmp((dn + dnlen - subtreelen), subtreelist[tre]) == 0)) {
                    outofsubtree = FALSE;
                    break;
                }
            }
        }

        for (tre=0; tre < ntrees; ++tre) {
            free(subtreelist[tre]);
        }

        if (outofsubtree == TRUE) {
            st = EINVAL;
            krb5_set_error_message(context, st,
                                   _("DN is out of the realm subtree"));
            goto cleanup;
        }

        /*
         * dn value will be set either by dn, linkdn or the standalone_principal_dn
         * In the first 2 cases, the dn should be existing and in the last case we
         * are supposed to create the ldap object. so the below should not be
         * executed for the last case.
         */

        if (standalone_principal_dn == NULL) {
            /*
             * If the ldap object is missing, this results in an error.
             */

            /*
             * Search for krbprincipalname attribute here.
             * This is to find if a kerberos identity is already present
             * on the ldap object, in which case adding a kerberos identity
             * on the ldap object should result in an error.
             */
            char  *attributes[]={"krbticketpolicyreference", "krbprincipalname", NULL};

            LDAP_SEARCH_1(dn, LDAP_SCOPE_BASE, 0, attributes, IGNORE_STATUS);
            if (st == LDAP_SUCCESS) {
                ent = ldap_first_entry(ld, result);
                if (ent != NULL) {
                    if ((values=ldap_get_values(ld, ent, "krbticketpolicyreference")) != NULL) {
                        ldap_value_free(values);
                    }

                    if ((values=ldap_get_values(ld, ent, "krbprincipalname")) != NULL) {
                        krb_identity_exists = TRUE;
                        ldap_value_free(values);
                    }
                }
                ldap_msgfree(result);
            } else {
                st = set_ldap_error(context, st, OP_SEARCH);
                goto cleanup;
            }
        }
    }

    /*
     * If xargs.dn is set then the request is to add a
     * kerberos principal on a ldap object, but if
     * there is one already on the ldap object this
     * should result in an error.
     */

    if (xargs.dn != NULL && krb_identity_exists == TRUE) {
        st = EINVAL;
        snprintf(errbuf, sizeof(errbuf),
                 _("ldap object is already kerberized"));
        krb5_set_error_message(context, st, "%s", errbuf);
        goto cleanup;
    }

    if (xargs.linkdn != NULL) {
        /*
         * link information can be changed using modprinc.
         * However, link information can be changed only on the
         * standalone kerberos principal objects. A standalone
         * kerberos principal object is of type krbprincipal
         * structural objectclass.
         *
         * NOTE: kerberos principals on an ldap object can't be
         * linked to other ldap objects.
         */
        if (optype == MODIFY_PRINCIPAL &&
            kerberos_principal_object_type != KDB_STANDALONE_PRINCIPAL_OBJECT) {
            st = EINVAL;
            snprintf(errbuf, sizeof(errbuf),
                     _("link information can not be set/updated as the "
                       "kerberos principal belongs to an ldap object"));
            krb5_set_error_message(context, st, "%s", errbuf);
            goto cleanup;
        }
        /*
         * Check the link information. If there is already a link
         * existing then this operation is not allowed.
         */
        {
            char **linkdns=NULL;
            int  j=0;

            if ((st=krb5_get_linkdn(context, entry, &linkdns)) != 0) {
                snprintf(errbuf, sizeof(errbuf),
                         _("Failed getting object references"));
                krb5_set_error_message(context, st, "%s", errbuf);
                goto cleanup;
            }
            if (linkdns != NULL) {
                st = EINVAL;
                snprintf(errbuf, sizeof(errbuf),
                         _("kerberos principal is already linked to a ldap "
                           "object"));
                krb5_set_error_message(context, st, "%s", errbuf);
                for (j=0; linkdns[j] != NULL; ++j)
                    free (linkdns[j]);
                free (linkdns);
                goto cleanup;
            }
        }

        establish_links = TRUE;
    }

    if (entry->mask & KADM5_LAST_SUCCESS) {
        memset(strval, 0, sizeof(strval));
        if ((strval[0]=getstringtime(entry->last_success)) == NULL)
            goto cleanup;
        if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbLastSuccessfulAuth", LDAP_MOD_REPLACE, strval)) != 0) {
            free (strval[0]);
            goto cleanup;
        }
        free (strval[0]);
    }

    if (entry->mask & KADM5_LAST_FAILED) {
        memset(strval, 0, sizeof(strval));
        if ((strval[0]=getstringtime(entry->last_failed)) == NULL)
            goto cleanup;
        if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbLastFailedAuth", LDAP_MOD_REPLACE, strval)) != 0) {
            free (strval[0]);
            goto cleanup;
        }
        free(strval[0]);
    }

    if (entry->mask & KADM5_FAIL_AUTH_COUNT) {
        krb5_kvno fail_auth_count;

        fail_auth_count = entry->fail_auth_count;
        if (entry->mask & KADM5_FAIL_AUTH_COUNT_INCREMENT)
            fail_auth_count++;

        st = krb5_add_int_mem_ldap_mod(&mods, "krbLoginFailedCount",
                                       LDAP_MOD_REPLACE,
                                       fail_auth_count);
        if (st != 0)
            goto cleanup;
    } else if (entry->mask & KADM5_FAIL_AUTH_COUNT_INCREMENT) {
        int attr_mask = 0;
        krb5_boolean has_fail_count;

        /* Check if the krbLoginFailedCount attribute exists.  (Through
         * krb5 1.8.1, it wasn't set in new entries.) */
        st = krb5_get_attributes_mask(context, entry, &attr_mask);
        if (st != 0)
            goto cleanup;
        has_fail_count = ((attr_mask & KDB_FAIL_AUTH_COUNT_ATTR) != 0);

        /*
         * If the client library and server supports RFC 4525,
         * then use it to increment by one the value of the
         * krbLoginFailedCount attribute. Otherwise, assert the
         * (provided) old value by deleting it before adding.
         */
#ifdef LDAP_MOD_INCREMENT
        if (ldap_server_handle->server_info->modify_increment &&
            has_fail_count) {
            st = krb5_add_int_mem_ldap_mod(&mods, "krbLoginFailedCount",
                                           LDAP_MOD_INCREMENT, 1);
            if (st != 0)
                goto cleanup;
        } else {
#endif /* LDAP_MOD_INCREMENT */
            if (has_fail_count) {
                st = krb5_add_int_mem_ldap_mod(&mods,
                                               "krbLoginFailedCount",
                                               LDAP_MOD_DELETE,
                                               entry->fail_auth_count);
                if (st != 0)
                    goto cleanup;
            }
            st = krb5_add_int_mem_ldap_mod(&mods, "krbLoginFailedCount",
                                           LDAP_MOD_ADD,
                                           entry->fail_auth_count + 1);
            if (st != 0)
                goto cleanup;
#ifdef LDAP_MOD_INCREMENT
        }
#endif
    } else if (optype == ADD_PRINCIPAL) {
        /* Initialize krbLoginFailedCount in new entries to help avoid a
         * race during the first failed login. */
        st = krb5_add_int_mem_ldap_mod(&mods, "krbLoginFailedCount",
                                       LDAP_MOD_ADD, 0);
    }

    if (entry->mask & KADM5_MAX_LIFE) {
        if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxticketlife", LDAP_MOD_REPLACE, entry->max_life)) != 0)
            goto cleanup;
    }

    if (entry->mask & KADM5_MAX_RLIFE) {
        if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbmaxrenewableage", LDAP_MOD_REPLACE,
                                          entry->max_renewable_life)) != 0)
            goto cleanup;
    }

    if (entry->mask & KADM5_ATTRIBUTES) {
        if ((st=krb5_add_int_mem_ldap_mod(&mods, "krbticketflags", LDAP_MOD_REPLACE,
                                          entry->attributes)) != 0)
            goto cleanup;
    }

    if (entry->mask & KADM5_PRINCIPAL) {
        memset(strval, 0, sizeof(strval));
        strval[0] = user;
        if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbprincipalname", LDAP_MOD_REPLACE, strval)) != 0)
            goto cleanup;
    }

    if (entry->mask & KADM5_PRINC_EXPIRE_TIME) {
        memset(strval, 0, sizeof(strval));
        if ((strval[0]=getstringtime(entry->expiration)) == NULL)
            goto cleanup;
        if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbprincipalexpiration", LDAP_MOD_REPLACE, strval)) != 0) {
            free (strval[0]);
            goto cleanup;
        }
        free (strval[0]);
    }

    if (entry->mask & KADM5_PW_EXPIRATION) {
        memset(strval, 0, sizeof(strval));
        if ((strval[0]=getstringtime(entry->pw_expiration)) == NULL)
            goto cleanup;
        if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpasswordexpiration",
                                          LDAP_MOD_REPLACE,
                                          strval)) != 0) {
            free (strval[0]);
            goto cleanup;
        }
        free (strval[0]);
    }

    if (entry->mask & KADM5_POLICY) {
        memset(&princ_ent, 0, sizeof(princ_ent));
        for (tl_data=entry->tl_data; tl_data; tl_data=tl_data->tl_data_next) {
            if (tl_data->tl_data_type == KRB5_TL_KADM_DATA) {
                /* FIX ME: I guess the princ_ent should be freed after this call */
                if ((st = krb5_lookup_tl_kadm_data(tl_data, &princ_ent)) != 0) {
                    goto cleanup;
                }
            }
        }

        if (princ_ent.aux_attributes & KADM5_POLICY) {
            memset(strval, 0, sizeof(strval));
            if ((st = krb5_ldap_name_to_policydn (context, princ_ent.policy, &polname)) != 0)
                goto cleanup;
            strval[0] = polname;
            if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpwdpolicyreference", LDAP_MOD_REPLACE, strval)) != 0)
                goto cleanup;
        } else {
            st = EINVAL;
            krb5_set_error_message(context, st, "Password policy value null");
            goto cleanup;
        }
    } else if (entry->mask & KADM5_LOAD && found_entry == TRUE) {
        /*
         * a load is special in that existing entries must have attrs that
         * removed.
         */

        if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpwdpolicyreference", LDAP_MOD_REPLACE, NULL)) != 0)
            goto cleanup;
    }

    if (entry->mask & KADM5_POLICY_CLR) {
        if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbpwdpolicyreference", LDAP_MOD_DELETE, NULL)) != 0)
            goto cleanup;
    }

    if (entry->mask & KADM5_KEY_DATA || entry->mask & KADM5_KVNO) {
        krb5_kvno mkvno;

        if ((st=krb5_dbe_lookup_mkvno(context, entry, &mkvno)) != 0)
            goto cleanup;
        bersecretkey = krb5_encode_krbsecretkey (entry->key_data,
                                                 entry->n_key_data, mkvno);

        if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey",
                                          LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, bersecretkey)) != 0)
            goto cleanup;

        if (!(entry->mask & KADM5_PRINCIPAL)) {
            memset(strval, 0, sizeof(strval));
            if ((strval[0]=getstringtime(entry->pw_expiration)) == NULL)
                goto cleanup;
            if ((st=krb5_add_str_mem_ldap_mod(&mods,
                                              "krbpasswordexpiration",
                                              LDAP_MOD_REPLACE, strval)) != 0) {
                free (strval[0]);
                goto cleanup;
            }
            free (strval[0]);
        }

        /* Update last password change whenever a new key is set */
        {
            krb5_timestamp last_pw_changed;
            if ((st=krb5_dbe_lookup_last_pwd_change(context, entry,
                                                    &last_pw_changed)) != 0)
                goto cleanup;

            memset(strval, 0, sizeof(strval));
            if ((strval[0] = getstringtime(last_pw_changed)) == NULL)
                goto cleanup;

            if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbLastPwdChange",
                                              LDAP_MOD_REPLACE, strval)) != 0) {
                free (strval[0]);
                goto cleanup;
            }
            free (strval[0]);
        }

    } /* Modify Key data ends here */

    /* Set tl_data */
    if (entry->tl_data != NULL) {
        int count = 0;
        struct berval **ber_tl_data = NULL;
        krb5_tl_data *ptr;
        krb5_timestamp unlock_time;
        for (ptr = entry->tl_data; ptr != NULL; ptr = ptr->tl_data_next) {
            if (ptr->tl_data_type == KRB5_TL_LAST_PWD_CHANGE
#ifdef SECURID
                || ptr->tl_data_type == KRB5_TL_DB_ARGS
#endif
                || ptr->tl_data_type == KRB5_TL_KADM_DATA
                || ptr->tl_data_type == KDB_TL_USER_INFO
                || ptr->tl_data_type == KRB5_TL_CONSTRAINED_DELEGATION_ACL
                || ptr->tl_data_type == KRB5_TL_LAST_ADMIN_UNLOCK)
                continue;
            count++;
        }
        if (count != 0) {
            int j;
            ber_tl_data = (struct berval **) calloc (count + 1,
                                                     sizeof (struct berval*));
            if (ber_tl_data == NULL) {
                st = ENOMEM;
                goto cleanup;
            }
            for (j = 0, ptr = entry->tl_data; ptr != NULL; ptr = ptr->tl_data_next) {
                /* Ignore tl_data that are stored in separate directory
                 * attributes */
                if (ptr->tl_data_type == KRB5_TL_LAST_PWD_CHANGE
#ifdef SECURID
                    || ptr->tl_data_type == KRB5_TL_DB_ARGS
#endif
                    || ptr->tl_data_type == KRB5_TL_KADM_DATA
                    || ptr->tl_data_type == KDB_TL_USER_INFO
                    || ptr->tl_data_type == KRB5_TL_CONSTRAINED_DELEGATION_ACL
                    || ptr->tl_data_type == KRB5_TL_LAST_ADMIN_UNLOCK)
                    continue;
                if ((st = tl_data2berval (ptr, &ber_tl_data[j])) != 0)
                    break;
                j++;
            }
            if (st == 0) {
                ber_tl_data[count] = NULL;
                st=krb5_add_ber_mem_ldap_mod(&mods, "krbExtraData",
                                             LDAP_MOD_REPLACE |
                                             LDAP_MOD_BVALUES, ber_tl_data);
            }
            for (j = 0; ber_tl_data[j] != NULL; j++) {
                free(ber_tl_data[j]->bv_val);
                free(ber_tl_data[j]);
            }
            free(ber_tl_data);
            if (st != 0)
                goto cleanup;
        }
        if ((st=krb5_dbe_lookup_last_admin_unlock(context, entry,
                                                  &unlock_time)) != 0)
            goto cleanup;
        if (unlock_time != 0) {
            /* Update last admin unlock */
            memset(strval, 0, sizeof(strval));
            if ((strval[0] = getstringtime(unlock_time)) == NULL)
                goto cleanup;

            if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbLastAdminUnlock",
                                              LDAP_MOD_REPLACE, strval)) != 0) {
                free (strval[0]);
                goto cleanup;
            }
            free (strval[0]);
        }
    }

    /* Directory specific attribute */
    if (xargs.tktpolicydn != NULL) {
        int tmask=0;

        if (strlen(xargs.tktpolicydn) != 0) {
            st = checkattributevalue(ld, xargs.tktpolicydn, "objectclass", policyclass, &tmask);
            CHECK_CLASS_VALIDITY(st, tmask, _("ticket policy object value: "));

            strval[0] = xargs.tktpolicydn;
            strval[1] = NULL;
            if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbticketpolicyreference", LDAP_MOD_REPLACE, strval)) != 0)
                goto cleanup;

        } else {
            /* if xargs.tktpolicydn is a empty string, then delete
             * already existing krbticketpolicyreference attr */
            if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbticketpolicyreference", LDAP_MOD_DELETE, NULL)) != 0)
                goto cleanup;
        }

    }

    if (establish_links == TRUE) {
        memset(strval, 0, sizeof(strval));
        strval[0] = xargs.linkdn;
        if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbObjectReferences", LDAP_MOD_REPLACE, strval)) != 0)
            goto cleanup;
    }

    /*
     * in case mods is NULL then return
     * not sure but can happen in a modprinc
     * so no need to return an error
     * addprinc will at least have the principal name
     * and the keys passed in
     */
    if (mods == NULL)
        goto cleanup;

    if (create_standalone_prinicipal == TRUE) {
        memset(strval, 0, sizeof(strval));
        strval[0] = "krbprincipal";
        strval[1] = "krbprincipalaux";
        strval[2] = "krbTicketPolicyAux";

        if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
            goto cleanup;

        st = ldap_add_ext_s(ld, standalone_principal_dn, mods, NULL, NULL);
        if (st == LDAP_ALREADY_EXISTS && entry->mask & KADM5_LOAD) {
            /* a load operation must replace an existing entry */
            st = ldap_delete_ext_s(ld, standalone_principal_dn, NULL, NULL);
            if (st != LDAP_SUCCESS) {
                snprintf(errbuf, sizeof(errbuf),
                         _("Principal delete failed (trying to replace "
                           "entry): %s"), ldap_err2string(st));
                st = translate_ldap_error (st, OP_ADD);
                krb5_set_error_message(context, st, "%s", errbuf);
                goto cleanup;
            } else {
                st = ldap_add_ext_s(ld, standalone_principal_dn, mods, NULL, NULL);
            }
        }
        if (st != LDAP_SUCCESS) {
            snprintf(errbuf, sizeof(errbuf), _("Principal add failed: %s"),
                     ldap_err2string(st));
            st = translate_ldap_error (st, OP_ADD);
            krb5_set_error_message(context, st, "%s", errbuf);
            goto cleanup;
        }
    } else {
        /*
         * Here existing ldap object is modified and can be related
         * to any attribute, so always ensure that the ldap
         * object is extended with all the kerberos related
         * objectclasses so that there are no constraint
         * violations.
         */
        {
            char *attrvalues[] = {"krbprincipalaux", "krbTicketPolicyAux", NULL};
            int p, q, r=0, amask=0;

            if ((st=checkattributevalue(ld, (xargs.dn) ? xargs.dn : principal_dn,
                                        "objectclass", attrvalues, &amask)) != 0)
                goto cleanup;

            memset(strval, 0, sizeof(strval));
            for (p=1, q=0; p<=2; p<<=1, ++q) {
                if ((p & amask) == 0)
                    strval[r++] = attrvalues[q];
            }
            if (r != 0) {
                if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_ADD, strval)) != 0)
                    goto cleanup;
            }
        }
        if (xargs.dn != NULL)
            st=ldap_modify_ext_s(ld, xargs.dn, mods, NULL, NULL);
        else
            st = ldap_modify_ext_s(ld, principal_dn, mods, NULL, NULL);

        if (st != LDAP_SUCCESS) {
            snprintf(errbuf, sizeof(errbuf), _("User modification failed: %s"),
                     ldap_err2string(st));
            st = translate_ldap_error (st, OP_MOD);
            krb5_set_error_message(context, st, "%s", errbuf);
            goto cleanup;
        }

        if (entry->mask & KADM5_FAIL_AUTH_COUNT_INCREMENT)
            entry->fail_auth_count++;
    }

cleanup:
    if (user)
        free(user);

    if (filtuser)
        free(filtuser);

    free_xargs(xargs);

    if (standalone_principal_dn)
        free(standalone_principal_dn);

    if (principal_dn)
        free (principal_dn);

    if (polname != NULL)
        free(polname);

    if (subtree)
        free (subtree);

    if (bersecretkey) {
        for (l=0; bersecretkey[l]; ++l) {
            if (bersecretkey[l]->bv_val)
                free (bersecretkey[l]->bv_val);
            free (bersecretkey[l]);
        }
        free (bersecretkey);
    }

    if (keys)
        free (keys);

    ldap_mods_free(mods, 1);
    krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
    return(st);
}
Beispiel #17
0
/** @brief Return LDAP error for a ldap error.
  * @param res LDAP error id.
  * @returns Error string.*/
extern const char *ldap_errmsg(int res) {
	return ldap_err2string(res);
}
Beispiel #18
0
static int ldap_verify_user_password (CcnetUserManager *manager,
                                      const char *uid,
                                      const char *password)
{
    LDAP *ld = NULL;
    int res;
    GString *filter;
    char *filter_str = NULL;
    char *attrs[2];
    LDAPMessage *msg = NULL, *entry;
    char *dn = NULL;
    int ret = 0;

    /* First search for the DN with the given uid. */

    ld = ldap_init_and_bind (manager->ldap_host,
#ifdef WIN32
                             manager->use_ssl,
#endif
                             manager->user_dn,
                             manager->password);
    if (!ld)
        return -1;

    filter = g_string_new (NULL);
    g_string_printf (filter, "(%s=%s)", manager->login_attr, uid);
    filter_str = g_string_free (filter, FALSE);

    attrs[0] = manager->login_attr;
    attrs[1] = NULL;

    res = ldap_search_s (ld, manager->base, LDAP_SCOPE_SUBTREE,
                         filter_str, attrs, 0, &msg);
    if (res != LDAP_SUCCESS) {
        ccnet_warning ("ldap_search failed: %s.\n", ldap_err2string(res));
        ret = -1;
        goto out;
    }

    entry = ldap_first_entry (ld, msg);
    if (!entry) {
        ccnet_warning ("user with uid %s not found in LDAP.\n", uid);
        ret = -1;
        goto out;
    }

    dn = ldap_get_dn (ld, entry);

    /* Then bind the DN with password. */

    ldap_unbind_s (ld);

    ld = ldap_init_and_bind (manager->ldap_host,
#ifdef WIN32
                             manager->use_ssl,
#endif
                             dn, password);
    if (!ld) {
        ccnet_warning ("Password check for %s failed.\n", uid);
        ret = -1;
    }

out:
    ldap_msgfree (msg);
    ldap_memfree (dn);
    g_free (filter_str);
    if (ld) ldap_unbind_s (ld);
    return ret;
}
Beispiel #19
0
static int domodrdn(
	LDAP	*ld,
	char	*dn,
	char	*rdn,
	char	*newSuperior,
	int		remove ) /* flag: remove old RDN */
{
	int rc, code, id;
	char *matcheddn=NULL, *text=NULL, **refs=NULL;
	LDAPControl **ctrls = NULL;
	LDAPMessage *res;

	if ( verbose ) {
		printf( _("Renaming \"%s\"\n"), dn );
		printf( _("\tnew rdn=\"%s\" (%s old rdn)\n"),
			rdn, remove ? _("delete") : _("keep") );
		if( newSuperior != NULL ) {
			printf(_("\tnew parent=\"%s\"\n"), newSuperior);
		}
	}

	if( dont ) return LDAP_SUCCESS;

	rc = ldap_rename( ld, dn, rdn, newSuperior, remove,
		NULL, NULL, &id );

	if ( rc != LDAP_SUCCESS ) {
		fprintf( stderr, "%s: ldap_rename: %s (%d)\n",
			prog, ldap_err2string( rc ), rc );
		return rc;
	}

	for ( ; ; ) {
		struct timeval	tv = { 0, 0 };

		if ( tool_check_abandon( ld, id ) ) {
			return LDAP_CANCELLED;
		}

		tv.tv_sec = 0;
		tv.tv_usec = 100000;

		rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
		if ( rc < 0 ) {
			tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
			return rc;
		}

		if ( rc != 0 ) {
			break;
		}
	}

	rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, &ctrls, 1 );

	if( rc != LDAP_SUCCESS ) {
		fprintf( stderr, "%s: ldap_parse_result: %s (%d)\n",
			prog, ldap_err2string( rc ), rc );
		return rc;
	}

	if( verbose || code != LDAP_SUCCESS ||
		(matcheddn && *matcheddn) || (text && *text) || (refs && *refs) )
	{
		printf( _("Rename Result: %s (%d)\n"),
			ldap_err2string( code ), code );

		if( text && *text ) {
			printf( _("Additional info: %s\n"), text );
		}

		if( matcheddn && *matcheddn ) {
			printf( _("Matched DN: %s\n"), matcheddn );
		}

		if( refs ) {
			int i;
			for( i=0; refs[i]; i++ ) {
				printf(_("Referral: %s\n"), refs[i] );
			}
		}
	}

	if (ctrls) {
		tool_print_ctrls( ld, ctrls );
		ldap_controls_free( ctrls );
	}

	ber_memfree( text );
	ber_memfree( matcheddn );
	ber_memvfree( (void **) refs );

	return code;
}
Beispiel #20
0
/*
 * @uid: user's uid, list all users if * is passed in.
 */
static GList *ldap_list_users (CcnetUserManager *manager, const char *uid,
                               int start, int limit)
{
    LDAP *ld = NULL;
    GList *ret = NULL;
    int res;
    GString *filter;
    char *filter_str;
    char *attrs[2];
    LDAPMessage *msg = NULL, *entry;

    ld = ldap_init_and_bind (manager->ldap_host,
#ifdef WIN32
                             manager->use_ssl,
#endif
                             manager->user_dn,
                             manager->password);
    if (!ld)
        return NULL;

    filter = g_string_new (NULL);
    g_string_printf (filter, "(%s=%s)", manager->login_attr, uid);
    filter_str = g_string_free (filter, FALSE);

    attrs[0] = manager->login_attr;
    attrs[1] = NULL;

    res = ldap_search_s (ld, manager->base, LDAP_SCOPE_SUBTREE,
                         filter_str, attrs, 0, &msg);
    if (res != LDAP_SUCCESS) {
        ccnet_warning ("ldap_search failed: %s.\n", ldap_err2string(res));
        ret = NULL;
        goto out;
    }

    int i = 0;
    if (start == -1)
        start = 0;

    for (entry = ldap_first_entry (ld, msg);
         entry != NULL;
         entry = ldap_next_entry (ld, entry), ++i)
    {
        char *attr;
        char **vals;
        BerElement *ber;
        CcnetEmailUser *user;

        if (i < start)
            continue;
        if (limit >= 0 && i >= start + limit)
            break;

        attr = ldap_first_attribute (ld, entry, &ber);
        vals = ldap_get_values (ld, entry, attr);

        user = g_object_new (CCNET_TYPE_EMAIL_USER,
                             "id", 0,
                             "email", vals[0],
                             "is_staff", FALSE,
                             "is_active", TRUE,
                             "ctime", (gint64)0,
                             NULL);
        ret = g_list_prepend (ret, user);

        ldap_memfree (attr);
        ldap_value_free (vals);
        ber_free (ber, 0);
    }

out:
    ldap_msgfree (msg);
    g_free (filter_str);
    if (ld) ldap_unbind_s (ld);
    return ret;
}
static void *modify_thread(char *id) {
  LDAPMessage *res;
  LDAPMessage *e;
  int i, modentry, num_entries, msgid, parse_rc, finished;
  int rc, opcount;
  LDAPMod mod;
  LDAPMod *mods[2];
  char *vals[2];
  char *dn;
  ldapmsgwrapper *list, *lmwp, *lastlmwp;
  struct timeval zerotime;
  void *voidrc = (void *)0;

  zerotime.tv_sec = zerotime.tv_usec = 0L;

  printf("Starting modify_thread %s.\n", id);
  opcount = 0;
  tsd_setup();

  rc = ldap_search_ext(ld, BASE, SCOPE, "(objectclass=*)", NULL, 0, NULL, NULL,
                       NULL, LDAP_NO_LIMIT, &msgid);
  if (rc != LDAP_SUCCESS) {
    fprintf(stderr,
            "Thread %s error: Modify thread: "
            "ldap_search_ext: %s\n",
            id, ldap_err2string(rc));
    exit(1);
  }
  list = lastlmwp = NULL;
  finished = 0;
  num_entries = 0;
  while (!finished) {
    rc = ldap_result(ld, msgid, LDAP_MSG_ONE, &zerotime, &res);
    switch (rc) {
      case -1:
        rc = ldap_get_lderrno(ld, NULL, NULL);
        fprintf(stderr, "ldap_result: %s\n", ldap_err2string(rc));
        exit(1);
        break;
      case 0:
        break;
      /* Keep track of the number of entries found. */
      case LDAP_RES_SEARCH_ENTRY:
        num_entries++;
        if ((lmwp = (ldapmsgwrapper *)malloc(sizeof(ldapmsgwrapper))) == NULL) {
          fprintf(stderr, "Thread %s: Modify thread: Cannot malloc\n", id);
          exit(1);
        }
        lmwp->lmw_messagep = res;
        lmwp->lmw_next = NULL;
        if (lastlmwp == NULL) {
          list = lastlmwp = lmwp;
        } else {
          lastlmwp->lmw_next = lmwp;
        }
        lastlmwp = lmwp;
        break;
      case LDAP_RES_SEARCH_REFERENCE:
        break;
      case LDAP_RES_SEARCH_RESULT:
        finished = 1;
        parse_rc = ldap_parse_result(ld, res, &rc, NULL, NULL, NULL, NULL, 1);
        if (parse_rc != LDAP_SUCCESS) {
          fprintf(stderr, "Thread %s error: can't parse result code.\n", id);
          exit(1);
        } else {
          if (rc != LDAP_SUCCESS) {
            fprintf(stderr, "Thread %s error: ldap_search: %s\n", id,
                    ldap_err2string(rc));
          } else {
            printf("Thread %s: Got %d results.\n", id, num_entries);
          }
        }
        break;
      default:
        break;
    }
  }

  mods[0] = &mod;
  mods[1] = NULL;
  vals[0] = "bar";
  vals[1] = NULL;

  for (;;) {
    modentry = random() % num_entries;
    for (i = 0, lmwp = list; lmwp != NULL && i < modentry;
         i++, lmwp = lmwp->lmw_next) {
      /* NULL */
    }

    if (lmwp == NULL) {
      fprintf(stderr,
              "Thread %s: Modify thread could not find entry %d of %d\n", id,
              modentry, num_entries);
      continue;
    }

    e = lmwp->lmw_messagep;
    printf("Thread %s: Modify thread picked entry %d of %d\n", id, i,
           num_entries);
    dn = ldap_get_dn(ld, e);

    mod.mod_op = LDAP_MOD_REPLACE;
    mod.mod_type = "description";
    mod.mod_values = vals;
    printf("Thread %s: Modifying (%s)\n", id, dn);

    rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL);
    if (rc != LDAP_SUCCESS) {
      fprintf(stderr, "ldap_modify_ext_s: %s\n", ldap_err2string(rc));
      if (rc == LDAP_SERVER_DOWN) {
        perror("ldap_modify_ext_s");
        voidrc = (void *)1;
        goto modify_cleanup_and_return;
      }
    }
    free(dn);

    ++opcount;
    if (maxops != 0 && opcount >= maxops) {
      break;
    }
  }

modify_cleanup_and_return:
  printf("Thread %s: attempted %d modify operations\n", id, opcount);
  set_ld_error(0, NULL, NULL, NULL); /* disposes of memory */
  tsd_cleanup();
  free(id);
  return voidrc;
}
Beispiel #22
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
  int yubi_attr_prefix_len = 0;
  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;

  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 */
  i = (strlen(cfg->user_attr) + strlen(cfg->ldapdn) + strlen(user) + 3) * sizeof(char);
  if ((find = malloc(i)) == NULL) {
    DBG (("Failed allocating %i bytes", i));
    retval = 0;
    goto done;
  }

  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)
	    {
	      DBG(("LDAP : Found %i values - checking if any of them match '%s%s'",
		   ldap_count_values_len(vals),
		   cfg->yubi_attr_prefix ? cfg->yubi_attr_prefix : "",
		   token_id));

	      yubi_attr_prefix_len = cfg->yubi_attr_prefix ? strlen(cfg->yubi_attr_prefix) : 0;

	      /* Compare each value for the attribute against the token id. */
	      for (i = 0; vals[i] != NULL; i++)
		{
		  /* Only values containing this prefix are considered. */
		  if ((!cfg->yubi_attr_prefix || !strncmp (cfg->yubi_attr_prefix, vals[i]->bv_val, yubi_attr_prefix_len)))
		    {
		      if(!strncmp (token_id, vals[i]->bv_val + yubi_attr_prefix_len, strlen (token_id)))
		        {
		          DBG (("Token Found :: %s", vals[i]->bv_val));
		          retval = 1;
		        }
		    }
		}
	      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);

#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;
}
static void *delete_thread(char *id) {
  LDAPMessage *res;
  char dn[BUFSIZ], name[40];
  int num_entries, msgid, rc, parse_rc, finished, opcount;
  struct timeval zerotime;
  void *voidrc = (void *)0;

  zerotime.tv_sec = zerotime.tv_usec = 0L;

  printf("Starting delete_thread %s.\n", id);
  opcount = 0;
  tsd_setup();

  rc = ldap_search_ext(ld, BASE, SCOPE, "(objectclass=*)", NULL, 0, NULL, NULL,
                       NULL, LDAP_NO_LIMIT, &msgid);
  if (rc != LDAP_SUCCESS) {
    fprintf(stderr,
            "Thread %s error: Delete thread: "
            "ldap_search_ext: %s\n",
            id, ldap_err2string(rc));
    exit(1);
  }

  finished = 0;
  num_entries = 0;
  while (!finished) {
    rc = ldap_result(ld, msgid, LDAP_MSG_ONE, &zerotime, &res);
    switch (rc) {
      case -1:
        rc = ldap_get_lderrno(ld, NULL, NULL);
        fprintf(stderr, "ldap_result: %s\n", ldap_err2string(rc));
        exit(1);
        break;
      case 0:
        break;
      /* Keep track of the number of entries found. */
      case LDAP_RES_SEARCH_ENTRY:
        num_entries++;
        break;
      case LDAP_RES_SEARCH_REFERENCE:
        break;
      case LDAP_RES_SEARCH_RESULT:
        finished = 1;
        parse_rc = ldap_parse_result(ld, res, &rc, NULL, NULL, NULL, NULL, 1);
        if (parse_rc != LDAP_SUCCESS) {
          fprintf(stderr, "Thread %s error: can't parse result code.\n", id);
          exit(1);
        } else {
          if (rc != LDAP_SUCCESS) {
            fprintf(stderr, "Thread %s error: ldap_search: %s\n", id,
                    ldap_err2string(rc));
          } else {
            printf("Thread %s: Got %d results.\n", id, num_entries);
          }
        }
        break;
      default:
        break;
    }
  }

  for (;;) {
    sprintf(name, "%d", get_random_id());
    sprintf(dn, "cn=%s, " BASE, name);
    printf("Thread %s: Deleting entry (%s)\n", id, dn);

    if ((rc = ldap_delete_ext_s(ld, dn, NULL, NULL)) != LDAP_SUCCESS) {
      ldap_perror(ld, "ldap_delete_ext_s");
      if (rc == LDAP_SERVER_DOWN) {
        perror("ldap_delete_ext_s");
        voidrc = (void *)1;
        goto delete_cleanup_and_return;
      }
    }

    ++opcount;
    if (maxops != 0 && opcount >= maxops) {
      break;
    }
  }

delete_cleanup_and_return:
  printf("Thread %s: attempted %d delete operations\n", id, opcount);
  set_ld_error(0, NULL, NULL, NULL); /* disposes of memory */
  tsd_cleanup();
  free(id);
  return voidrc;
}
Beispiel #24
0
void LDAPSession::remove ( string dn )
{
	int errc= ldap_delete_s ( ld,dn.c_str() );
	if ( errc != LDAP_SUCCESS )
		throw LDAPExeption ( "ldap_delete_s",ldap_err2string ( errc ) );
}
Beispiel #25
0
void run_ldap_tests(service_t *ldaptest, int sslcertcheck, int querytimeout)
{
#ifdef XYMON_LDAP
	ldap_data_t *req;
	testitem_t *t;
	struct timespec starttime;
	struct timespec endtime;

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

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

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

		ludp = (LDAPURLDesc *) req->ldapdesc;

		getntimer(&starttime);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		getntimer(&endtime);

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

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

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

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

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

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

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

		ldap_msgfree(result);
		ldap_unbind(ld);
		ldap_free_urldesc(ludp);
	}
#endif
}
Beispiel #26
0
void LDAPSession::stringSearch ( string dn,const list<string> &attributes,
                                 string searchParam,
                                 list<LDAPStringEntry>& result )
{
	char** attr;
	attr= ( char** ) malloc ( sizeof ( char* ) *attributes.size() +1 );
	int i=0;
	list<string>::const_iterator it=attributes.begin();
	list<string>::const_iterator end=attributes.end();
	for ( ;it!=end;++it )
	{
		attr[i]= ( char* ) malloc ( sizeof ( char ) *
		                            ( *it ).length() +1 );
		strcpy ( attr[i], ( *it ).c_str() );
		++i;
	}
	attr[i]=0l;
	LDAPMessage* res;
	int errc=ldap_search_s ( ld,dn.c_str(),LDAP_SCOPE_SUBTREE,
	                         searchParam.c_str(),attr,0,&res );
	if ( errc != LDAP_SUCCESS )
	{
		i=0;
		it=attributes.begin();
		for ( ;it!=end;++it )
		{
			free ( attr[i] );
			++i;
		}
		free ( attr );
		throw LDAPExeption ( "ldap_search_s",ldap_err2string ( errc ) );
	}
	LDAPMessage *entry=ldap_first_entry ( ld,res );
	while ( entry )
	{
		LDAPStringEntry stringEntry;
		it=attributes.begin();
		for ( ;it!=end;++it )
		{
			LDAPStringValue val;
			val.attr= ( *it );
			char **atr=ldap_get_values ( ld,entry,
			                             ( *it ).c_str() );
			int count=ldap_count_values ( atr );
			for ( i=0;i<count;i++ )
			{
				val.value.push_back ( atr[i] );
			}
			ldap_value_free ( atr );
			stringEntry.push_back ( val );
		}
		entry=ldap_next_entry ( ld,entry );
		result.push_back ( stringEntry );
	}
	free ( res );
	i=0;
	it=attributes.begin();
	for ( ;it!=end;++it )
	{
		free ( attr[i] );
		++i;
	}
	free ( attr );
}
Beispiel #27
0
int ldap_params_search(
	int* _ld_result_count,
	char* _lds_name,
	char* _dn,
	int _scope,
	char** _attrs,
	char* _filter,
	...)
{
	int rc;
	static char filter_str[LDAP_MAX_FILTER_LEN];
	char *filter_ptr = NULL;
	va_list filter_vars;

	/*
	* check _scope
	*/
	switch (_scope)
	{
	case LDAP_SCOPE_ONELEVEL:
	case LDAP_SCOPE_BASE:
	case LDAP_SCOPE_SUBTREE:
		break;
	default:
		LM_ERR("[%s]: invalid scope argument [%d]\n", _lds_name, _scope);
		return -1;
	}

	if (_filter) {
		/*
		* vsnprintf
		*/
		va_start(filter_vars, _filter);
		rc = vsnprintf(filter_str, (size_t)LDAP_MAX_FILTER_LEN, _filter,
				filter_vars);
		va_end(filter_vars);

		if (rc >= LDAP_MAX_FILTER_LEN)
		{
			LM_ERR(	"[%s]: filter string too long (len [%d], max len [%d])\n",
				_lds_name,
				rc,
				LDAP_MAX_FILTER_LEN);
			return -1;
		}
		else if (rc < 0)
		{
			LM_ERR("vsnprintf failed\n");
			return -1;
		}
		filter_ptr = filter_str;
	}

	/*
	* ldap search
	*/
	if (lds_search(_lds_name,
			_dn,
			_scope,
			filter_ptr,
			_attrs,
			NULL,
			_ld_result_count,
			&rc)
		!= 0)
	{
		/* try again if LDAP API ERROR */
		if (LDAP_API_ERROR(rc) && 
				(lds_search(_lds_name,
						_dn,
						_scope,
						filter_str,
						_attrs,
						NULL,
						_ld_result_count,
						&rc) != 0))
		{
			LM_ERR(	"[%s]: LDAP search (dn [%s], scope [%d],"
				" filter [%s]) failed: %s\n",
				_lds_name,
				_dn,
				_scope,
				filter_str,
				ldap_err2string(rc));
			return -1;
		}
	}
	
	LM_DBG(	"[%s]: [%d] LDAP entries found\n", 
		_lds_name,
		*_ld_result_count);
	
	return 0;
}
Beispiel #28
0
static int
process( void *arg )
{
    char	*rbuf, *saved_rbuf, *start, *p, *q;
    FILE	*rfp = NULL;
    int		rc, use_ldif, deref;
    LDAPControl	*ldctrl;

#ifdef SOLARIS_LDAP_CMD
    LDAP	*ld;
#endif  /* SOLARIS_LDAP_CMD */
    
    ld = ldaptool_ldap_init( 0 );

    if ( !ldaptool_not ) {
	deref = LDAP_DEREF_NEVER;	/* this seems prudent */
	ldap_set_option( ld, LDAP_OPT_DEREF, &deref );
    }

    ldaptool_bind( ld );

    if (( ldctrl = ldaptool_create_manage_dsait_control()) != NULL ) {
	ldaptool_add_control_to_array( ldctrl, ldaptool_request_ctrls);
    } 

    if ((ldctrl = ldaptool_create_proxyauth_control(ld)) !=NULL) {
	ldaptool_add_control_to_array( ldctrl, ldaptool_request_ctrls);
    }

    rc = 0;

    /* turn on bulk import?*/
    if (bulkimport_suffix) {
	struct berval	bv, *retdata;
	char		*retoid;

	bv.bv_val = bulkimport_suffix;
	bv.bv_len = strlen(bulkimport_suffix);
	if ((rc = ldap_extended_operation_s(ld,
	    BULKIMPORT_START_OID, &bv, NULL,
	    NULL, &retoid, &retdata)) != 0) {
		fprintf(stderr, gettext("Error: unable to service "
		    "extended operation request\n\t'%s' for "
		    "bulk import\n\t(error:%d:'%s')\n"),
		    BULKIMPORT_START_OID, rc, ldap_err2string(rc));
		return (rc);
	}
	if (retoid)
		ldap_memfree(retoid);
	if (retdata)
		ber_bvfree(retdata);
    }

    while (( rc == 0 || contoper ) &&
		( rbuf = read_one_record( ldaptool_fp )) != NULL ) {
	/*
	 * we assume record is ldif/slapd.replog if the first line
	 * has a colon that appears to the left of any equal signs, OR
	 * if the first line consists entirely of digits (an entry id)
	 */
	use_ldif = ( p = strchr( rbuf, ':' )) != NULL &&
		( q = strchr( rbuf, '\n' )) != NULL && p < q &&
		(( q = strchr( rbuf, '=' )) == NULL || p < q );

	start = rbuf;
	saved_rbuf = strdup( rbuf );

	if ( !use_ldif && ( q = strchr( rbuf, '\n' )) != NULL ) {
	    for ( p = rbuf; p < q; ++p ) {
		if ( !isdigit( *p )) {
		    break;
		}
	    }
	    if ( p >= q ) {
		use_ldif = 1;
		start = q + 1;
	    }
	}

#ifdef SOLARIS_LDAP_CMD
	if ( use_ldif ) {
	    rc = process_ldif_rec( ld, start );
	} else {
	    rc = process_ldapmod_rec( ld, start );
	}
#else
	if ( use_ldif ) {
	    rc = process_ldif_rec( start );
	} else {
	    rc = process_ldapmod_rec( start );
	}
#endif	/* SOLARIS_LDAP_CMD */

	if ( rc != LDAP_SUCCESS && rejfile != NULL ) {
	    /* Write this record to the reject file */
	    int newfile = 0;
	    struct stat stbuf;
	    if ( stat( rejfile, &stbuf ) < 0 ) {
		if ( errno == ENOENT ) {
		    newfile = 1;
		}
	    }
	    if (( rfp = ldaptool_open_file( rejfile, "a" )) == NULL ) {
		fprintf( stderr, gettext("Cannot open error file \"%s\" - "
			"erroneous entries will not be saved\n"), rejfile );
		rejfile = NULL;
	    } else {
		if ( newfile == 0 ) {
		    fputs( "\n", rfp );
		}
		fprintf( rfp, gettext("# Error: %s\n"), ldap_err2string( rc ));
		fputs( saved_rbuf, rfp );
		fclose( rfp );
		rfp = NULL;
	    }
	}

	free( rbuf );
	free( saved_rbuf );
    }
    ldaptool_reset_control_array( ldaptool_request_ctrls );

    /* turn off bulk import?*/
    if (bulkimport_suffix) {
	struct berval	bv, *retdata;
	char		*retoid;

	bv.bv_val = "";
	bv.bv_len = 0;
	if ((rc = ldap_extended_operation_s(ld,
	    BULKIMPORT_STOP_OID, &bv, NULL,
	    NULL, &retoid, &retdata)) != 0) {

		fprintf(stderr, gettext("Error: unable to service "
		    "extended operation request\n\t '%s' for "
		    "bulk import\n\t(rc:%d:'%s')\n"),
		    BULKIMPORT_STOP_OID, rc, ldap_err2string(rc));
		return (rc);
	}
	if (retoid)
		ldap_memfree(retoid);
	if (retdata)
		ber_bvfree(retdata);
    }

#ifdef SOLARIS_LDAP_CMD
    mutex_lock(&read_mutex);	
#endif
    ldaptool_cleanup( ld );
#ifdef SOLARIS_LDAP_CMD
    mutex_unlock(&read_mutex);	
#endif
    return( rc );
}
Beispiel #29
0
/*
 * Remove an array of values from a value set.
 * The removed values are passed back in an array.
 *
 * Flags
 *  SLAPI_VALUE_FLAG_PRESERVECSNSET - csnset in the value set is duplicated and
 *                                    preserved in the matched element of the
 *                                    array of values.
 *  SLAPI_VALUE_FLAG_IGNOREERROR - ignore an error: Couldn't find the value to
 *                                 be deleted.
 *  SLAPI_VALUE_FLAG_USENEWVALUE - replace the value between the value set and
 *                                 the matched element of the array of values
 *                                 (used by entry_add_present_values_wsi).
 *
 * Returns
 *  LDAP_SUCCESS - OK.
 *  LDAP_NO_SUCH_ATTRIBUTE - A value to be deleted was not in the value set.
 *  LDAP_OPERATIONS_ERROR - Something very bad happened.
 */
int
valueset_remove_valuearray(Slapi_ValueSet *vs, const Slapi_Attr *a, Slapi_Value **valuestodelete, int flags, Slapi_Value ***va_out)
{
	int rc= LDAP_SUCCESS;
	if(!valuearray_isempty(vs->va))
	{
		int numberofvaluestodelete= valuearray_count(valuestodelete);
		struct valuearrayfast vaf_out;
		if ( va_out )
		{
			valuearrayfast_init(&vaf_out,*va_out);
		}

		/*
		 * If there are more then one values, build an AVL tree to check
		 * the duplicated values.
		 */
		if ( numberofvaluestodelete > 1 )
		{
			/*
			 * Several values to delete: first build an AVL tree that
			 * holds all of the existing values and use that to find
			 * the values we want to delete.
			 */
			Avlnode	*vtree = NULL;
			int numberofexistingvalues= slapi_valueset_count(vs);
			rc= valuetree_add_valuearray( a, vs->va, &vtree, NULL );
			if ( rc!=LDAP_SUCCESS )
			{
				/*
				 * failed while constructing AVL tree of existing
				 * values... something bad happened.
				 */
				rc= LDAP_OPERATIONS_ERROR;
			}
			else
			{
				int i;
				/*
				 * find and mark all the values that are to be deleted
				 */
				for ( i = 0; rc == LDAP_SUCCESS && valuestodelete[i] != NULL; ++i )
				{
					int index= 0;
					rc = valuetree_find( a, valuestodelete[i], vtree, &index );
					if(rc==LDAP_SUCCESS)
					{
						if(vs->va[index]!=NULL)
						{
							/* Move the value to be removed to the out array */
							if ( va_out )
							{
								if (vs->va[index]->v_csnset &&
									(flags & (SLAPI_VALUE_FLAG_PRESERVECSNSET|
                                              SLAPI_VALUE_FLAG_USENEWVALUE)))
								{
									valuestodelete[i]->v_csnset = csnset_dup (vs->va[index]->v_csnset);
								}
								if (flags & SLAPI_VALUE_FLAG_USENEWVALUE)
								{
									valuearrayfast_add_value_passin(&vaf_out,valuestodelete[i]);
									valuestodelete[i] = vs->va[index];
									vs->va[index] = NULL;
								}
								else
								{
									valuearrayfast_add_value_passin(&vaf_out,vs->va[index]);
									vs->va[index] = NULL;
								}
							}
							else
							{
								if (flags & SLAPI_VALUE_FLAG_PRESERVECSNSET)
								{
									valuestodelete[i]->v_csnset = vs->va[index]->v_csnset;
									vs->va[index]->v_csnset = NULL;
								}
								slapi_value_free ( & vs->va[index] );
							}
						}
						else
						{
							/* We already deleted this value... */
							if((flags & SLAPI_VALUE_FLAG_IGNOREERROR) == 0)
							{
								/* ...that's an error. */
								rc= LDAP_NO_SUCH_ATTRIBUTE;
							}
						}
					}
					else
					{
						/* Couldn't find the value to be deleted */
						if(rc==LDAP_NO_SUCH_ATTRIBUTE && (flags & SLAPI_VALUE_FLAG_IGNOREERROR ))
						{
							rc= LDAP_SUCCESS;
						}
					}
				}
				valuetree_free( &vtree );

				if ( rc != LDAP_SUCCESS )
				{
					LDAPDebug( LDAP_DEBUG_ANY,"could not find value %d for attr %s (%s)\n", i-1, a->a_type, ldap_err2string( rc ));
				}
				else
				{
					/* Shunt up all the remaining values to cover the deleted ones. */
					valuearray_compress(vs->va,numberofexistingvalues);
				}
			}
		}
		else
		{
			/* We delete one or no value, so we use brute force. */
			int i;
			for ( i = 0; rc==LDAP_SUCCESS && valuestodelete[i] != NULL; ++i )
			{
				Slapi_Value *found= valueset_remove_value(a, vs, valuestodelete[i]);
				if(found!=NULL)
				{
					if ( va_out )
					{
						if (found->v_csnset &&
							(flags & (SLAPI_VALUE_FLAG_PRESERVECSNSET|
                                      SLAPI_VALUE_FLAG_USENEWVALUE)))
						{
							valuestodelete[i]->v_csnset = csnset_dup (found->v_csnset);
						}
						if (flags & SLAPI_VALUE_FLAG_USENEWVALUE)
						{
							valuearrayfast_add_value_passin(&vaf_out,valuestodelete[i]);
							valuestodelete[i] = found;
						}
						else
						{
							valuearrayfast_add_value_passin(&vaf_out,found);
						}
					}
					else
					{
						if (flags & SLAPI_VALUE_FLAG_PRESERVECSNSET)
						{
							valuestodelete[i]->v_csnset = found->v_csnset;
							found->v_csnset = NULL;
						}
						slapi_value_free ( & found );
					}
				}
				else
				{
					if((flags & SLAPI_VALUE_FLAG_IGNOREERROR) == 0)
					{
						LDAPDebug( LDAP_DEBUG_ARGS,"could not find value %d for attr %s\n", i-1, a->a_type, 0 );
						rc= LDAP_NO_SUCH_ATTRIBUTE;
					}
				}
			}
		}
		if ( va_out )
		{
			*va_out= vaf_out.va;
			if(rc!=LDAP_SUCCESS)
			{
				valuearray_free(va_out);
			}
		}
	}
	return rc;
}
Beispiel #30
0
handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
#ifdef USE_LDAP
	int ret;
#if 0
	if (s->auth_ldap_basedn->used == 0) {
		log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set");

		return HANDLER_ERROR;
	}
#endif

	if (s->auth_ldap_hostname->used) {
		/* free old context */
		if (NULL != s->ldap) ldap_unbind_s(s->ldap);

		if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) {
			log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno));

			return HANDLER_ERROR;
		}

		ret = LDAP_VERSION3;
		if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
			log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

			return HANDLER_ERROR;
		}

		if (s->auth_ldap_starttls) {
			/* if no CA file is given, it is ok, as we will use encryption
				* if the server requires a CAfile it will tell us */
			if (!buffer_is_empty(s->auth_ldap_cafile)) {
				if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
								s->auth_ldap_cafile->ptr))) {
					log_error_write(srv, __FILE__, __LINE__, "ss",
							"Loading CA certificate failed:", ldap_err2string(ret));

					return HANDLER_ERROR;
				}
			}

			if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL,  NULL))) {
				log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));

				return HANDLER_ERROR;
			}
		}


		/* 1. */
		if (s->auth_ldap_binddn->used) {
			if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) {
				log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

				return HANDLER_ERROR;
			}
		} else {
			if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) {
				log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

				return HANDLER_ERROR;
			}
		}
	}
	return HANDLER_GO_ON;
#else
	UNUSED(s);
	log_error_write(srv, __FILE__, __LINE__, "s", "no ldap support available");
	return HANDLER_ERROR;
#endif
}