Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.4
pure-ftpd
pure-ftpd-1.0.20-oes_remote_server.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pure-ftpd-1.0.20-oes_remote_server.patch of Package pure-ftpd
--- src/ftpd.c 2004-07-17 18:58:22.000000000 +0530 +++ src/ftpd.c 2009-05-07 14:12:45.000000000 +0530 @@ -38,6 +38,20 @@ # include <dmalloc.h> #endif +#include <ldap.h> +LDAP* ldapHandle; + + +// remote server navigation constants +#define MAX_SERVER_SIZE 100 +#define MAX_PATH_SIZE 1000 +const char MOUNT_PATH[] = "/var/opt/novell/nclmnt"; +const int MOUNT_PATH_SIZE = 22; + +char userFDN[512]; +static const char *getlocalhostname(); + + #ifndef HAVE_SYS_FSUID_H void disablesignals(void) { @@ -1496,6 +1510,9 @@ void dopass(char *password) /* Clear password from memory, paranoia */ register volatile char *password_ = (volatile char *) password; + if(remote_server == 1 ) + edir_login(account,password,authresult.uid); + while (*password_ != 0) { *password_++ = 0; } @@ -1843,6 +1860,31 @@ void docwd(const char *dir) addreply(550, MSG_SANITY_FILE_FAILURE, where); return; } + + char server[MAX_SERVER_SIZE],nss_loc[MAX_PATH_SIZE]; + if(remote_server ==1 ) + { + // Not allowed to move inside the folder NCPVolForFTP + if (strstr(where,"nclmnt") != NULL) + goto cd_success; + + getcwd(wd, sizeof wd - (size_t) 1U); + + // cd .. is not allowed from base remote dir + if( (wd != NULL) && (strcmp(where,"..") == 0)) + { + if(strncmp(wd,MOUNT_PATH,MOUNT_PATH_SIZE) ==0) + { + if(strstr(wd+MOUNT_PATH_SIZE+1+strlen(account)+1,"/") == NULL ) + goto cd_success; + } + } + + //mount remote server + if ( mount_remote_server(where,nss_loc,server) == 0 ) + where = nss_loc; + + } if (chdir(where) != 0) { #ifdef WITH_DIRALIASES @@ -1886,6 +1928,9 @@ void docwd(const char *dir) failures = 0UL; dobanner(1); #endif + +cd_success: + if (getcwd(wd, sizeof wd - (size_t) 1U) == NULL) { if (*dir == '/') { if (SNCHECK(snprintf(wd, sizeof wd, "%s", dir), sizeof wd)) { /* already checked */ @@ -1899,6 +1944,10 @@ void docwd(const char *dir) } } } + + if(remote_server ==1 ) + get_remote_server_path(wd); + addreply(250, MSG_CURRENT_DIR_IS, wd); } @@ -3244,6 +3293,7 @@ void domkd(char *name) #endif error(550, MSG_MKD_FAILURE); } else { + get_remote_server_path(name); addreply(257, "\"%s\" : " MSG_MKD_SUCCESS, name); } #ifdef QUOTAS @@ -4914,6 +4964,11 @@ int main(int argc, char *argv[]) no_ipv4 = 1; break; } + case '9': { + remote_server = 1; + break; + } + case '1': { log_pid = LOG_PID; break; @@ -5560,3 +5615,242 @@ 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) { + return NULL; + } + return buf; +} + +int edir_login(const char* user,const char* passwd,int uid) +{ + int index =0,openCount = 0; + char tmp[MAX_PATH_SIZE+100]; + FILE* fd = NULL; + char fdn[512];fdn[0] = '\0' ; + + const char* hostname = getlocalhostname(); + + // get the FDN of user from pam_nam.so + void * lumHandle = dlopen("/lib64/security/pam_nam.so", RTLD_LAZY); + if (lumHandle == NULL) + lumHandle = dlopen("/lib/security/pam_nam.so", RTLD_LAZY); + if(lumHandle != NULL) + { + namGetUserFDNfromUID = (int (*)(int, char *))dlsym(lumHandle, "namGetUserFDNfromUID"); + if(namGetUserFDNfromUID != NULL) + { + namGetUserFDNfromUID(uid, fdn); + } else + logfile(LOG_ERR,"Function namGetUserFDNfromUID not found"); + dlclose(lumHandle); + } else + logfile(LOG_ERR,"PAM library not found"); + + //copy user name provided by the ftp client incase pam_nam.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 + while (fdn[index] != '\0') + { + if(fdn[index] != ',') + userFDN[index] = fdn[index]; + else + userFDN[index] = '.'; + ++index; + } + userFDN[index] = '\0'; + + /* + do nwlogin the local server.Same nw connection is reused for connecting to different machine. + */ + snprintf(tmp,sizeof(tmp),"sudo -u %s nwlogin -s %s -u %s -p %s -c x > /dev/null",user,hostname,userFDN,passwd ); + system(tmp); + + //create directories to store no of simultaneous logins by same user + mkdir("/var/opt/novell/pure-ftpd/",0777); + snprintf(tmp,sizeof(tmp),"/var/opt/novell/pure-ftpd/%s",account); + mkdir(tmp, 0777); + + snprintf(tmp,sizeof(tmp),"/var/opt/novell/pure-ftpd/%s/count.txt",account); + fd = fopen(tmp,"r+"); + + openCount = 1; + if(fd != NULL) + { + if(fread(&openCount,sizeof(int),1,fd) > 0) + { + if(openCount >= 0) + ++openCount; + else + openCount = 1; + } else + openCount = 1; + fclose(fd); + } else + openCount = 1; + sprintf(tmp,"/var/opt/novell/pure-ftpd/%s/count.txt",account); + fd = fopen(tmp,"w+"); + if(fd != NULL) + { + fwrite(&openCount,sizeof(int),1,fd); + fclose(fd); + } + + ldapHandle = ldap_init("127.0.0.1", 389); + if (ldapHandle == NULL) + { + logfile(LOG_ERR, "ldap init failed"); + return 0; + } + ldap_simple_bind(ldapHandle,fdn,passwd); + + + + return 0; +} + +int mount_remote_server(const char* where,char* nss_loc,char* remote_server) +{ + char tmp[MAX_PATH_SIZE+100],path[MAX_PATH_SIZE]; + char* str1,*server; + int err; + struct hostent *he; + struct in_addr ipv4addr; + + if((where != NULL ) &&(strncmp(where,"//",2 ) ==0)) + { + //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,"/"); + + /* + * nwlogin as logged in ftp user. + * nwlogin does not require password here. novell client reuses exising connection + */ + sprintf(tmp,"sudo -u %s nwlogin -s %s -u %s -p x -c x > /dev/null",account,server,userFDN); + err= system(tmp); + + if(err !=0 ) + { + snprintf(tmp,sizeof(tmp),"Novell Client Login Failed with error %d ",err); + logfile(LOG_ERR,tmp); + return -1; + } + + /* + nwlogin mounts the remote server to dir with name "hostname" + ip address is converted to hostname + */ + + if(inet_pton(AF_INET, server, &ipv4addr) > 0) + { + he = gethostbyaddr(&ipv4addr, sizeof ipv4addr, AF_INET); + if(he != NULL) + server = strtok(he->h_name,"."); + } + + if(nss_loc != NULL) + snprintf(nss_loc,MAX_PATH_SIZE,"%s/%s/%s/%s",MOUNT_PATH,account,server,path); + if(remote_server != NULL ) + strncpy(remote_server,server, MAX_SERVER_SIZE); + + return 0; + } else + return -1; +} + + +int umount_remote_server() +{ + char tmp[MAX_PATH_SIZE+100]; + int openCount = 0; + FILE* fd = NULL; + + snprintf(tmp,sizeof(tmp),"/var/opt/novell/pure-ftpd/%s/count.txt",account); + fd = fopen(tmp,"r+"); + if(fd != NULL) + { + if(fread(&openCount,sizeof(int),1,fd) > 0) + { + if (openCount > 0 ) + --openCount; + else + openCount = 0; + } else + openCount = 0; + + fclose(fd); + + fd = fopen(tmp,"w+"); + fwrite(&openCount,sizeof(int),1,fd); + fclose(fd); + } else + logfile(LOG_ERR,"File Open failed"); + + //nwlogout is not called when same ftp user is logged in more than once + if(openCount <= 0) + { + snprintf(tmp,sizeof(tmp),"sudo -u %s nwlogout -f -a > /dev/null",account); + system(tmp); + } + return 0; +} + +int get_remote_server_path(char* path) +{ + char tmp[MAX_PATH_SIZE]; + + if (path == NULL) + return -1; + + // Send the remote dir location as reply + if( strncmp(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); + } + return 0; +} +int do_list_servers() +{ + //create server list + char* attrs[]={"cn",NULL}; + char* ldapDN; + LDAPMessage* entry = NULL; + LDAPMessage* searchResult = NULL; + + if (ldapHandle == NULL) + { + logfile(LOG_ERR, "LDAP connection failed "); + return -1; + } + int rc = ldap_search_ext_s(ldapHandle,"",LDAP_SCOPE_SUBTREE,"(&(objectclass=NCP Server))", + attrs, 0,NULL, NULL, 0, LDAP_NO_LIMIT, &searchResult); + + if(rc == LDAP_SUCCESS ) + { + for(entry = ldap_first_entry(ldapHandle,searchResult) ; entry != NULL ; + entry = ldap_next_entry(ldapHandle,entry)) + { + if(ldapDN = ldap_get_dn(ldapHandle,entry)) + addreply_noformat(0, ldapDN); + } + } else + addreply_noformat(0, ""); + return 0; +} + --- src/ftpd_p.h 2004-03-01 03:19:28.000000000 +0530 +++ src/ftpd_p.h 2009-05-05 10:57:16.000000000 +0530 @@ -61,6 +61,7 @@ struct reply { static const char *GETOPT_OPTIONS = "0146Aa:bc:" + "9" #ifndef NO_STANDALONE "BC:" #endif @@ -110,6 +111,7 @@ static struct option long_options[] = { { "logpid", 0, NULL, '1' }, { "ipv4only", 0, NULL, '4' }, { "ipv6only", 0, NULL, '6' }, + { "remoteserver", 0, NULL, '9' }, { "chrooteveryone", 0, NULL, 'A' }, { "trustedgid", 1, NULL, 'a' }, { "brokenclientscompatibility", 0, NULL, 'b' }, --- src/ftp_parser.c 2004-06-06 16:10:28.000000000 +0530 +++ src/ftp_parser.c 2009-05-05 10:57:17.000000000 +0530 @@ -16,6 +16,8 @@ # include <dmalloc.h> #endif +#define MAX_PATH_SIZE 1000 + static void antiidle(void) { if (noopidle == (time_t) -1) { @@ -294,6 +296,8 @@ void parser(void) } dopass(arg); } else if (!strcmp(cmd, "quit")) { + if(remote_server == 1) + umount_remote_server(); addreply(221, MSG_GOODBYE, (unsigned long long) ((uploaded + 1023ULL) / 1024ULL), (unsigned long long) ((downloaded + 1023ULL) / 1024ULL)); @@ -407,6 +411,10 @@ void parser(void) } else if (!strcmp(cmd, "cdup") || !strcmp(cmd, "xcup")) { docwd(".."); } else if (!strcmp(cmd, "retr")) { + // support full remote server path + char nss_loc[MAX_PATH_SIZE]; + if ( (remote_server == 1) && (mount_remote_server(arg,nss_loc,NULL) ==0)) + arg = nss_loc; if (*arg != 0) { doretr(arg); } else { @@ -422,12 +430,20 @@ void parser(void) } goto wayout; } else if (!strcmp(cmd, "dele")) { + // support full remote server path + char nss_loc[MAX_PATH_SIZE]; + if ( (remote_server == 1) && (mount_remote_server(arg,nss_loc,NULL) ==0)) + arg = nss_loc; if (*arg != 0) { dodele(arg); } else { addreply_noformat(501, MSG_NO_FILE_NAME); } } else if (!strcmp(cmd, "stor")) { + // support full remote server path + char nss_loc[MAX_PATH_SIZE]; + if ( (remote_server == 1) && (mount_remote_server(arg,nss_loc,NULL) ==0)) + arg = nss_loc; arg = revealextraspc(arg); if (*arg != 0) { dostor(arg, 0, autorename); @@ -435,6 +451,10 @@ void parser(void) addreply_noformat(501, MSG_NO_FILE_NAME); } } else if (!strcmp(cmd, "appe")) { + // support full remote server path + char nss_loc[MAX_PATH_SIZE]; + if ((remote_server == 1) && (mount_remote_server(arg,nss_loc,NULL) ==0)) + arg = nss_loc; arg = revealextraspc(arg); if (*arg != 0) { dostor(arg, 1, 0); @@ -447,6 +467,10 @@ void parser(void) #endif #ifndef DISABLE_MKD_RMD } else if (!strcmp(cmd, "mkd") || !strcmp(cmd, "xmkd")) { + // support full remote server path + char nss_loc[MAX_PATH_SIZE]; + if ((remote_server == 1) && (mount_remote_server(arg,nss_loc,NULL) ==0)) + arg = nss_loc; arg = revealextraspc(arg); if (*arg != 0) { domkd(arg); @@ -454,6 +478,10 @@ void parser(void) addreply_noformat(501, MSG_NO_DIRECTORY_NAME); } } else if (!strcmp(cmd, "rmd") || !strcmp(cmd, "xrmd")) { + // support full remote server path + char nss_loc[MAX_PATH_SIZE]; + if ( (remote_server == 1) && (mount_remote_server(arg,nss_loc,NULL) ==0)) + arg = nss_loc; if (*arg != 0) { dormd(arg); } else { @@ -575,6 +603,8 @@ void parser(void) } } # endif + } else if (!strcasecmp(arg, "slist")) { + do_list_servers(); } else if (*arg != 0) { addreply(500, "SITE %s " MSG_UNKNOWN_EXTENSION, arg); } else { --- src/globals.h 2004-03-01 03:19:28.000000000 +0530 +++ src/globals.h 2009-05-05 10:57:19.000000000 +0530 @@ -29,6 +29,7 @@ GLOBAL(int datafd, -1); GLOBAL0(struct sockaddr_storage ctrlconn); /* stdin/stdout, for using the same ip number */ GLOBAL0(signed char v6ready); /* IPv6 supported or not */ GLOBAL0(signed char no_ipv4); /* IPv4 disabled or not */ +GLOBAL0(signed char remote_server); /* OES remote server supported or not*/ GLOBAL(const size_t cmdsize, MAXPATHLEN + 16U); GLOBAL0(char cmd[MAXPATHLEN + 32U]); /* command line - about 30 chars for command */ GLOBAL0(char wd[MAXPATHLEN + 1U]); /* current working directory */ --- src/ls.c 2004-03-01 03:19:27.000000000 +0530 +++ src/ls.c 2009-05-05 10:57:16.000000000 +0530 @@ -12,6 +12,8 @@ # include <dmalloc.h> #endif +#define MAX_PATH_SIZE 1000 + static void wrstr(const int f, const char *s) { static char outbuf[CONF_TCP_SO_SNDBUF]; @@ -171,6 +173,7 @@ static void addfile(const char *name, co if (!name || !suffix) { return; } + if (matches >= max_ls_files) { return; } @@ -332,6 +335,11 @@ static int listfile(const PureFileInfo * if ((alloca_nameline = ALLOCA(sizeof_nameline)) == NULL) { return 0; } + char remote_file_name[MAX_PATH_SIZE]; + strncpy(remote_file_name,name,MAX_PATH_SIZE); + if(remote_server == 1) + get_remote_server_path(remote_file_name); + #ifdef WITH_LARGE_FILES if (SNCHECK(snprintf(alloca_nameline, sizeof_nameline, "%s %4d %s %s %8llu %s %2d %s %s", @@ -339,7 +347,7 @@ static int listfile(const PureFileInfo * getgroup(st.st_gid), (unsigned long long) st.st_size, months[t->tm_mon], - t->tm_mday, timeline, name), + t->tm_mday, timeline, remote_file_name), sizeof_nameline)) #else if (SNCHECK(snprintf(alloca_nameline, sizeof_nameline, @@ -348,7 +356,7 @@ static int listfile(const PureFileInfo * getgroup(st.st_gid), (unsigned long) st.st_size, months[t->tm_mon], - t->tm_mday, timeline, name), + t->tm_mday, timeline, remote_file_name), sizeof_nameline)) #endif { @@ -796,6 +804,11 @@ void donlist(char *arg, const int on_ctr justone = 1; /* just one argument, so don't print dir name */ + // support full remote server path + char nss_loc[MAX_PATH_SIZE]; + if ( (remote_server == 1) && (mount_remote_server(arg,nss_loc,NULL) ==0)) + arg = nss_loc; + do { glob_t g; int a;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor