Okay, I haven't yet found the problem but am getting closer.
When logging in , it apparently tries to expire the old cookie session id (which was generated when the login form was displayed), and set a new one. But this doesn't work, for some reason, and when the browser gets redirected to ./?_task=mail, the browser doesn't send any cookie at all!
It seems that two Set-Cookie headers are sent to the browser along with the redirect request (in response to the login POST request), one with the OLD session id, with expiration set to a few hours from now() and one with the NEW session id with expiration set to January 1970.
Notice the problem? :-)
Strangely, the setcookie() function in session.inc is called with the new session id and lifetime set to some non-zero value (14400)... Could that be a php problem then?
Note that I know that cookies are working, normally, because:
1) Other php applications on the same server work correctly (and set+receive the cookies correctly)
2) When GETting the login form, I get *one* Set-Cookie header with expiration set correctly, and when submitting the form, that session cookie is correctly sent to the server (I print_r'red the $_COOKIE table from index.php to check that).
If any roundcube developer reads this: Is there any particular reason you are using custom session handlers? Would I break something if I just commented out all custom cookie and session handling code, and dropped the "session" table?
Thanks.