[Fedora-directory-commits] ldapserver/ldap/servers/slapd proto-slap.h, 1.13, 1.14 util.c, 1.7, 1.8

Noriko Hosoi (nhosoi) fedora-directory-commits at redhat.com
Tue Jan 10 23:53:10 UTC 2006


Author: nhosoi

Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv4197

Modified Files:
	proto-slap.h util.c 
Log Message:
[174776] Multiple restores from a non-existant directory could wipe out database
If the specified backup dir does not exist, does not contain necessary files
(including the directory is not accessible), is not a directory, or is
identical to the path to the db dir, issues an error and stops restoring before
wiping out the database.



Index: proto-slap.h
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/proto-slap.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- proto-slap.h	3 Dec 2005 01:45:34 -0000	1.13
+++ proto-slap.h	10 Jan 2006 23:53:02 -0000	1.14
@@ -589,6 +589,8 @@
 void slapd_nasty(char* str, int c, int err);
 int strarray2str( char **a, char *buf, size_t buflen, int include_quotes );
 int slapd_chown_if_not_owner(const char *filename, uid_t uid, gid_t gid);
+int slapd_comp_path(char *p0, char *p1);
+
 
 /*
  * modify.c


Index: util.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/util.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- util.c	23 Nov 2005 17:58:01 -0000	1.7
+++ util.c	10 Jan 2006 23:53:02 -0000	1.8
@@ -44,6 +44,7 @@
 #include <unistd.h>
 #include <pwd.h>
 #endif
+#include <libgen.h>
 #include <pk11func.h>
 #include "slap.h"
 #include "prtime.h"
@@ -53,6 +54,14 @@
 #define UTIL_ESCAPE_HEX       1
 #define UTIL_ESCAPE_BACKSLASH 2
 
+#if defined( _WIN32 )
+#define _PSEP "\\"
+#define _CSEP '\\'
+#else
+#define _PSEP "/"
+#define _CSEP '/'
+#endif
+
 static int special_np(unsigned char c)
 {
 	if(c < 32 || c > 126) {
@@ -383,6 +392,60 @@
 	return 0; /* not an abs path */
 }
 
