Browse Source

[173687] deadlock caused by error log rotation and logging
Modified to change the owner to the "localuser" if the error log file is not
owned by the user.

Noriko Hosoi 20 years ago
parent
commit
1ec891b346
4 changed files with 49 additions and 29 deletions
  1. 18 0
      ldap/servers/slapd/log.c
  2. 3 29
      ldap/servers/slapd/main.c
  3. 1 0
      ldap/servers/slapd/proto-slap.h
  4. 27 0
      ldap/servers/slapd/util.c

+ 18 - 0
ldap/servers/slapd/log.c

@@ -48,6 +48,7 @@
 
 #include "log.h"
 #include "fe.h"
+#include <pwd.h> /* getpwnam */
 
 #if defined( XP_WIN32 )
 #include <fcntl.h>
@@ -3225,6 +3226,17 @@ log__open_errorlogfile(int logfile_state, int locked)
 	char			tbuf[TBUFSIZE];
 	struct logfileinfo	*logp;
 	char			buffer[BUFSIZ];
+	struct passwd	*pw = NULL;
+
+	slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+	if ( slapdFrontendConfig->localuser != NULL )  {
+		if ( (pw = getpwnam( slapdFrontendConfig->localuser )) == NULL )
+			return LOG_UNABLE_TO_OPENFILE;
+	}
+	else {
+		return LOG_UNABLE_TO_OPENFILE;
+	}
 
 	if (!locked) LOG_ERROR_LOCK_WRITE( );
 
@@ -3287,6 +3299,12 @@ log__open_errorlogfile(int logfile_state, int locked)
 		return LOG_UNABLE_TO_OPENFILE;
 	}
 
+	/* make sure the logfile is owned by the localuser.  If one of the
+	 * alternate ns-slapd modes, such as db2bak, tries to log an error
+	 * at startup, it will create the logfile as root! 
+	 */
+	slapd_chown_if_not_owner(loginfo.log_error_file, pw->pw_uid, -1);
+
 	loginfo.log_error_fdes = fp;
 	if (logfile_state == LOGFILE_REOPENED) {
 		/* we have all the information */

+ 3 - 29
ldap/servers/slapd/main.c

@@ -207,32 +207,6 @@ extern void collation_init();
 
 #ifndef WIN32
 
-/* Changes the ownership of the given file/directory iff not
-   already the owner
-   Returns 0 upon success or non-zero otherwise, usually -1 if
-   some system error occurred
-*/
-static int
-chown_if_not_owner(const char *filename, uid_t uid, gid_t gid)
-{
-	struct stat statbuf;
-	int result = 1;
-	if (!filename)
-		return result;
-
-	memset(&statbuf, '\0', sizeof(statbuf));
-	if (!(result = stat(filename, &statbuf)))
-	{
-		if (((uid != -1) && (uid != statbuf.st_uid)) ||
-			((gid != -1) && (gid != statbuf.st_gid)))
-		{
-			result = chown(filename, uid, gid);
-		}
-	}
-
-	return result;
-}
-
 /* 
    Four cases:
     - change ownership of all files in directory (strip_fn=PR_FALSE)
@@ -258,7 +232,7 @@ chown_dir_files(char *name, struct passwd *pw, PRBool strip_fn)
     if((ptr=strrchr(log,'/'))==NULL)
     {
       LDAPDebug(LDAP_DEBUG_ANY, "Caution changing ownership of ./%s \n",name,0,0);
-      chown_if_not_owner(log, pw->pw_uid, -1 ); 
+      slapd_chown_if_not_owner(log, pw->pw_uid, -1 ); 
       rc=1;
     } else if(log==ptr) {
       LDAPDebug(LDAP_DEBUG_ANY, "Caution changing ownership of / directory and its contents to %s\n",pw->pw_name,0,0);
@@ -273,7 +247,7 @@ chown_dir_files(char *name, struct passwd *pw, PRBool strip_fn)
     while( (entry = PR_ReadDir(dir , PR_SKIP_BOTH )) !=NULL ) 
     {
 	PR_snprintf(file,MAXPATHLEN+1,"%s/%s",log,entry->name);
-	chown_if_not_owner( file, pw->pw_uid, -1 ); 
+	slapd_chown_if_not_owner( file, pw->pw_uid, -1 ); 
     }
     PR_CloseDir( dir );
   }
@@ -302,7 +276,7 @@ fix_ownership()
 	}
 
 	/* The instance directory needs to be owned by the local user */
-	chown_if_not_owner( slapdFrontendConfig->instancedir, pw->pw_uid, -1 );
+	slapd_chown_if_not_owner( slapdFrontendConfig->instancedir, pw->pw_uid, -1 );
 	PR_snprintf(dirname,sizeof(dirname),"%s/config",slapdFrontendConfig->instancedir);
 	chown_dir_files(dirname, pw, PR_FALSE); /* config directory */
 	chown_dir_files(slapdFrontendConfig->accesslog, pw, PR_TRUE); /* do access log directory */

+ 1 - 0
ldap/servers/slapd/proto-slap.h

@@ -588,6 +588,7 @@ void g_set_accesslog_level(int val);
  */
 void slapd_nasty(char* str, int c, int err);
 int strarray2str( char **a, char *buf, size_t buflen, int include_quotes );
+int slapd_slapd_chown_if_not_owner(const char *filename, uid_t uid, gid_t gid);
 
 /*
  * modify.c

+ 27 - 0
ldap/servers/slapd/util.c

@@ -631,3 +631,30 @@ strarray2str( char **a, char *buf, size_t buflen, int include_quotes )
 	return( rc );
 }
 /*****************************************************************************/
+
+/* Changes the ownership of the given file/directory if not
+   already the owner
+   Returns 0 upon success or non-zero otherwise, usually -1 if
+   some system error occurred
+*/
+int
+slapd_chown_if_not_owner(const char *filename, uid_t uid, gid_t gid)
+{
+        struct stat statbuf;
+        int result = 1;
+        if (!filename)
+                return result;
+
+        memset(&statbuf, '\0', sizeof(statbuf));
+        if (!(result = stat(filename, &statbuf)))
+        {
+                if (((uid != -1) && (uid != statbuf.st_uid)) ||
+                        ((gid != -1) && (gid != statbuf.st_gid)))
+                {
+                        result = chown(filename, uid, gid);
+                }
+        }
+
+        return result;
+}
+