Example #1
0
static krb5_error_code
LDAP__connect(krb5_context context, HDB * db)
{
    int rc, version = LDAP_VERSION3;
    /*
     * Empty credentials to do a SASL bind with LDAP. Note that empty
     * different from NULL credentials. If you provide NULL
     * credentials instead of empty credentials you will get a SASL
     * bind in progress message.
     */
    struct berval bv = { 0, "" };

    if (HDB2LDAP(db)) {
	/* connection has been opened. ping server. */
	struct sockaddr_un addr;
	socklen_t len = sizeof(addr);
	int sd;

	if (ldap_get_option(HDB2LDAP(db), LDAP_OPT_DESC, &sd) == 0 &&
	    getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
	    /* the other end has died. reopen. */
	    LDAP_close(context, db);
	}
    }

    if (HDB2LDAP(db) != NULL) /* server is UP */
	return 0;

    rc = ldap_initialize(&((struct hdbldapdb *)db->hdb_db)->h_lp, "ldapi:///");
    if (rc != LDAP_SUCCESS) {
	krb5_set_error_string(context, "ldap_initialize: %s", 
			      ldap_err2string(rc));
	return HDB_ERR_NOENTRY;
    }

    rc = ldap_set_option(HDB2LDAP(db), LDAP_OPT_PROTOCOL_VERSION,
			 (const void *)&version);
    if (rc != LDAP_SUCCESS) {
	krb5_set_error_string(context, "ldap_set_option: %s",
			      ldap_err2string(rc));
	LDAP_close(context, db);
	return HDB_ERR_BADVERSION;
    }

    rc = ldap_sasl_bind_s(HDB2LDAP(db), NULL, "EXTERNAL", &bv,
			  NULL, NULL, NULL);
    if (rc != LDAP_SUCCESS) {
	krb5_set_error_string(context, "ldap_sasl_bind_s: %s",
			      ldap_err2string(rc));
	LDAP_close(context, db);
	return HDB_ERR_BADVERSION;
    }

    return 0;
}
Example #2
0
static int
check_ldap(krb5_context context, HDB *db, int ret)
{
    switch (ret) {
    case LDAP_SUCCESS:
	return 0;
    case LDAP_SERVER_DOWN:
	LDAP_close(context, db);
	return 1;
    default:
	return 1;
    }
}
Example #3
0
static krb5_error_code
LDAP_destroy(krb5_context context, HDB * db)
{
    krb5_error_code ret;

    LDAP_close(context, db);

    ret = hdb_clear_master_key(context, db);
    if (HDB2BASE(db))
	free(HDB2BASE(db));
    if (HDB2CREATE(db))
	free(HDB2CREATE(db));
    if (db->hdb_name)
	free(db->hdb_name);
    free(db->hdb_db);
    free(db);

    return ret;
}
Example #4
0
static krb5_error_code
LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry * entry)
{
    int msgid, rc, parserc;
    krb5_error_code ret;
    LDAPMessage *e;

    msgid = HDB2MSGID(db);
    if (msgid < 0)
	return HDB_ERR_NOENTRY;

    do {
	rc = ldap_result(HDB2LDAP(db), msgid, LDAP_MSG_ONE, NULL, &e);
	switch (rc) {
	case LDAP_RES_SEARCH_REFERENCE:
	    ldap_msgfree(e);
	    ret = 0;
	    break;
	case LDAP_RES_SEARCH_ENTRY:
	    /* We have an entry. Parse it. */
	    ret = LDAP_message2entry(context, db, e, entry);
	    ldap_msgfree(e);
	    break;
	case LDAP_RES_SEARCH_RESULT:
	    /* We're probably at the end of the results. If not, abandon. */
	    parserc =
		ldap_parse_result(HDB2LDAP(db), e, NULL, NULL, NULL,
				  NULL, NULL, 1);
	    if (parserc != LDAP_SUCCESS
		&& parserc != LDAP_MORE_RESULTS_TO_RETURN) {
	        krb5_set_error_string(context, "ldap_parse_result: %s",
				      ldap_err2string(parserc));
		ldap_abandon(HDB2LDAP(db), msgid);
	    }
	    ret = HDB_ERR_NOENTRY;
	    HDBSETMSGID(db, -1);
	    break;
	case LDAP_SERVER_DOWN:
	    ldap_msgfree(e);
	    LDAP_close(context, db);
	    HDBSETMSGID(db, -1);
	    ret = ENETDOWN;
	    break;
	default:
	    /* Some unspecified error (timeout?). Abandon. */
	    ldap_msgfree(e);
	    ldap_abandon(HDB2LDAP(db), msgid);
	    ret = HDB_ERR_NOENTRY;
	    HDBSETMSGID(db, -1);
	    break;
	}
    } while (rc == LDAP_RES_SEARCH_REFERENCE);

    if (ret == 0) {
	if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) {
	    ret = hdb_unseal_keys(context, db, entry);
	    if (ret)
		hdb_free_entry(context,entry);
	}
    }

    return ret;
}