+static void
+clean_path(char **norm_path)
+{
+	char **np;
+
+	for (np = norm_path; np && *np; np++)
+		slapi_ch_free((void **)np);
+	slapi_ch_free((void  **)&norm_path);
+}
+
+static char **
+normalize_path(char *path)
+{
+    char *dname = slapi_ch_strdup(path);
+    char *dnamep = dname;
+    char *bnamep = NULL;
+    char **dirs = (char **)slapi_ch_calloc(strlen(path), 1);
+    char **rdirs = (char **)slapi_ch_calloc(strlen(path), 1);
+    char **dp = dirs;
+    char **rdp;
+    do {
+        bnamep = basename(dnamep);
+        if (0 != strcmp(bnamep, ".")) {
+            *dp++ = slapi_ch_strdup(bnamep);    /* remove "/./" in the path */
+        }
+        dnamep = dirname(dnamep);
+    } while (strcmp(dnamep, _PSEP) &&
+            !(0 == strcmp(dnamep, ".") && 0 == strcmp(bnamep, ".")));    
+
+    /* remove "xxx/.." in the path */
+    for (dp = dirs, rdp = rdirs; dp && *dp; dp++) {
+        while (*dp && 0 == strcmp(*dp, "..")) {
+            dp++; 
+            if (rdp > rdirs)
+                rdp--;
+        }
+        if (*dp)
+            *rdp++ = slapi_ch_strdup(*dp);
+    }
+    for (--dp, rdp = rdirs; dp >= dirs; dp--) {
+        while (*dp && 0 == strcmp(*dp, "..")) {
+            dp--; 
+            if (rdp > rdirs)
+                rdp--;
+        }
+        if (*dp)
+            *rdp++ = slapi_ch_strdup(*dp);
+    }
+
+    clean_path(dirs);
+    slapi_ch_free_string(&dname);
+
+    return rdirs;
+}
 
 /*
  * Take "relpath" and prepend the current working directory to it
@@ -399,13 +462,10 @@
    CHAR szDir[_MAX_DIR];
    CHAR szFname[_MAX_FNAME];
    CHAR szExt[_MAX_EXT];
-#define _PSEP "\\"
-#else
-#define _PSEP "/"
 #endif
 
     if ( relpath == NULL ) {
-	return NULL;
+        return NULL;
     }
 
 #if defined( _WIN32 )
@@ -413,41 +473,51 @@
     memset (&szDir, 0, sizeof (szDir));
     memset (&szFname, 0, sizeof (szFname));
     memset (&szExt, 0, sizeof (szExt));
-	_splitpath( relpath, szDrive, szDir, szFname, szExt );
-	if( szDrive[0] && szDir[0] )
-		return( slapi_ch_strdup( relpath ));
-    if ( relpath[ 0 ] == '/' || relpath[ 0 ] == '\\' ) {
-	return( slapi_ch_strdup( relpath ));
-#else
-    if ( relpath[ 0 ] == '/' ) {
-	return( slapi_ch_strdup( relpath ));
-    }
+    _splitpath( relpath, szDrive, szDir, szFname, szExt );
+    if( szDrive[0] && szDir[0] )
+        return( slapi_ch_strdup( relpath ));
 #endif
-
-    if ( getcwd( abspath, MAXPATHLEN ) == NULL ) {
-	perror( "getcwd" );
-	LDAPDebug( LDAP_DEBUG_ANY, "Cannot determine current directory\n",
-		0, 0, 0 );
-	exit( 1 );
-    }
-
-    if ( strlen( relpath ) + strlen( abspath ) + 1  > MAXPATHLEN ) {
-	LDAPDebug( LDAP_DEBUG_ANY, "Pathname \"%s" _PSEP "%s\" too long\n",
-		abspath, relpath, 0 );
-	exit( 1 );
+    if ( relpath[ 0 ] == _CSEP ) {     /* absolute path */
+        PR_snprintf(abspath, sizeof(abspath), "%s", relpath);
+    } else {                        /* relative path */
+        if ( getcwd( abspath, MAXPATHLEN ) == NULL ) {
+            perror( "getcwd" );
+            LDAPDebug( LDAP_DEBUG_ANY, "Cannot determine current directory\n",
+                    0, 0, 0 );
+            exit( 1 );
+        }
+    
+        if ( strlen( relpath ) + strlen( abspath ) + 1  > MAXPATHLEN ) {
+            LDAPDebug( LDAP_DEBUG_ANY, "Pathname \"%s" _PSEP "%s\" too long\n",
+                    abspath, relpath, 0 );
+            exit( 1 );
+        }
+    
+        if ( strcmp( relpath, "." )) {
+            if ( abspath[ 0 ] != '\0' &&
+                 abspath[ strlen( abspath ) - 1 ] != _CSEP )
+            {
+                PL_strcatn( abspath, sizeof(abspath), "/" );
+            }
+            PL_strcatn( abspath, sizeof(abspath), relpath );
+        }
     }
-
-    if ( strcmp( relpath, "." )) {
-#if defined( _WIN32 )
-	if ( abspath[ 0 ] != '\0' && abspath[ strlen( abspath ) - 1 ] != '/' && abspath[ strlen( abspath ) - 1 ] != '\\' )
-#else
-	if ( abspath[ 0 ] != '\0' && abspath[ strlen( abspath ) - 1 ] != '/' ) {
-#endif
-	    PL_strcatn( abspath, sizeof(abspath), "/" );
-	}
-	PL_strcatn( abspath, sizeof(abspath), relpath );
+    {
+        char **norm_path = normalize_path(abspath);
+        char *retpath = slapi_ch_strdup(abspath); /* size is long enough */
+        char **np, *rp;
+        int pathlen = strlen(abspath) + 1;
+        int usedlen = 0;
+        for (np = norm_path, rp = retpath; np && *np; np++) {
+            int thislen = strlen(*np) + 1;
+            if (0 != strcmp(*np, _PSEP))
+                PR_snprintf(rp, pathlen - usedlen, "%c%s", _CSEP, *np);
+            rp += thislen;
+            usedlen += thislen;
+        }
+        clean_path(norm_path);
+        return retpath;
     }
-    return( slapi_ch_strdup( abspath ));
 }
 
 
@@ -658,3 +728,20 @@
         return result;
 }
 
+/*
+ * Compare 2 pathes
+ * Paths could contain ".", "..", "//" in the path, thus normalize them first.
+ * One or two of the paths could be a relative path.
+ */
+int
+slapd_comp_path(char *p0, char *p1)
+{
+	int rval = 0;
+	char *norm_p0 = rel2abspath(p0);
+	char *norm_p1 = rel2abspath(p1);
+
+	rval = strcmp(norm_p0, norm_p1);
+	slapi_ch_free_string(&norm_p0);
+	slapi_ch_free_string(&norm_p1);
+	return rval;
+}




More information about the Fedora-directory-commits mailing list