int tls_success(tls_session_t *ssn, REQUEST *request)
{
	VALUE_PAIR *vp, *vps = NULL;
	fr_tls_server_conf_t *conf;
	TALLOC_CTX *talloc_ctx;

	conf = (fr_tls_server_conf_t *)SSL_get_ex_data(ssn->ssl, FR_TLS_EX_INDEX_CONF);
	rad_assert(conf != NULL);

	talloc_ctx = SSL_get_ex_data(ssn->ssl, FR_TLS_EX_INDEX_TALLOC);

	/*
	 *	If there's no session resumption, delete the entry
	 *	from the cache.  This means either it's disabled
	 *	globally for this SSL context, OR we were told to
	 *	disable it for this user.
	 *
	 *	This also means you can't turn it on just for one
	 *	user.
	 */
	if ((!ssn->allow_session_resumption) ||
	    (((vp = pairfind(request->config, PW_ALLOW_SESSION_RESUMPTION, 0, TAG_ANY)) != NULL) &&
	     (vp->vp_integer == 0))) {
		SSL_CTX_remove_session(ssn->ctx,
				       ssn->ssl->session);
		ssn->allow_session_resumption = false;

		/*
		 *	If we're in a resumed session and it's
		 *	not allowed,
		 */
		if (SSL_session_reused(ssn->ssl)) {
			RDEBUG("Forcibly stopping session resumption as it is not allowed");
			return -1;
		}

	/*
	 *	Else resumption IS allowed, so we store the
	 *	user data in the cache.
	 */
	} else if (!SSL_session_reused(ssn->ssl)) {
		size_t size;
		VALUE_PAIR **certs;
		char buffer[2 * MAX_SESSION_SIZE + 1];

		size = ssn->ssl->session->session_id_length;
		if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE;

		fr_bin2hex(buffer, ssn->ssl->session->session_id, size);

		vp = paircopy_by_num(talloc_ctx, request->reply->vps, PW_USER_NAME, 0, TAG_ANY);
		if (vp) pairadd(&vps, vp);

		vp = paircopy_by_num(talloc_ctx, request->packet->vps, PW_STRIPPED_USER_NAME, 0, TAG_ANY);
		if (vp) pairadd(&vps, vp);

		vp = paircopy_by_num(talloc_ctx, request->packet->vps, PW_STRIPPED_USER_DOMAIN, 0, TAG_ANY);
		if (vp) pairadd(&vps, vp);

		vp = paircopy_by_num(talloc_ctx, request->reply->vps, PW_CHARGEABLE_USER_IDENTITY, 0, TAG_ANY);
		if (vp) pairadd(&vps, vp);

		vp = paircopy_by_num(talloc_ctx, request->reply->vps, PW_CACHED_SESSION_POLICY, 0, TAG_ANY);
		if (vp) pairadd(&vps, vp);

		certs = (VALUE_PAIR **)SSL_get_ex_data(ssn->ssl, fr_tls_ex_index_certs);

		/*
		 *	Hmm... the certs should probably be session data.
		 */
		if (certs) {
			/*
			 *	@todo: some go into reply, others into
			 *	request
			 */
			pairadd(&vps, paircopy(talloc_ctx, *certs));

			/*
			 *	Save the certs in the packet, so that we can see them.
			 */
			pairadd(&request->packet->vps, paircopy(request->packet, *certs));
		}

		if (vps) {
			SSL_SESSION_set_ex_data(ssn->ssl->session, fr_tls_ex_index_vps, vps);
			rdebug_pair_list(L_DBG_LVL_2, request, vps, "  caching ");

			if (conf->session_cache_path) {
				/* write the VPs to the cache file */
				char filename[256], buf[1024];
				FILE *vp_file;

				RDEBUG2("Saving session %s in the disk cache", buffer);

				snprintf(filename, sizeof(filename), "%s%c%s.vps", conf->session_cache_path,
					 FR_DIR_SEP, buffer);
				vp_file = fopen(filename, "w");
				if (vp_file == NULL) {
					RWDEBUG("Could not write session VPs to persistent cache: %s",
						fr_syserror(errno));
				} else {
					VALUE_PAIR *prev = NULL;
					vp_cursor_t cursor;
					/* generate a dummy user-style entry which is easy to read back */
					fprintf(vp_file, "# SSL cached session\n");
					fprintf(vp_file, "%s\n\t", buffer);

					for (vp = fr_cursor_init(&cursor, &vps);
					     vp;
					     vp = fr_cursor_next(&cursor)) {
						/*
						 *	Terminate the previous line.
						 */
						if (prev) fprintf(vp_file, ",\n\t");

						/*
						 *	Write this one.
						 */
						vp_prints(buf, sizeof(buf), vp);
						fputs(buf, vp_file);
						prev = vp;
					}

					/*
					 *	Terminate the final line.
					 */
					fprintf(vp_file, "\n");
					fclose(vp_file);
				}
			} else {
				RDEBUG("Failed to find 'persist_dir' in TLS configuration.  Session will not be cached on disk.");
			}
		} else {
			RDEBUG2("No information to cache: session caching will be disabled for session %s", buffer);
			SSL_CTX_remove_session(ssn->ctx, ssn->ssl->session);
		}

	/*
	 *	Else the session WAS allowed.  Copy the cached reply.
	 */
	} else {
		size_t size;
		char buffer[2 * MAX_SESSION_SIZE + 1];

		size = ssn->ssl->session->session_id_length;
		if (size > MAX_SESSION_SIZE) size = MAX_SESSION_SIZE;

		fr_bin2hex(buffer, ssn->ssl->session->session_id, size);

		/*
		 *	The "restore VPs from OpenSSL cache" code is
		 *	now in eaptls_process()
		 */

		if (conf->session_cache_path) {
			/* "touch" the cached session/vp file */
			char filename[256];

			snprintf(filename, sizeof(filename), "%s%c%s.asn1",
				 conf->session_cache_path, FR_DIR_SEP, buffer);
			utime(filename, NULL);
			snprintf(filename, sizeof(filename), "%s%c%s.vps",
				 conf->session_cache_path, FR_DIR_SEP, buffer);
			utime(filename, NULL);
		}

		/*
		 *	Mark the request as resumed.
		 */
		pairmake_packet("EAP-Session-Resumed", "1", T_OP_SET);
	}

	return 0;
}