Implemented gsasl driver for authentication.
[users/heiko/exim.git] / src / src / exim.c
index 371bc1025c5c584292aa32bf0c6004c9f945ddbd..b4ea01dcd35fa64cd6adfb4a8ddabc9848bc12e6 100644 (file)
@@ -1,5 +1,3 @@
-/* $Cambridge: exim/src/src/exim.c,v 1.71 2010/06/07 00:12:42 pdp Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
@@ -140,6 +138,38 @@ return yield;
 
 
 
+/*************************************************
+*            Set up processing details           *
+*************************************************/
+
+/* Save a text string for dumping when SIGUSR1 is received.
+Do checks for overruns.
+
+Arguments: format and arguments, as for printf()
+Returns:   nothing
+*/
+
+void
+set_process_info(const char *format, ...)
+{
+int len;
+va_list ap;
+sprintf(CS process_info, "%5d ", (int)getpid());
+len = Ustrlen(process_info);
+va_start(ap, format);
+if (!string_vformat(process_info + len, PROCESS_INFO_SIZE - len - 2, format, ap))
+  Ustrcpy(process_info + len, "**** string overflowed buffer ****");
+len = Ustrlen(process_info);
+process_info[len+0] = '\n';
+process_info[len+1] = '\0';
+process_info_len = len + 1;
+DEBUG(D_process_info) debug_printf("set_process_info: %s", process_info);
+va_end(ap);
+}
+
+
+
+
 /*************************************************
 *             Handler for SIGUSR1                *
 *************************************************/
@@ -149,6 +179,8 @@ what it is currently doing. It will only be used if the OS is capable of
 setting up a handler that causes automatic restarting of any system call
 that is in progress at the time.
 
+This function takes care to be signal-safe.
+
 Argument: the signal number (SIGUSR1)
 Returns:  nothing
 */
@@ -156,10 +188,32 @@ Returns:  nothing
 static void
 usr1_handler(int sig)
 {
-sig = sig;      /* Keep picky compilers happy */
-log_write(0, LOG_PROCESS, "%s", process_info);
-log_close_all();
-os_restarting_signal(SIGUSR1, usr1_handler);
+int fd;
+
+os_restarting_signal(sig, usr1_handler);
+
+fd = Uopen(process_log_path, O_APPEND|O_WRONLY, LOG_MODE);
+if (fd < 0)
+  {
+  /* If we are already running as the Exim user, try to create it in the
+  current process (assuming spool_directory exists). Otherwise, if we are
+  root, do the creation in an exim:exim subprocess. */
+
+  int euid = geteuid();
+  if (euid == exim_uid)
+    fd = Uopen(process_log_path, O_CREAT|O_APPEND|O_WRONLY, LOG_MODE);
+  else if (euid == root_uid)
+    fd = log_create_as_exim(process_log_path);
+  }
+
+/* If we are neither exim nor root, or if we failed to create the log file,
+give up. There is not much useful we can do with errors, since we don't want
+to disrupt whatever is going on outside the signal handler. */
+
+if (fd < 0) return;
+
+(void)write(fd, process_info, process_info_len);
+(void)close(fd);
 }
 
 
@@ -348,35 +402,6 @@ if (exim_tvcmp(&now_tv, then_tv) <= 0)
 
 
 
-/*************************************************
-*            Set up processing details           *
-*************************************************/
-
-/* Save a text string for dumping when SIGUSR1 is received.
-Do checks for overruns.
-
-Arguments: format and arguments, as for printf()
-Returns:   nothing
-*/
-
-void
-set_process_info(const char *format, ...)
-{
-int len;
-va_list ap;
-sprintf(CS process_info, "%5d ", (int)getpid());
-len = Ustrlen(process_info);
-va_start(ap, format);
-if (!string_vformat(process_info + len, PROCESS_INFO_SIZE - len, format, ap))
-  Ustrcpy(process_info + len, "**** string overflowed buffer ****");
-DEBUG(D_process_info) debug_printf("set_process_info: %s\n", process_info);
-va_end(ap);
-}
-
-
-
-
-
 /*************************************************
 *   Call fopen() with umask 777 and adjust mode  *
 *************************************************/
@@ -700,6 +725,8 @@ Returns:    nothing
 static void
 show_whats_supported(FILE *f)
 {
+  auth_info *authi;
+
 #ifdef DB_VERSION_STRING
 fprintf(f, "Berkeley DB: %s\n", DB_VERSION_STRING);
 #elif defined(BTREEVERSION) && defined(HASHVERSION)
@@ -842,6 +869,9 @@ fprintf(f, "Authenticators:");
 #ifdef AUTH_DOVECOT
   fprintf(f, " dovecot");
 #endif
+#ifdef AUTH_GSASL
+  fprintf(f, " gsasl");
+#endif
 #ifdef AUTH_PLAINTEXT
   fprintf(f, " plaintext");
 #endif
@@ -937,9 +967,11 @@ DEBUG(D_any) do {
   tls_version_report(f);
 #endif
 
-#ifdef AUTH_CYRUS_SASL
-  auth_cyrus_sasl_version_report(f);
-#endif
+  for (authi = auths_available; *authi->driver_name != '\0'; ++authi) {
+    if (authi->version_report) {
+      (*authi->version_report)(f);
+    }
+  }
 
   fprintf(f, "Library version: PCRE: Compile: %d.%d%s\n"
              "                       Runtime: %s\n",
@@ -948,7 +980,9 @@ DEBUG(D_any) do {
            * unless its an ancient version of PCRE in which case it
            * is not defined */
 #ifdef PCRE_PRERELEASE
-          PCRE_PRERELEASE "",
+# define STRINGIFY(x) #x
+          STRINGIFY(PCRE_PRERELEASE) "",
+# undef STRINGIFY
 #else
           "",
 #endif
@@ -1053,9 +1087,9 @@ set_readline(char * (**fn_readline_ptr)(const char *),
              void   (**fn_addhist_ptr)(const char *))
 {
 void *dlhandle;
-void *dlhandle_curses = dlopen("libcurses.so", RTLD_GLOBAL|RTLD_LAZY);
+void *dlhandle_curses = dlopen("libcurses." DYNLIB_FN_EXT, RTLD_GLOBAL|RTLD_LAZY);
 
-dlhandle = dlopen("libreadline.so", RTLD_GLOBAL|RTLD_NOW);
+dlhandle = dlopen("libreadline." DYNLIB_FN_EXT, RTLD_GLOBAL|RTLD_NOW);
 if (dlhandle_curses != NULL) dlclose(dlhandle_curses);
 
 if (dlhandle != NULL)