diff --git a/build/Debug/GNU-Linux/ftpCommandElaborate.o b/build/Debug/GNU-Linux/ftpCommandElaborate.o index ce59abc..6bb7a17 100644 Binary files a/build/Debug/GNU-Linux/ftpCommandElaborate.o and b/build/Debug/GNU-Linux/ftpCommandElaborate.o differ diff --git a/build/Debug/GNU-Linux/ftpData.o b/build/Debug/GNU-Linux/ftpData.o index 13e5ea0..886821b 100644 Binary files a/build/Debug/GNU-Linux/ftpData.o and b/build/Debug/GNU-Linux/ftpData.o differ diff --git a/build/Debug/GNU-Linux/ftpServer.o b/build/Debug/GNU-Linux/ftpServer.o index 0df3cfe..0328589 100644 Binary files a/build/Debug/GNU-Linux/ftpServer.o and b/build/Debug/GNU-Linux/ftpServer.o differ diff --git a/build/Debug/GNU-Linux/library/configRead.o b/build/Debug/GNU-Linux/library/configRead.o index 5c4f366..e2258e3 100644 Binary files a/build/Debug/GNU-Linux/library/configRead.o and b/build/Debug/GNU-Linux/library/configRead.o differ diff --git a/build/Debug/GNU-Linux/library/connection.o b/build/Debug/GNU-Linux/library/connection.o index 786e57e..a26ec1f 100644 Binary files a/build/Debug/GNU-Linux/library/connection.o and b/build/Debug/GNU-Linux/library/connection.o differ diff --git a/build/Debug/GNU-Linux/library/daemon.o b/build/Debug/GNU-Linux/library/daemon.o index 1ca7643..b1e3b9e 100644 Binary files a/build/Debug/GNU-Linux/library/daemon.o and b/build/Debug/GNU-Linux/library/daemon.o differ diff --git a/build/Debug/GNU-Linux/library/dynamicVectors.o b/build/Debug/GNU-Linux/library/dynamicVectors.o index 4de3406..f4d601c 100644 Binary files a/build/Debug/GNU-Linux/library/dynamicVectors.o and b/build/Debug/GNU-Linux/library/dynamicVectors.o differ diff --git a/build/Debug/GNU-Linux/library/fileManagement.o b/build/Debug/GNU-Linux/library/fileManagement.o index 6e34e31..8a51513 100644 Binary files a/build/Debug/GNU-Linux/library/fileManagement.o and b/build/Debug/GNU-Linux/library/fileManagement.o differ diff --git a/build/Debug/GNU-Linux/library/logFunctions.o b/build/Debug/GNU-Linux/library/logFunctions.o index f5e868c..41b67dd 100644 Binary files a/build/Debug/GNU-Linux/library/logFunctions.o and b/build/Debug/GNU-Linux/library/logFunctions.o differ diff --git a/build/Debug/GNU-Linux/library/signals.o b/build/Debug/GNU-Linux/library/signals.o index e3fd546..3f931cc 100644 Binary files a/build/Debug/GNU-Linux/library/signals.o and b/build/Debug/GNU-Linux/library/signals.o differ diff --git a/build/Debug/GNU-Linux/uFTP.o b/build/Debug/GNU-Linux/uFTP.o index 5bd4a41..4fe0bf1 100644 Binary files a/build/Debug/GNU-Linux/uFTP.o and b/build/Debug/GNU-Linux/uFTP.o differ diff --git a/dist/Debug/GNU-Linux/uftp b/dist/Debug/GNU-Linux/uftp index b34363f..8c2b9ed 100755 Binary files a/dist/Debug/GNU-Linux/uftp and b/dist/Debug/GNU-Linux/uftp differ diff --git a/ftpCommandElaborate.c b/ftpCommandElaborate.c index c2a6c0a..4436137 100644 --- a/ftpCommandElaborate.c +++ b/ftpCommandElaborate.c @@ -77,7 +77,7 @@ int parseCommandSite(clientDataType *theClientData) if(compareStringCaseInsensitive(theCommand, "CHMOD", strlen("CHMOD")) == 1) { - setPermissions(theCommand, theClientData->login.absolutePath.text); + setPermissions(theCommand, theClientData->login.absolutePath.text, theClientData->login.ownerShip); char *theResponse = "200 Permissions changed\r\n"; returnCode = write(theClientData->socketDescriptor, theResponse, strlen(theResponse)); if (returnCode <= 0) return FTP_COMMAND_PROCESSED_WRITE_ERROR; @@ -113,7 +113,6 @@ int parseCommandPass(ftpDataType * data, int socketId) char *theResponse = "430 Invalid username or password\r\n"; returnCode = write(data->clients[socketId].socketDescriptor, theResponse, strlen(theResponse)); if (returnCode <= 0) return FTP_COMMAND_PROCESSED_WRITE_ERROR; - //printf("\nLogin Error recorded no such username or password"); } else { @@ -122,16 +121,15 @@ int parseCommandPass(ftpDataType * data, int socketId) setDynamicStringDataType(&data->clients[socketId].login.absolutePath, ((usersParameters_DataType *) data->ftpParameters.usersVector.Data[searchUserNameIndex])->homePath, strlen(((usersParameters_DataType *) data->ftpParameters.usersVector.Data[searchUserNameIndex])->homePath)); setDynamicStringDataType(&data->clients[socketId].login.homePath, ((usersParameters_DataType *) data->ftpParameters.usersVector.Data[searchUserNameIndex])->homePath, strlen(((usersParameters_DataType *) data->ftpParameters.usersVector.Data[searchUserNameIndex])->homePath)); setDynamicStringDataType(&data->clients[socketId].login.ftpPath, "/", strlen("/")); + + data->clients[socketId].login.ownerShip.ownerShipSet = ((usersParameters_DataType *) data->ftpParameters.usersVector.Data[searchUserNameIndex])->ownerShip.ownerShipSet; + data->clients[socketId].login.ownerShip.gid = ((usersParameters_DataType *) data->ftpParameters.usersVector.Data[searchUserNameIndex])->ownerShip.gid; + data->clients[socketId].login.ownerShip.uid = ((usersParameters_DataType *) data->ftpParameters.usersVector.Data[searchUserNameIndex])->ownerShip.uid; data->clients[socketId].login.userLoggedIn = 1; returnCode = write(data->clients[socketId].socketDescriptor, theResponse, strlen(theResponse)); if (returnCode <= 0) return FTP_COMMAND_PROCESSED_WRITE_ERROR; printTimeStamp(); - - //printf("PASS COMMAND OK, PASSWORD IS: %s", data->clients[socketId].login.password.text); - //printf("\nheClientData->login.homePath: %s", data->clients[socketId].login.homePath.text); - //printf("\nheClientData->login.ftpPath: %s", data->clients[socketId].login.ftpPath.text); - //printf("\nheClientData->login.absolutePath: %s", data->clients[socketId].login.absolutePath.text); } return 1; @@ -295,7 +293,6 @@ int parseCommandPort(ftpDataType * data, int socketId) return 1; } - int parseCommandAbor(ftpDataType * data, int socketId) { char theResponse[FTP_COMMAND_ELABORATE_CHAR_BUFFER]; @@ -657,6 +654,11 @@ int parseCommandMkd(clientDataType *theClientData) int returnStatus; //printf("\nThe directory to make is: %s", mkdFileName.text); returnStatus = mkdir(mkdFileName.text, S_IRWXU | S_IRWXG | S_IRWXO); + if (theClientData->login.ownerShip.ownerShipSet == 1) + { + FILE_doChownFromUidGid(mkdFileName.text, theClientData->login.ownerShip.uid, theClientData->login.ownerShip.gid); + } + setDynamicStringDataType(&theResponse, "257 \"", strlen("257 \"")); appendToDynamicStringDataType(&theResponse, theDirectoryFilename, strlen(theDirectoryFilename)); appendToDynamicStringDataType(&theResponse, "\" : The directory was successfully created\r\n", strlen("\" : The directory was successfully created\r\n")); @@ -1122,13 +1124,14 @@ int getFtpCommandArgWithOptions(char * theCommand, char *theCommandString, ftpCo return 1; } -int setPermissions(char * permissionsCommand, char * basePath) +int setPermissions(char * permissionsCommand, char * basePath, ownerShip_DataType ownerShip) { #define STATUS_INCREASE 0 #define STATUS_PERMISSIONS 1 #define STATUS_LOCAL_PATH 2 int permissionsCommandCursor = 0; + int returnCode = 0; int status = STATUS_INCREASE; char thePermissionString[1024]; @@ -1174,14 +1177,37 @@ int setPermissions(char * permissionsCommand, char * basePath) //printf("\n thePermissionString = %s ", thePermissionString); //printf("\n theLocalPathCursor = %s ", theLocalPath); + //if (basePath[strlen(basePath)-1] != '/') + //sprintf(theFinalCommand, "chmod %s %s/%s", thePermissionString, basePath, theLocalPath); + //else + //sprintf(theFinalCommand, "chmod %s %s%s", thePermissionString, basePath, theLocalPath); + + //printf("\ntheFinalCommand = %s ", theFinalCommand); + + //system(theFinalCommand); + if (ownerShip.ownerShipSet == 1) + { + memset(theFinalCommand, 0, 2048); + if (basePath[strlen(basePath)-1] != '/') + sprintf(theFinalCommand, "%s/%s", basePath, theLocalPath); + else + sprintf(theFinalCommand, "%s%s", basePath, theLocalPath); + + FILE_doChownFromUidGid(theFinalCommand, ownerShip.uid, ownerShip.gid); + } + + memset(theFinalCommand, 0, 2048); + if (basePath[strlen(basePath)-1] != '/') - sprintf(theFinalCommand, "chmod %s %s/%s", thePermissionString, basePath, theLocalPath); + sprintf(theFinalCommand, "%s/%s", basePath, theLocalPath); else - sprintf(theFinalCommand, "chmod %s %s%s", thePermissionString, basePath, theLocalPath); - - //printf("\n theFinalCommand = %s ", theFinalCommand); - - system(theFinalCommand); - + sprintf(theFinalCommand, "%s%s", basePath, theLocalPath); + + returnCode = strtol(thePermissionString, 0, 8); + if (chmod (theFinalCommand, returnCode) < 0) + { + printf("\n---> ERROR WHILE SETTING FILE PERMISSION"); + } + return 1; } \ No newline at end of file diff --git a/ftpCommandsElaborate.h b/ftpCommandsElaborate.h index e2c092f..cd97ca2 100644 --- a/ftpCommandsElaborate.h +++ b/ftpCommandsElaborate.h @@ -75,7 +75,7 @@ int parseCommandRnto(clientDataType *theClientData); int writeRetrFile(char * theFilename, int thePasvSocketConnection, int startFrom, FILE *retrFP); char *getFtpCommandArg(char * theCommand, char *theCommandString, int skipArgs); int getFtpCommandArgWithOptions(char * theCommand, char *theCommandString, ftpCommandDataType *ftpCommand); -int setPermissions(char * permissionsCommand, char * basePath); +int setPermissions(char * permissionsCommand, char * basePath, ownerShip_DataType ownerShip); #ifdef __cplusplus } diff --git a/ftpData.c b/ftpData.c index bd72b0c..34c6401 100644 --- a/ftpData.c +++ b/ftpData.c @@ -22,7 +22,6 @@ * THE SOFTWARE. */ - #include #include #include @@ -31,7 +30,6 @@ #include #include - #include "ftpServer.h" #include "ftpCommandsElaborate.h" #include "ftpData.h" @@ -459,7 +457,6 @@ void resetClientData(clientDataType *clientData, int isInitialization) memset(&clientData->client_sockaddr_in, 0, clientData->sockaddr_in_size); memset(&clientData->server_sockaddr_in, 0, clientData->sockaddr_in_server_size); - memset(clientData->clientIpAddress, 0, INET_ADDRSTRLEN); memset(clientData->buffer, 0, CLIENT_BUFFER_STRING_SIZE); memset(clientData->theCommandReceived, 0, CLIENT_COMMAND_STRING_SIZE); @@ -475,12 +472,9 @@ void resetClientData(clientDataType *clientData, int isInitialization) cleanDynamicStringDataType(&clientData->ftpCommand.commandArgs, isInitialization); cleanDynamicStringDataType(&clientData->ftpCommand.commandOps, isInitialization); - - + clientData->connectionTimeStamp = 0; clientData->lastActivityTimeStamp = 0; - - } int compareStringCaseInsensitive(char * stringIn, char * stringRef, int stringLenght) diff --git a/ftpData.h b/ftpData.h index 8bd163b..1fc4fd3 100644 --- a/ftpData.h +++ b/ftpData.h @@ -47,11 +47,25 @@ struct parameter char* value; } typedef parameter_DataType; + +struct ownerShip +{ + int ownerShipSet; + char* userOwnerString; + char* groupOwnerString; + uid_t uid; + gid_t gid; + +} typedef ownerShip_DataType; + struct usersParameters { char* name; char* password; - char* homePath; + char* homePath; + + ownerShip_DataType ownerShip; + } typedef usersParameters_DataType; struct ftpParameters @@ -85,7 +99,7 @@ struct loginData dynamicStringDataType homePath; dynamicStringDataType ftpPath; dynamicStringDataType absolutePath; - + ownerShip_DataType ownerShip; } typedef loginDataType; struct ipData diff --git a/ftpServer.c b/ftpServer.c index 25250e3..ee4ae22 100644 --- a/ftpServer.c +++ b/ftpServer.c @@ -219,6 +219,12 @@ void *connectionWorkerHandle(void * socketId) } fclose(ftpData.clients[theSocketId].workerData.theStorFile); ftpData.clients[theSocketId].workerData.theStorFile = NULL; + + + if (ftpData.clients[theSocketId].login.ownerShip.ownerShipSet == 1) + { + FILE_doChownFromUidGid(ftpData.clients[theSocketId].fileToStor.text, ftpData.clients[theSocketId].login.ownerShip.uid, ftpData.clients[theSocketId].login.ownerShip.gid); + } memset(theResponse, 0, FTP_COMMAND_ELABORATE_CHAR_BUFFER); sprintf(theResponse, "226 file stor ok\r\n"); diff --git a/library/configRead.c b/library/configRead.c index 62c3df0..ec2b431 100644 --- a/library/configRead.c +++ b/library/configRead.c @@ -346,7 +346,9 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve char userX[PARAMETER_SIZE_LIMIT], passwordX[PARAMETER_SIZE_LIMIT], - homeX[PARAMETER_SIZE_LIMIT]; + homeX[PARAMETER_SIZE_LIMIT], + userOwnerX[PARAMETER_SIZE_LIMIT], + groupOwnerX[PARAMETER_SIZE_LIMIT]; printf("\nReading configuration settings.."); @@ -441,21 +443,33 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve memset(userX, 0, PARAMETER_SIZE_LIMIT); memset(passwordX, 0, PARAMETER_SIZE_LIMIT); memset(homeX, 0, PARAMETER_SIZE_LIMIT); - + memset(userOwnerX, 0, PARAMETER_SIZE_LIMIT); + memset(groupOwnerX, 0, PARAMETER_SIZE_LIMIT); + DYNV_VectorGeneric_Init(&ftpParameters->usersVector); while(1) { - int searchUserIndex, searchPasswordIndex, searchHomeIndex; + int searchUserIndex, searchPasswordIndex, searchHomeIndex, searchUserOwnerIndex, searchGroupOwnerIndex; usersParameters_DataType userData; sprintf(userX, "USER_%d", userIndex); sprintf(passwordX, "PASSWORD_%d", userIndex); sprintf(homeX, "HOME_%d", userIndex); + sprintf(groupOwnerX, "GROUP_NAME_OWNER_%d", userIndex); + sprintf(userOwnerX, "USER_NAME_OWNER_%d", userIndex); userIndex++; searchUserIndex = searchParameter(userX, parametersVector); searchPasswordIndex = searchParameter(passwordX, parametersVector); searchHomeIndex = searchParameter(homeX, parametersVector); + searchUserOwnerIndex = searchParameter(userOwnerX, parametersVector); + searchGroupOwnerIndex = searchParameter(groupOwnerX, parametersVector); + + //printf("\ngroupOwnerX = %s", groupOwnerX); + //printf("\nuserOwnerX = %s", userOwnerX); + //printf("\nsearchUserOwnerIndex = %d", searchUserOwnerIndex); + //printf("\nsearchGroupOwnerIndex = %d", searchGroupOwnerIndex); + if (searchUserIndex == -1 || searchPasswordIndex == -1 || @@ -465,6 +479,8 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve break; } + userData.ownerShip.groupOwnerString = NULL; + userData.ownerShip.userOwnerString = NULL; userData.name = malloc(strlen(((parameter_DataType *) parametersVector->Data[searchUserIndex])->value) + 1); userData.password = malloc(strlen(((parameter_DataType *) parametersVector->Data[searchPasswordIndex])->value) + 1); userData.homePath = malloc(strlen(((parameter_DataType *) parametersVector->Data[searchHomeIndex])->value) + 1); @@ -476,12 +492,41 @@ static int parseConfigurationFile(ftpParameters_DataType *ftpParameters, DYNV_Ve userData.name[strlen(((parameter_DataType *) parametersVector->Data[searchUserIndex])->value)] = '\0'; userData.password[strlen(((parameter_DataType *) parametersVector->Data[searchPasswordIndex])->value)] = '\0'; userData.homePath[strlen(((parameter_DataType *) parametersVector->Data[searchHomeIndex])->value)] = '\0'; + + if (searchUserOwnerIndex != -1 && + searchGroupOwnerIndex != -1) + { + userData.ownerShip.groupOwnerString = malloc(strlen(((parameter_DataType *) parametersVector->Data[searchGroupOwnerIndex])->value) + 1); + userData.ownerShip.userOwnerString = malloc(strlen(((parameter_DataType *) parametersVector->Data[searchUserOwnerIndex])->value) + 1); - printf("\nUser parameter found"); + strcpy(userData.ownerShip.groupOwnerString, ((parameter_DataType *) parametersVector->Data[searchGroupOwnerIndex])->value); + strcpy(userData.ownerShip.userOwnerString, ((parameter_DataType *) parametersVector->Data[searchUserOwnerIndex])->value); + + userData.ownerShip.groupOwnerString[strlen(((parameter_DataType *) parametersVector->Data[searchGroupOwnerIndex])->value)] = '\0'; + userData.ownerShip.userOwnerString[strlen(((parameter_DataType *) parametersVector->Data[searchUserOwnerIndex])->value)] = '\0'; + + userData.ownerShip.gid = FILE_getGID(userData.ownerShip.groupOwnerString); + userData.ownerShip.uid = FILE_getUID(userData.ownerShip.userOwnerString); + userData.ownerShip.ownerShipSet = 1; + } + else + { + userData.ownerShip.ownerShipSet = 0; + userData.ownerShip.groupOwnerString = NULL; + userData.ownerShip.userOwnerString = NULL; + } + + printf("\n\nUser parameter found"); printf("\nName: %s", userData.name); printf("\nPassword: %s", userData.password); printf("\nHomePath: %s", userData.homePath); - + printf("\ngroupOwnerStr: %s", userData.ownerShip.groupOwnerString); + printf("\nuserOwnerStr: %s", userData.ownerShip.userOwnerString); + printf("\nuserData.gid = %d", userData.ownerShip.gid); + printf("\nuserData.uid = %d", userData.ownerShip.uid); + printf("\nuserData.ownerShipSet = %d", userData.ownerShip.ownerShipSet); + + ftpParameters->usersVector.PushBack(&ftpParameters->usersVector, &userData, sizeof(usersParameters_DataType)); } diff --git a/library/fileManagement.c b/library/fileManagement.c index 02fa4bf..49ebf38 100644 --- a/library/fileManagement.c +++ b/library/fileManagement.c @@ -32,12 +32,17 @@ #include #include #include +#include #include #include #include "fileManagement.h" #include "dynamicVectors.h" + + + + static int FILE_CompareString(const void * a, const void * b); static int FILE_CompareString(const void * a, const void * b) @@ -537,4 +542,72 @@ int FILE_LockFile(int fd) fl.l_whence = SEEK_SET; fl.l_len = 0; return(fcntl(fd, F_SETLK, &fl)); +} + + +int FILE_doChownFromUidGid(const char *file_path, uid_t uid, gid_t gid) +{ + if (chown(file_path, uid, gid) == -1) + { + return 0; + } + + return 1; +} + +int FILE_doChownFromUidGidString ( const char *file_path, + const char *user_name, + const char *group_name) +{ + uid_t uid; + gid_t gid; + struct passwd *pwd; + struct group *grp; + + pwd = getpwnam(user_name); + if (pwd == NULL) + { + return 0; + } + uid = pwd->pw_uid; + + grp = getgrnam(group_name); + if (grp == NULL) + { + return 0; + } + gid = grp->gr_gid; + + if (chown(file_path, uid, gid) == -1) + { + return 0; + } + + return 1; +} + + +uid_t FILE_getUID(const char *user_name) +{ + struct passwd *pwd; + pwd = getpwnam(user_name); + + if (pwd == NULL) + { + return -1; + } + + return pwd->pw_uid; +} + +gid_t FILE_getGID(const char *group_name) +{ + struct group *grp; + grp = getgrnam(group_name); + if (grp == NULL) + { + return -1; + } + + return grp->gr_gid; } \ No newline at end of file diff --git a/library/fileManagement.h b/library/fileManagement.h index 8036dc2..0277ae6 100644 --- a/library/fileManagement.h +++ b/library/fileManagement.h @@ -26,6 +26,7 @@ #include #include + #include #include "dynamicVectors.h" #define FILE_MAX_LINE_LENGHT 512 @@ -65,5 +66,9 @@ void FILE_AppendToString(char ** sourceString, char *theString); void FILE_DirectoryToParent(char ** sourceString); int FILE_LockFile(int fd); + int FILE_doChownFromUidGidString(const char *file_path, const char *user_name, const char *group_name); + int FILE_doChownFromUidGid(const char *file_path, uid_t uid, gid_t gid); + uid_t FILE_getUID(const char *user_name); + gid_t FILE_getGID(const char *group_name); #define GEN_FILE_MANAGEMENT_TYPES #endif diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml index 4708682..752dd27 100644 --- a/nbproject/private/private.xml +++ b/nbproject/private/private.xml @@ -7,7 +7,11 @@ + file:/home/ugo/NetBeansProjects/uFTP/ftpData.c + file:/home/ugo/NetBeansProjects/uFTP/ftpCommandElaborate.c file:/home/ugo/NetBeansProjects/uFTP/ftpServer.c + file:/home/ugo/NetBeansProjects/uFTP/uFTP.c + file:/home/ugo/NetBeansProjects/uFTP/library/configRead.c diff --git a/uftpd.cfg b/uftpd.cfg index 5759bde..a60480f 100644 --- a/uftpd.cfg +++ b/uftpd.cfg @@ -32,9 +32,11 @@ IDLE_MAX_TIMEOUT = 3600 USER_0 = ugo PASSWORD_0 = pass HOME_0 = / +GROUP_NAME_OWNER_0 = ugo +USER_NAME_OWNER_0 = ugo USER_1 = root PASSWORD_1 = pass HOME_1 = / - - +GROUP_NAME_OWNER_1 = root +USER_NAME_OWNER_1 = root \ No newline at end of file