--- ./old/src/ftpd.c	2011-08-30 14:15:27.581000028 +0530
+++ src/ftpd.c	2011-08-30 10:13:31.800000000 +0530
@@ -42,38 +42,33 @@
 #include <stdio.h>
 #include <ldap.h>
 
-LDAP* ldapHandle;
-
-int no_of_server = 0 ;
-#define FTP_RSN_PATH    "/var/opt/novell/pure-ftpd/"
+/*  Remote server navigation specific constants and strings  */
+#define	MOUNT_PATH	"/var/opt/novell/nclmnt"
+#define FTP_RSN_PATH    "/var/opt/novell/pure-ftpd"
 #define SERV_LIST_FILE "/var/opt/novell/pure-ftpd/server_list.txt"
+#define SITE_MSG	"NCP Servers in the NDS Tree"
 
-     
-
-// remote server navigation constants
-#define MAX_SERVER_SIZE 100
-#define MAX_SERVER_FDN_SIZE 300
-#define MAX_PATH_SIZE 1000
 #define MAX_IP_SIZE 20
-#define MAX_NO_OF_SERVERS 300
-#define SITE_MSG "NCP Servers in the NDS Tree"
 #define CHK_MOD_TIME 3600
-
-#define USER_FDN_SIZE 512 
 #define OES_DIR_MASK  0022
 #define OES_FILE_MASK 0133
+#define USER_FDN_SIZE		512 
+#define MAX_PATH_SIZE		1000
+#define MAX_SERVER_SIZE		100
+#define	MOUNT_PATH_SIZE		22
+#define MAX_SERVER_FDN_SIZE	300
+#define MAX_NO_OF_SERVERS	300
 
 
+char	userFDN[USER_FDN_SIZE];
 char serverInfo[MAX_NO_OF_SERVERS][120]; 
-const char MOUNT_PATH[] = "/var/opt/novell/nclmnt";
-const int MOUNT_PATH_SIZE = 22;
+int 	no_of_server = 0 ;
+char	*userName = NULL;
+LDAP	*ldapHandle = NULL;
 	
-char userFDN[USER_FDN_SIZE];
-static char *userName = NULL;
-static const char *getlocalhostname();
-void extractEdir_IP_Port(char *);
 char* removeWhiteSpace(char *str);
-static const char *getUserNameByUID(const uid_t uid);
+char *getUserNameByUID (const uid_t uid);
+void extractEdir_IP_Port (char *);
 	  
 
 #ifndef HAVE_SYS_FSUID_H
@@ -1991,6 +1986,7 @@ void docwd(const char *dir)
 #endif
     const char *where;
     char buffer[MAXPATHLEN + 256U];
+	char	server[MAX_SERVER_SIZE] = {0}, nss_loc[MAX_PATH_SIZE] = {0};
 #ifdef WITH_RFC2640
     char *nwd = NULL;
 #endif
@@ -2048,17 +2044,16 @@ void docwd(const char *dir)
         return;
     }
 
-	char server[MAX_SERVER_SIZE],nss_loc[MAX_PATH_SIZE];
 	if(remote_server ==1 )
 	{	
-		// Not allowed to move inside the folder NCPVolForFTP
+		/*  Not allowed to move inside the NCP volumes folder for FTP  */
 		if (strstr(where,"nclmnt") != NULL)
 			goto cd_success;
 
 		if(NULL == getcwd(wd, sizeof wd - (size_t) 1U))
 			logfile(LOG_ERR," Get current working directory failed");	
 
-		// cd .. is not allowed from base remote dir
+		/*  cd.. is not allowed from base remote dir  */
 		if( (wd != NULL) && (strcmp(where,"..") == 0))
 		{	
 			if(strncasecmp(wd,MOUNT_PATH,MOUNT_PATH_SIZE) ==0)
@@ -2070,11 +2065,11 @@ void docwd(const char *dir)
 
 		get_remote_server_path(wd);
 
-		//mount remote server
+		/*  Mount remote server  */
 		if ( mount_remote_server(where,nss_loc,server) == 0 )	
 			where = nss_loc;	
-
 	} 	
+
     if (chdir(where) != 0) {
         
 #ifdef WITH_DIRALIASES
@@ -6094,35 +6089,26 @@ int main(int argc, char *argv[])
 
     return 0;
 }
+
 #include <stdlib.h>
 #include <dlfcn.h>
 #include <string.h>
 
 int (*namGetUserFDNfromUID)    (int uid, char * userFDN);
 
-static const char *getlocalhostname()
-{
-	static char buf[1025];
-
-	if (gethostname(buf, sizeof buf - 1U) != 0) {
-		snprintf(buf,sizeof(buf),"127.0.0.1");
-	}
-	return buf;
-}
 
 int edir_login(const char* user,const char* passwd,int uid)
 {
-	int srcIndex =0,destIndex=0,openCount = 0;
-	char tmp[MAX_PATH_SIZE+100];
+	char		tmp[MAX_PATH_SIZE + 100], fdn[512] = {0}, buff[1000] = {0};	
+	int		update = 1, pid = 0, srcIndex = 0, destIndex = 0, openCount = 0, n = 0, status = 0, error = 0, pFD[2];
 	FILE* fd = NULL;
-	char fdn[512];fdn[0] = '\0' ;	
-	struct stat buf;
-	int update = 1,pid = 0;
+	void		*lumHandle = NULL;
 	time_t curr_time;
+	struct stat	buf;
 
 	
-	// get the FDN of user from libnam_misc.so
-	void * lumHandle =  dlopen("/usr/lib64/libnam_misc.so", RTLD_LAZY);
+	/*  Get the FDN of the user from pam_nam.so  */
+	lumHandle =  dlopen ("/usr/lib64/libnam_misc.so", RTLD_LAZY);
 	if (lumHandle == NULL)
 		lumHandle =  dlopen("/usr/lib/libnam_misc.so", RTLD_LAZY);
 	if(lumHandle != NULL)
@@ -6130,22 +6116,29 @@ int edir_login(const char* user,const ch
 		namGetUserFDNfromUID = (int (*)(int, char *))dlsym(lumHandle, "namGetUserFDNfromUID");
 		if(namGetUserFDNfromUID != NULL)
 		{	 
-			int error = namGetUserFDNfromUID(uid, fdn);
-			sprintf(tmp,"namGetUserFDNfromUID for uid %d return %d",uid,error);
+			if ((error = namGetUserFDNfromUID (uid, fdn)))
+				snprintf (tmp, sizeof (tmp), "UserFDNfromUID: Failed to get user FDN for UID: %d, Error: %d", uid, error);
+			else
+				snprintf (tmp, sizeof (tmp), "UserFDNfromUID: User FDN: %s, UID: %d", fdn, uid);
+
 			logfile(LOG_DEBUG,tmp);
-		} else			
-			logfile(LOG_ERR,"Function namGetUserFDNfromUID not found");
-		dlclose(lumHandle);
-	} else
-		logfile(LOG_ERR,"PAM library not found");
+		}
+		else
+			logfile (LOG_ERR, "Failed to find the function namGetUserFDNfromUID in the PAM NAM library");
 
+		dlclose (lumHandle);
+	}
+	else
+	{
+		logfile (LOG_ERR, "Failed to find PAM library");
+		return -1;
+	}
 
-	//copy user name provided by the ftp client incase pam_nam.so does not provide FDN of user
+	/*  Copy user name provided by the ftp client incase nam_misc.so does not provide FDN of user  */
 	if (fdn[0] == '\0')
 		strncpy(fdn,user,sizeof(fdn));
 
-
-	//Convert . separared user FDN to ldap formated(, separated) user FDN
+	/*  Convert , separared user FDN to . separated user FDN  */
 	while (fdn[srcIndex] != '\0')
 	{
 		if(strncasecmp(&fdn[srcIndex],",st=",4) == 0)
@@ -6153,7 +6146,9 @@ int edir_login(const char* user,const ch
 			strncpy(&userFDN[destIndex],".s=",3);
 			srcIndex += 4;
 			destIndex += 3;
-		} else {
+		} 
+		else
+		{
 			if(fdn[srcIndex] != ',')
 				userFDN[destIndex] = fdn[srcIndex];
 			else	
@@ -6162,32 +6157,38 @@ int edir_login(const char* user,const ch
 			++destIndex;
 		}
 	}
+
 	userFDN[destIndex] = '\0';
 		
-	/*
-	   do nwlogin the local server.Same nw connection is reused for connecting to different machine.
-	 */  
- //   snprintf(tmp,sizeof(tmp),"su '%s'  /opt/novell/ncl/bin/nwlogin  -s '%s' -u '%s' -p '%s' -c x > /dev/null",user,hostname,userFDN,passwd );
-  //  system(tmp);
+	if (pipe (pFD) < 0)
+	{
+		logfile (LOG_ERR, "Failed to open an IPC channel to perform authentication of the user: %s", userFDN);
+		return -1;
+	}		
+
+	/*  Do nwlogin to the local server. Same connection is reused for connecting to the remote server  */  
    
 	if( (pid = fork()) == 0)
 	{	
-		// calling nwlogin from system command put password in /var/log/message 
-		
 		char* data[9];
-		char* context;
+		char	context[MAX_SERVER_FDN_SIZE] = {0};
 		char tree[MAX_SERVER_FDN_SIZE] = {0};
 		char server[MAX_SERVER_FDN_SIZE] = {0};
 
-		context = index(userFDN,'.');
-		if(context != NULL)
-			context++;
 
-		if(context == NULL)
+		if (dup2 (pFD[1], STDERR_FILENO) < 0)
+		{
+			logfile (LOG_ERR, "Failed to re-direct stderr of child to parent during authentication. Error: %d", errno);
+			exit (EXIT_FAILURE);
+		}   
+
+		close (pFD[0]);
+		close (pFD[1]);
+
+		if (getUserContext (userFDN, context))
 		{	
-			snprintf(tmp,sizeof(tmp),"no context for user %s",userFDN);
-			logfile(LOG_ERR,tmp);
-			exit(0);
+			logfile (LOG_ERR, "No context provided for user: %s", userFDN);
+			exit (EXIT_FAILURE);
 		}	
 		
 		snprintf(tree,sizeof(tree),"-t %s",edir_ip_address);
@@ -6195,33 +6196,87 @@ int edir_login(const char* user,const ch
 
 		data[0] =tree;
 		data[1] =server;
-		data[2] ="-u" ; data[3] = (char*)user;
-		data[4] ="-c" ; data[5] = (char*)context;
-		data[6] ="-p" ; data[7] = (char*)passwd;
+		data[2] = "-u";
+		data[3] = (char *)user;
+		data[4] = "-c" ;
+		data[5] = (char *)context;
+		data[6] = "-p";
+		data[7] = (char *)passwd;
 		data[8] =NULL;
 		
-		snprintf(tmp,sizeof(tmp),"nwlogin -u %s uid %d context %s",userFDN,uid,context);
-		logfile(LOG_DEBUG,tmp);
+		logfile (LOG_DEBUG, "nwlogin -u %s uid %d context %s", userFDN, uid, context);
 
 		setuid(uid);
 		seteuid(uid);
-		//redirect all nwlogin output to /dev/null to aviod sending wrong response to ftp client
+
+		/*  
+		 *  In case login succeeds, nwlogin returns output to stdout else returns error to stderr.
+		 *  So, redirect all nwlogin stdout output to /dev/null and stderr output to parent to log
+		 * */
 		stdout = freopen("/dev/null", "w", stdout);
-    		execv("/opt/novell/ncl/bin/nwlogin",data); 
-		exit(0);
-	} else
-		waitpid(pid,NULL,0);
 
-	//create directories to store no of simultaneous logins by same user
+		if (execv ("/opt/novell/ncl/bin/nwlogin", data) < 0)
+		{
+			logfile (LOG_ERR, "Failed to perform authentication of the user: %s. Error: %d", userFDN, errno);
+			exit (EXIT_FAILURE);
+		}	
+
+            	exit (EXIT_SUCCESS);
+	}
+	else
+	{
+		close (pFD[1]);
+
+		if (waitpid (pid, &status, (WUNTRACED | WCONTINUED)) < 0)
+		{
+			logfile (LOG_ERR, "Failed to wait for the execution of login command. Error: %d", status);
+			return -1;
+		}
+
+		n = 0;
+		memset (buff, '\0', 1000);
+		if ((n = read (pFD[0], buff, sizeof (buff))) < 0)
+		{
+			logfile (LOG_ERR, "Failed to read error information during authentication. Error: %d", errno);
+		}
+
+		if (n >= 1)
+		{
+			buff[n-1] = '\0';
+			logfile (LOG_ERR, "Failed to perform authentication. Error: %s", buff);
+		}
+
+		if (WIFEXITED(status))
+		{
+			if ((n = WEXITSTATUS(status)))
+			{
+				logfile (LOG_ERR, "User authentication status: %d", n);
+				return -1;
+			}
+		}
+		else if (WIFSIGNALED(status))
+		{
+			logfile (LOG_ERR, "User authentication killed by signal: %d", WTERMSIG(status));
+			return -1;
+		}
+		else if (WIFSTOPPED(status))
+		{
+			logfile (LOG_ERR, "User authentication stopped: %d", WSTOPSIG(status));
+			return -1;
+		}
+		else if (WIFCONTINUED(status))
+		{
+			logfile (LOG_ERR, "User authentication continued");
+		}		
+	}
+
+	/*  Create directories to store no of simultaneous logins by same user  */
 	snprintf(tmp,sizeof(tmp),"%s/%s",FTP_RSN_PATH,account);
 	mkdir(tmp, (mode_t) 0777 & ~OES_DIR_MASK);
 	chown(tmp,uid,(gid_t)0);
 	
 	snprintf(tmp,sizeof(tmp),"%s/%s/count.txt",FTP_RSN_PATH,account);
-	fd = fopen(tmp,"r+");
-	
-	openCount = 1;
-	if(fd != NULL)
+	if ((fd = fopen (tmp, "r+")) != NULL)
 	{
 		if(fread(&openCount,sizeof(int),1,fd) > 0)
 		{
@@ -6229,19 +6284,26 @@ int edir_login(const char* user,const ch
 				++openCount;
 			else
 				openCount = 1;
-		} else
+		}
+		else
 			 openCount = 1;
+
 		fclose(fd);	
-	} else
+	}
+	else
 		openCount = 1;
 
 	snprintf(tmp,sizeof(tmp),"%s/%s/count.txt",FTP_RSN_PATH,account);
-	fd = fopen(tmp,"w+");
-	if(fd != NULL)
+	if ((fd = fopen (tmp, "w+")) != NULL)
 	{
 		chmod(tmp,(mode_t) 0777 & ~OES_FILE_MASK);
 		chown(tmp,uid,(gid_t)0);
-		fwrite(&openCount,sizeof(int),1,fd);
+		
+		if (fwrite (&openCount, sizeof (int), 1, fd) < 0)
+		{
+			logfile (LOG_ERR, "Failed to write the current open count to file");
+		}
+		
 		fclose(fd);	
 	}
 
@@ -6255,103 +6317,87 @@ int edir_login(const char* user,const ch
 		}	
 	}	
 			
-	if( (update != 0) || (get_server_list_from_file() < 0))
+	if ((ldap_connect (fdn, passwd) >= 0))
 	{
-		logfile(LOG_DEBUG,"refresh the server-ip cache");
-		if(fork() == 0)
+		if ((update != 0) || (get_server_list_from_file() < 0))
 		{
-			ldap_connect(fdn,passwd);
+			logfile (LOG_DEBUG, "Reloading remote server information");
+		
 			get_server_list_from_edir();
-			if(ldapHandle != NULL)
-				ldap_unbind(ldapHandle);
-			exit(0);
 		}	
 	}
-
-	ldap_connect(fdn,passwd);
-	
 	return 0;
 }
 
+
 int mount_remote_server(const char* where,char* nss_loc,char* remote_server)
 {
-	char tmp[2*MAX_PATH_SIZE] = {0},path[MAX_PATH_SIZE] = {0};
-	char* str1,*server;
+	char		*server = NULL, *context = NULL, *userNameWithSpace = NULL;
+	char		path[MAX_PATH_SIZE] = {0}, ip[MAX_IP_SIZE] = {0};
+	char		buff[1000] = {0}, mnt_loc[MAX_SERVER_SIZE] = {0}, ncl_req_name[MAX_SERVER_SIZE] = {0};
+	int		pid = 0, ret = 0, status = 0, i = 0, pFD[2];
+	struct in_addr	addr, ipv4addr;
 	struct hostent *he;
-	struct in_addr ipv4addr;
-	//mnt_loc         - mounted path name by novell client (server name)
-	//ncl_req_name    - Request used in novell client (IP - preferably) 
-	char mnt_loc[MAX_SERVER_SIZE] ={0},ncl_req_name[MAX_SERVER_SIZE] = {0},ip[MAX_IP_SIZE] = {0};
-	struct in_addr addr;	
-	char*  context = NULL;
-	int pid = 0,ret =0,status = 0,i = 0;
-	// Get user Name for NWLOGIN
-	char *userNameWithSpace =  getUserNameByUID(authresult.uid);
+
+
+	userNameWithSpace =  getUserNameByUID (authresult.uid);		// Get user Name for nwlogin	
 	
 	userName = removeWhiteSpace(userNameWithSpace);
 	if (NULL == userName)
-	{
 		userName = account;
-	}
 	
 	if((where != NULL ) && (strncmp(where,"//",2 ) ==0) && (strlen(where) > 2) )
 	{
+		/*  Remote server name in FTP request can be either server name / DNS name / IP address  */   
+		memset (mnt_loc, 0, sizeof (mnt_loc));  
+		memset (ncl_req_name, 0, sizeof (ncl_req_name)); 
 
 		if( no_of_server <= 0) 
 			get_server_list_from_file(); 
 
-		//Get the remote oes server path excluding server name
-		snprintf(path,sizeof(path),index(where+2, '/'));
-		
-		//Get the server name from remote oes path
-		str1 = (char*) where+2;
-		server = strtok(str1,"/");
-
-		if ( NULL == server)
-		{
+		/*  Get the server name from remote server path  */
+		if ((server = strtok ((char *) (where + 2), "/")) == NULL)
 			return -1;
-		}
 
-		/*
-		   Get the server name/ip address of remote server
-		   Remote server name in ftp request can be either server name / DNS name / IP
-		*/   
-		memset(mnt_loc,0,sizeof(mnt_loc));  
-		memset(ncl_req_name,0,sizeof(ncl_req_name)); 
+		/*  Get the remote server path excluding server name  */
+		snprintf (path, sizeof (path), index (server, '/'));		
+
+		/*  FTP request is with IP address  */
 		if(inet_pton(AF_INET, server, &ipv4addr) > 0)
 		{	
-			// ftp request is with IP (server = ip )
 			snprintf(ncl_req_name,sizeof(ncl_req_name),"%s",server);
-			if(0 != get_server(server,mnt_loc))
+
+			if (get_server (server, mnt_loc) != 0)
 			{	
-				// IP is not available in server list. Use dns name as shared folder
-				he = gethostbyaddr(&ipv4addr, sizeof ipv4addr, AF_INET);
+				/*  IP is not available in server list. Use DNS name as shared folder  */
+				he = gethostbyaddr (&ipv4addr, sizeof (ipv4addr), AF_INET);
 				if(he != NULL)
 					server = strtok(he->h_name,".");
+			
 				snprintf(mnt_loc,sizeof(mnt_loc),"%s",server);
 			}	
-			
-		} else 
+		}
+		else
 		{
-			// ftp request is with server name / dns name
+			/*  FTP request is with server name / DNS name  */
 			snprintf(mnt_loc,sizeof(mnt_loc),"%s",server);
 
-			if(0 != get_ip(server,ncl_req_name))
+			if ((get_ip (server, ncl_req_name) != 0) || (strlen (ncl_req_name) == 0))
 			{
-				// Server name is not available in cache. request name can be dns name
+				/*  Server name is not available in cache, requested name can be DNS name  */
 				snprintf(ncl_req_name,sizeof(ncl_req_name),"%s",server);
+				
 				he = gethostbyname(server);
 				if(he != NULL)
 				{
 					i = 0;
 					while (he->h_addr_list[i] != 0) 
 					{
-						
 						   addr.s_addr = *(u_long *) he->h_addr_list[i++];
 				           snprintf(ip,sizeof(ip),"%s", inet_ntoa(addr));
+					
 						   if(get_server(ip,mnt_loc) == 0 )
 						   {
-							   
 								snprintf(ncl_req_name,sizeof(ncl_req_name),"%s",ip);
 								break;
 						   }	   
@@ -6360,24 +6406,33 @@ int mount_remote_server(const char* wher
 			}	
 		}	
 		
-
 		if(remote_server != NULL )
 			strncpy(remote_server,mnt_loc, MAX_SERVER_SIZE);
 
 		context = index(userFDN,'.');
 		if(context != NULL)
 			context++;
+
 		if(context == NULL)
 			context = "x";
 			
-		/*
-		 * nwlogin as logged in ftp user. 
-		 * nwlogin does not require password here. novell client reuses exising connection
-		 */		
+		if (pipe (pFD) < 0)
+		{
+			logfile (LOG_ERR, "Failed to open an IPC channel to perform remote server authentication of the user: %s", userFDN);
+			return -1;
+		}		
 
-		pid = fork();
-		if (!pid)
+		/*  Login as the already logged in FTP user. nwlogin does not require password here. Novell client reuses exising connection  */
+		if ((pid = fork()) == 0)
+		{
+			if (dup2 (pFD[1], STDERR_FILENO) < 0)
        		{
+				logfile (LOG_ERR, "Failed to re-direct stderr of child to parent during remote server authentication. Error: %d", errno);
+				return -1;
+			}   
+
+			close (pFD[0]);
+			close (pFD[1]);
 			
 			 setuid(authresult.uid);
 		         seteuid(authresult.uid);
@@ -6385,29 +6440,65 @@ int mount_remote_server(const char* wher
 	                //redirect all nwlogin output to /dev/null to aviod sending wrong response to ftp client
         	        stdout = freopen("/dev/null", "w", stdout);
 
-               		ret = execl("/opt/novell/ncl/bin/nwlogin","nwlogin","-s",ncl_req_name,"-u",userName,"-c",context,"-p","x",NULL );
-	              	if (ret != 0)
+			if (execl ("/opt/novell/ncl/bin/nwlogin", "nwlogin", "-s", ncl_req_name, "-u", userName, "-c", context, "-p", "x", NULL) != 0)
 		{
-				snprintf(tmp,sizeof(tmp),"Novell Client Login Failed with error %d ",errno);
-			logfile(LOG_ERR,tmp);
-        	               	exit(0);
+				logfile (LOG_ERR, "Failed to perform remote server authentication of the user: %s. Error: %d", userFDN, errno);
+				return -1;
                 	}
         	}
 		else
 		{
-                	waitpid(pid,&status,0);
-			if (status != 0)
+			close (pFD[1]);
+			
+			memset (buff, '\0', 1000);
+			if ((ret = read (pFD[0], buff, sizeof (buff))) < 0)
 			{
-				snprintf(tmp,sizeof(tmp),"Novell Client Login Failed with error %d ",status);
-				logfile(LOG_ERR,tmp);
+				logfile (LOG_ERR, "Failed to read error information during remote server authentication. Error: %d", errno);
 			}
+
+			if (ret >= 1)
+			{
+				buff[ret-1] = '\0';
+				logfile (LOG_ERR, "Failed to perform remote server authentication. Error: %s", buff);
+			}
+			
+			if (waitpid (pid, &status, (WUNTRACED | WCONTINUED)) < 0)
+			{
+				logfile (LOG_ERR, "Failed to wait for the execution of remote server login command. Error: %d", status);
+				return -1;
+			}
+
+			if (WIFEXITED(status))
+			{
+				if ((ret = WEXITSTATUS(status)))
+				{
+					logfile (LOG_ERR, "Remote server authentication status: %d", ret);
+					return -1;
+				}
+			}
+			else if (WIFSIGNALED(status))
+			{
+				logfile (LOG_ERR, "Remote server authentication killed by signal: %d", WTERMSIG(status));
+				return -1;
+			}
+			else if (WIFSTOPPED(status))
+			{
+				logfile (LOG_ERR, "Remote server authentication stopped: %d", WSTOPSIG(status));
+				return -1;
+			}
+			else if (WIFCONTINUED(status))
+			{
+				logfile (LOG_ERR, "Remote server authentication continued");
+				return -1;
+			}
+
+			logfile (LOG_DEBUG, "User: %s logged into remote server: %s", userName, remote_server);
 		}
 		
 		if(nss_loc != NULL)
 			snprintf(nss_loc,MAX_PATH_SIZE,"%s/%s/%s/%s",MOUNT_PATH,userName,mnt_loc,path);
 	
-		snprintf(tmp,sizeof(tmp),"ncl mount point:%s ftp request server name:%s ncl request server name:%s\n",nss_loc,remote_server,ncl_req_name);
-		logfile(LOG_DEBUG,tmp);
+		logfile (LOG_DEBUG, "NCL mount point: %s, Remote server name: %s, IP: %s", nss_loc, remote_server, ncl_req_name);
 
 		return 0;
 	}  else
@@ -6417,18 +6508,28 @@ int mount_remote_server(const char* wher
 
 int umount_remote_server()
 {
-	char tmp[MAX_PATH_SIZE+100];
-	int openCount = 0;
+	char	tmp[MAX_PATH_SIZE+100] = {0}, buff[1000] = {0};
+	int	openCount = 0, pid = 0, ret = 0, status = 0, pFD[2];	
 	FILE* fd = NULL;
 	
+	
 	if (NULL == userName)
-	{
 		userName=account;
+	
+	/*  Close the LDAP handle associated to this authenticated user before performing logout  */
+	if (ldapHandle)
+	{
+		ldap_unbind (ldapHandle);
+		ldapHandle = NULL;
+	}
+	else
+	{
+		logfile (LOG_DEBUG, "No user exists with name: %s to logout", userName);
+		return -1;	
 	}
 	
 	snprintf(tmp,sizeof(tmp),"%s/%s/count.txt",FTP_RSN_PATH,account);
-	fd = fopen(tmp,"r+");
-	if(fd != NULL)
+	if ((fd = fopen (tmp, "r+")) != NULL)
 	{
 		if(fread(&openCount,sizeof(int),1,fd) > 0)
 		{
@@ -6436,54 +6537,109 @@ int umount_remote_server()
 				--openCount;
 			else
 				openCount = 0;
-		} else
+		}
+		else
 			openCount = 0;
 			
 		fclose(fd);	
 		
 		fd = fopen(tmp,"w+");
 		chmod(tmp,(mode_t) 0777 & ~OES_FILE_MASK);
-		fwrite(&openCount,sizeof(int),1,fd);
+
+		if (fwrite (&openCount, sizeof (int), 1, fd) < 0)
+		{
+			logfile (LOG_ERR, "Failed to write the current open count to file");
+		}
+
 		fclose(fd);	
-	} else	
-		logfile(LOG_ERR,"File Open failed tmp:[%s] errno:[%s] uid:[%d] eid:[%d]",tmp,strerror(errno),getuid(),geteuid());
+	}
+	else	
+		logfile (LOG_ERR, "Failed to open file: %s, Error: %s, uid: %d, eid: %d", tmp, strerror (errno), getuid(), geteuid());
 	
-	//nwlogout is not called when same ftp user is logged in more than once
+	/*  nwlogout is not called when same ftp user is logged in more than once  */
 	if(openCount <= 0)	
 	{	
-		int pid = 0,ret = 0,status = 0;	
+		if (pipe (pFD) < 0)
+		{
+			logfile (LOG_ERR, "Failed to open an IPC channel to perform user logout: %s", userFDN);
+			return -1;
+		}		
 
-		pid = fork();
-                if (!pid)
+                if ((pid = fork()) == 0)
+                {
+			if (dup2 (pFD[1], STDERR_FILENO) < 0)
                 {
+				logfile (LOG_ERR, "Failed to re-direct stderr of child to parent during user logout. Error: %d", errno);
+				exit (EXIT_FAILURE);
+			}   
+
+			close (pFD[0]);
+			close (pFD[1]);
+
                 	setuid(authresult.uid);
                 	seteuid(authresult.uid);
 
-                        //redirect all nwlogout output to /dev/null to aviod sending wrong response to ftp client
+                        /*  Redirect all nwlogout output to /dev/null to aviod sending wrong response to FTP client  */
                         stdout = freopen("/dev/null", "w", stdout);
 
-			ret = execl("/opt/novell/ncl/bin/nwlogout","nwlogout","-f","-a",NULL );
-                        if (ret != 0)
+			if (execl ("/opt/novell/ncl/bin/nwlogout", "nwlogout", "-a", NULL) < 0)
                         {
-                                snprintf(tmp,sizeof(tmp),"Novell Client Logout Failed with error %d ",errno);
-                                logfile(LOG_ERR,tmp);
-                                exit(0);
+                                logfile (LOG_ERR, "Failed to perform logout of the user: %s. Error: %d", userName, errno);
+				exit (EXIT_FAILURE);
                         }
+			
+			exit (EXIT_SUCCESS);
 		}
 		else
                 {
-                        waitpid(pid,&status,0);
-                        if (status != 0)
+			close (pFD[1]);
+
+			if (waitpid (pid, &status, (WUNTRACED | WCONTINUED)) < 0)
+			{
+				logfile (LOG_ERR, "Failed to wait for the execution of user logout process. Error: %d", status);
+				return -1;
+			}
+
+			if (WIFEXITED(status))
+			{
+				if ((ret = WEXITSTATUS(status)))
+				{
+					logfile (LOG_ERR, "User logout process status: %d", ret);
+				}
+			}
+			else if (WIFSIGNALED(status))
+			{
+				logfile (LOG_ERR, "User logout process was killed by signal: %d", WTERMSIG(status));
+			}
+			else if (WIFSTOPPED(status))
+			{
+				logfile (LOG_ERR, "User logout process was stopped: %d", WSTOPSIG(status));
+			}
+			else if (WIFCONTINUED(status))
+			{
+				logfile (LOG_ERR, "User logout process continued");
+			}
+
+			memset (buff, '\0', 1000);
+			if ((ret = read (pFD[0], buff, sizeof (buff))) < 0)
+			{
+				logfile (LOG_ERR, "Failed to read error information returned by user logout process. Error: %d", errno);
+				return -1;
+			}
+
+			if (ret >= 1)
                         {
-                                snprintf(tmp,sizeof(tmp),"Novell Client Logout Failed with error %d ",status);
-                                logfile(LOG_ERR,tmp);
+				buff[ret-1] = '\0';
+				logfile (LOG_ERR, "Failed to logout the user. Error: %s", buff);
 				return -1;
                         }
                 }
 	}	
+	
 	return 0;
 }
 
+
 int get_remote_server_path(char* path)
 {	
 	char tmp[MAX_PATH_SIZE] = {0};
@@ -6491,20 +6647,19 @@ int get_remote_server_path(char* path)
 	if (path == NULL)
 		return -1;
 
-	// Send the remote dir location as reply	
+	/*  Send the remote dir location as reply  */
 	if( strncasecmp(path,MOUNT_PATH,MOUNT_PATH_SIZE) == 0)
 	{
 		snprintf(tmp,sizeof(tmp),"//%s",path+MOUNT_PATH_SIZE+1+strlen(account)+1);
 		strncpy(path,tmp,MAX_PATH_SIZE);
 	}	
 	else
-	{
 		return -1;
-	}
 	
 	return 0;
 }	
 
+
 /**
  * Description: This function is used to extract E-directory IP address
  * and Port number.
@@ -6567,19 +6722,15 @@ static int getModTime(char *fileName)
 
 /** 
  * Description: This function is used to response for site slist command.
- *
  * Input: None
- *
  * Output: integer which return the status
- *
  */
 int do_list_servers()
 {
-	FILE* file;
-	char buffer[2*MAX_SERVER_FDN_SIZE];
-	int serverLen;
-	char server[MAX_SERVER_FDN_SIZE + 2],countMsg[MAX_SERVER_FDN_SIZE +1]={0},*ip;
-	int nodeCount= 0;
+	FILE	*file = NULL;
+	char	buffer[2*MAX_SERVER_FDN_SIZE] = {0}, server[MAX_SERVER_FDN_SIZE + 2] = {0}, countMsg[MAX_SERVER_FDN_SIZE +1] = {0}, *ip = NULL;
+	int	serverLen = 0, nodeCount = 0;
+
 	
 	if( (( no_of_server <= 0) && (get_server_list_from_file() < 0)) || (getModTime(SERV_LIST_FILE) >= CHK_MOD_TIME))
 		 get_server_list_from_edir();
@@ -6618,61 +6769,53 @@ int do_list_servers()
 	addreply_noformat(200, countMsg);
 
 	return 0;
-	
 }
 
 				  
 int ldap_connect(const char* username,const char*passwd)
 {	
-    	ldapHandle = ldap_init(edir_ip_address,edir_ldap_port);
-    	if (ldapHandle == NULL)
+	if ((ldapHandle = ldap_init (edir_ip_address, edir_ldap_port)) == NULL)
     	{
+		logfile (LOG_ERR, "Failed to initialize the LDAP library. Error: %s <%d>", strerror (errno), errno);
 			return -1;
 		}
 
 		ldap_simple_bind_s(ldapHandle,username,passwd);
+
 		return 0;
 }
 
-/*
-   get list of server from edir and store in the file
-   File format : server name#IP$
-*/   
+
+/*  Get list of servers from edir and store in the file. Format: server name#IP$  */   
 int get_server_list_from_edir()
 {	
-        //create server list
+	int		i = 0, rc = 0;
+	char 		buffer[2*MAX_SERVER_FDN_SIZE] = {0}, temp[2*MAX_SERVER_FDN_SIZE] = {0};
         char* attrs[]={"networkAddress",NULL};
-        char* ldapDN,*attribute;
-        LDAPMessage* entry = NULL;
-        LDAPMessage* searchResult = NULL;
-	BerElement *ber;
-	char **vals;
-	int i = 0 ;
-	struct timeval timeval;
-	timeval.tv_sec = 1200; 
+	char		*ldapDN = NULL, *attribute = NULL, **vals = NULL;
 	FILE* file = NULL;
-	char buffer[2*MAX_SERVER_FDN_SIZE],temp[2*MAX_SERVER_FDN_SIZE];
-	char tmp[MAX_PATH_SIZE+1000];
+	BerElement	*ber = NULL;
+	LDAPMessage	*entry = NULL, *searchResult = NULL;
+	struct timeval	timeval;
 		
-	get_server_list_from_file();
 			
-        if (ldapHandle == NULL)
+	/*  Set the number of remote servers as 0  */
+	no_of_server = 0;
+		
+	timeval.tv_sec = 1200; 
+	
+	if ((rc = ldap_search_ext_s (ldapHandle, "", LDAP_SCOPE_SUBTREE, "(&(objectclass=NCP Server))", attrs, 0, NULL, NULL, &timeval, 0, &searchResult)) == LDAP_SUCCESS)
         {
-                 logfile(LOG_ERR,"LDAP connection is not available");
+		if ((file = fopen (SERV_LIST_FILE, "w+")) == NULL)
+		{
+			logfile (LOG_ERR, "Failed to open remote server list file while trying to search in eDirectory: %s <%d>", strerror (errno), errno);
                  return -1;
         }
-        int rc = ldap_search_ext_s(ldapHandle,"",LDAP_SCOPE_SUBTREE,"(&(objectclass=NCP Server))",
-						attrs,  0,NULL, NULL, &timeval, 0, &searchResult);
 		
-	no_of_server = 0;
-	if(rc == LDAP_SUCCESS )
-	{
-		file = fopen (SERV_LIST_FILE,"w+"); 
 		chmod(SERV_LIST_FILE,(mode_t) 0777 & ~OES_FILE_MASK);
-		for(entry = ldap_first_entry(ldapHandle,searchResult) ; entry != NULL ;
-				entry = ldap_next_entry(ldapHandle,entry))
-	    	    {
 	
+		for (entry = ldap_first_entry (ldapHandle, searchResult); entry != NULL; entry = ldap_next_entry (ldapHandle, entry))
+		{
 					if((ldapDN = ldap_get_dn(ldapHandle,entry)) != NULL )
 					{	
 						strncpy(temp,ldapDN,sizeof(temp));
@@ -6680,8 +6823,8 @@ int get_server_list_from_edir()
 						snprintf(serverInfo[no_of_server],MAX_SERVER_SIZE,"%s",strtok_r(temp+3,"," , (char**)&buffer));
 					} else 	
 					    continue;
-					for (attribute = ldap_first_attribute (ldapHandle, entry, &ber); attribute != NULL;
-		                    		attribute = ldap_next_attribute (ldapHandle, entry, ber))
+
+			for (attribute = ldap_first_attribute (ldapHandle, entry, &ber); attribute != NULL; attribute = ldap_next_attribute (ldapHandle, entry, ber))
 					{
 						if ((vals = ldap_get_values (ldapHandle, entry, attribute)) != NULL)
 						{
@@ -6690,14 +6833,21 @@ int get_server_list_from_edir()
 								if(strncmp(vals[i],"8#",2) == 0)
 								{	
 									snprintf(&serverInfo[no_of_server][MAX_SERVER_SIZE],MAX_IP_SIZE,
-										"%d.%d.%d.%d",0xFF & vals[i][4],0xFF & vals[i][5], 0xFF & vals[i][6], 0xFF & vals[i][7]);
+									"%d.%d.%d.%d", (0xFF & vals[i][4]), (0xFF & vals[i][5]), (0xFF & vals[i][6]), (0xFF & vals[i][7]));
 									break;
 								}
 							}	
+
 							ldap_value_free(vals);
 						}	
+				else
+				{
+					logfile (LOG_ERR, "Failed to get IP address of the remote server - %s", ldapDN);
+				}
+
 						ldap_memfree(attribute);
 					}
+
 					if ( ber != NULL ) 
 						 ber_free( ber, 0 );
 
@@ -6706,47 +6856,45 @@ int get_server_list_from_edir()
 						snprintf(buffer,sizeof(buffer),"%s#%s$\n",ldapDN,&serverInfo[no_of_server][MAX_SERVER_SIZE]);	
 						fputs(buffer,file);
 					}
+			
 					ldap_memfree( ldapDN );	
 					++no_of_server;
-				
 				}
-	} else
+	} 
+	else
 	{	
-		snprintf(tmp,sizeof(tmp),"ldap search failed with error code %d",rc);		
-		logfile(LOG_ERR,tmp);
-
+		logfile (LOG_ERR, "LDAP search search failed. Error: %s <%d>", ldap_err2string (rc), rc);		
 	}	
+	
 	if (file != NULL) 
 	{
 		fclose(file);
 	} 
 
-	if ( no_of_server > 0 )
-	{	
-		ldap_unbind(ldapHandle);
-		ldapHandle = NULL;
-	}	
+
 	return 0;
 }
 
-//create the server name / IP cache from file
+
+/*  Create the server name / IP cache from file  */
 int get_server_list_from_file()
 {
-	FILE* file;
-	char buffer[2*MAX_SERVER_FDN_SIZE],saveptr[2*MAX_SERVER_FDN_SIZE];
-	char* server,*ip;
-	file = fopen (SERV_LIST_FILE,"r"); 
+	FILE	*file = NULL;
+	char	buffer[2*MAX_SERVER_FDN_SIZE] = {0}, saveptr[2*MAX_SERVER_FDN_SIZE] = {0};
+	char	*server = NULL, *ip = NULL;
+
 	
 	no_of_server = 0;
+	
+	file = fopen (SERV_LIST_FILE, "r"); 
     if(file != NULL)
 	{	
 		while (!feof (file))
 		{
-			/*
-				data is stored in file in the format servername#IP$
-			*/   
+			/*  Data is stored in file in the format servername#IP$  */   
 			if (!fgets (buffer, 2*MAX_SERVER_FDN_SIZE, file))
 				    continue;
+
 			ip = strrchr(buffer,'#');
 			if(ip != NULL)
 			{	
@@ -6754,6 +6902,7 @@ int get_server_list_from_file()
 				if (ip!=NULL)
 					snprintf(&serverInfo[no_of_server][MAX_SERVER_SIZE],MAX_IP_SIZE,ip);
 			}	
+			
 			server = strtok_r(buffer+3,"," , (char**)&saveptr);
 			if (server == NULL)
 				continue;
@@ -6769,29 +6918,37 @@ int get_server_list_from_file()
 		return -1;
 	else
 		return 0;
-	
 }
 
 
-//get ip of server from cache
+/*  Get IP of server from cache  */
 int get_ip(char* server,char* ip)
 {
 	int index=0;
+
+
 	for(index = 0 ; index < no_of_server ; ++index )
 	{
 		if(strncasecmp(server,serverInfo[index], MAX_SERVER_SIZE) == 0)
 		{
+			if (serverInfo[index][MAX_SERVER_SIZE] == '\n')
+				return -1;
+
 			strncpy(ip,&serverInfo[index][MAX_SERVER_SIZE],MAX_IP_SIZE);
 			return 0;
 		}
 	}	
+
 	return -1;
 }
 
-//get server name from cache
+
+/*  Get server name from cache  */
 int get_server(char*ip, char*server)
 {
 	int index=0;
+
+
 	for(index = 0 ; index < no_of_server ; ++index )
 	{
 		if(strncasecmp(ip,&serverInfo[index][MAX_SERVER_SIZE], MAX_IP_SIZE) == 0)
@@ -6800,6 +6957,7 @@ int get_server(char*ip, char*server)
 			return 0;
 		}
 	}	
+
 	return -1;
 }
 	   
@@ -6812,7 +6970,7 @@ int get_server(char*ip, char*server)
  */ 
 char* removeWhiteSpace(char *str)
 {
-        char *userNameStr;
+        char	*userNameStr = NULL;
         int i=0;
 
         if (NULL == str)
@@ -6823,7 +6981,7 @@ char* removeWhiteSpace(char *str)
         userNameStr=strdup(str);
 
         // Remove White Space characters
-        for(i = 0;(userNameStr[i] != '\0') || (userNameStr[i] != 0);i++)
+        for (i = 0; ((userNameStr[i] != '\0') || (userNameStr[i] != 0)); i++)
         {
                 if (userNameStr[i] ==' ')
                 {
@@ -6841,10 +6999,10 @@ char* removeWhiteSpace(char *str)
  *
  * Output : user name	
  */
-static const char *getUserNameByUID(const uid_t uid)
+char *getUserNameByUID(const uid_t uid)
 {
-    struct passwd *pwd = NULL;
     char *userName = NULL;
+    struct passwd	*pwd = NULL;
     
     if ((userName = malloc((size_t) 32U)) == NULL)
     {
@@ -6863,3 +7021,32 @@ static const char *getUserNameByUID(cons
 
     return userName;
 }
+
+/* 
+ * This function is used to get the context information from user FDN
+ * Input  : User FDN (cn=ftpuser.ou=ftp.ou=users.o=novell)
+ * Output : Context (ftp.users.novell)	
+ */
+int getUserContext (char *userFDN, char *context)
+{
+	char	delim[] = "=";
+	char	*tmpPtr1 = NULL, *tmpPtr2 = NULL;
+
+
+	/*  In FDN (ex: cn=ftpuser.ou=ftp.ou=users.o=novell), skip first 3 bytes and then start parsing context info  */
+	if ((tmpPtr1 = index ((userFDN + 3), '=')) != NULL)				
+	{
+		tmpPtr1++;
+
+		for (; ((tmpPtr2 = strtok (tmpPtr1, delim)) != NULL); tmpPtr1 = NULL, context++)
+		{
+			while ((*tmpPtr2) && (*tmpPtr2 != '.'))			
+				*context++ = *tmpPtr2++;
+			*context = *tmpPtr2;				
+		}
+	}
+	else
+		return 1;
+
+	return 0;
+}
