/* * GProFTPD - A GTK+ frontend for the ProFTPD standalone server. * Copyright (C) 2001 - 2006 Magnus Loef (Magnus-swe) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include "widgets.h" #include "gettext.h" #include "functions.h" #include "reread_conf.h" #include "show_info.h" #include "apply_user.h" #include "allocate.h" #include "populate_users.h" #include "populate_user_settings.h" #include "populate_conf_tab.h" #include "dir_treeview_funcs.h" extern char global_server_address[1024]; extern char global_server_port[1024]; extern char global_server_type[1024]; extern int activated; extern int use_ratio; extern int use_quota; /* Temporary for option deprecations */ extern char global_version[1024]; /* The current directory beeing added and limited */ //gchar *dir; // ??? extern gchar *homedir; /* The 18 checkbox values */ gchar *dir_val[19]; // ??? char *user_profile; // ??? extern long num_rows; extern int row_pos; /* Fixme mod: group, comment and shell */ void apply_user(struct w *widgets) { /* Change the selected users configuration. */ /* First delete the user from the conf then add it */ FILE *fp; long conf_size; int password_length = 0; gchar *info; char *old_buffer, *new_buffer, *config, *address_buffer, *port_buffer; long profile_size = 0; int user_changed = 0; int found = 0; gchar *UserUsername; char *temp_user; G_CONST_RETURN gchar *username; G_CONST_RETURN gchar *groupname; G_CONST_RETURN gchar *comment; G_CONST_RETURN gchar *password; G_CONST_RETURN gchar *login_from; G_CONST_RETURN gchar *max_logins; G_CONST_RETURN gchar *br=NULL, *brc=NULL, *fr=NULL, *frc=NULL; /* Get the settings from the entries */ username = gtk_entry_get_text(GTK_ENTRY(widgets->user_set_entry[0])); password = gtk_entry_get_text(GTK_ENTRY(widgets->user_set_entry[1])); groupname = gtk_entry_get_text(GTK_ENTRY(widgets->user_set_entry[2])); comment = gtk_entry_get_text(GTK_ENTRY(widgets->user_set_entry[3])); login_from = gtk_entry_get_text(GTK_ENTRY(widgets->user_set_entry[5])); max_logins = gtk_entry_get_text(GTK_ENTRY(widgets->user_set_spinbutton[0])); /* Ratios */ if( use_ratio ) { br = gtk_entry_get_text(GTK_ENTRY(widgets->user_set_spinbutton[1])); brc = gtk_entry_get_text(GTK_ENTRY(widgets->user_set_spinbutton[2])); fr = gtk_entry_get_text(GTK_ENTRY(widgets->user_set_spinbutton[3])); frc = gtk_entry_get_text(GTK_ENTRY(widgets->user_set_spinbutton[4])); } if( password!=NULL ) password_length = strlen(password); /* If the user has written a password thats less then MIN_PASS_LEN chars long */ if( password_length > 0 && password_length < MIN_PASS_LEN ) { info = g_strdup_printf(_("The minimum password length is %d.\n"), MIN_PASS_LEN); show_info(info); g_free(info); return; } /* Set global num_rows */ num_rows = 0; gtk_tree_model_foreach(GTK_TREE_MODEL(widgets->directory_store), (GtkTreeModelForeachFunc) num_rows_func, widgets); /* There must be atleast one directory */ if( num_rows < 1 ) { info = g_strdup_printf(_("Missing ftp home directory. Scroll down and add one first.\n")); show_info(info); g_free(info); return; } /* (Global char) Statics + entries + number of rows (dirlen + APPE STOR STOU etc) */ profile_size = 16384 + 1400 + (num_rows * 16384); /* Allocate the user profile */ user_profile = allocate(profile_size); /* Set the users home dir and its values globally */ row_pos = 0; /* Only get the home directory */ gtk_tree_model_foreach(GTK_TREE_MODEL(widgets->directory_store), (GtkTreeModelForeachFunc) dirs_foreach, widgets); /* Create the user profile... */ /* Home directory */ snprintf(user_profile, 16384, "\n\n", homedir); // ERROR!!! /* Username */ strcat(user_profile, "User "); strcat(user_profile, username); strcat(user_profile, "\n"); /* Groupname */ strcat(user_profile, "Group "); strcat(user_profile, groupname); strcat(user_profile, "\n"); /* Require password */ if( ! gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widgets->user_set_checkbutton[1])) ) strcat(user_profile, "AnonRequirePassword off\n"); else strcat(user_profile, "AnonRequirePassword on\n"); /* Maximum logins */ strcat(user_profile, "MaxClients "); strcat(user_profile, max_logins); strcat(user_profile, " \""); strcat(user_profile, "The server is full, hosting %m users"); strcat(user_profile, "\"\n"); /* Static Welcome and chdir msgs */ strcat(user_profile, "DisplayLogin welcome.msg\n"); // Fedora backported all but this! // if( strstr(global_version, "1.2.") || strstr(global_version, "1.3.0") ) // strcat(user_profile, "DisplayFirstChdir .msg\n"); // else // strcat(user_profile, "DisplayChdir .msg\n"); /* Ratio Module (reversed br/fr order in the gui) */ if( use_ratio ) { strcat(user_profile, "UserRatio "); strcat(user_profile, username); strcat(user_profile, " "); strcat(user_profile, fr); strcat(user_profile, " "); strcat(user_profile, frc); strcat(user_profile, " "); strcat(user_profile, br); strcat(user_profile, " "); strcat(user_profile, brc); strcat(user_profile, "\n"); } /* Logins from, if nothing is specified we allow everything */ if( login_from == NULL || strlen(login_from) < 3 ) { strcat(user_profile, "\n"); strcat(user_profile, "Allow from all\nDeny from all\n"); strcat(user_profile, "\n"); } else { strcat(user_profile, "\n"); strcat(user_profile, "Allow from "); strcat(user_profile, login_from); strcat(user_profile, "\nDeny from all\n"); strcat(user_profile, "\n"); } /* Append the Limit CMDs for the home directory */ append_limit_cmds(); /* Append all other directories to the user profile */ row_pos = 1; gtk_tree_model_foreach(GTK_TREE_MODEL(widgets->directory_store), (GtkTreeModelForeachFunc) dirs_foreach, widgets); /* If not checked, dont show this user in the statistics (picked up by gprostats) */ if( ! gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widgets->user_set_checkbutton[2])) ) strcat(user_profile, "#gplockstats\n"); /* Profile end */ strcat(user_profile, "\n"); if( homedir!=NULL ) g_free(homedir); /* We have the new profile, insert it where the old user was located in the selected server */ UserUsername = g_strdup_printf("User %s\n", username); address_buffer = allocate(8192+15); port_buffer = allocate(8192+3); if( strstr((char *)global_server_type, "Virtualhost") ) sprintf(address_buffer, "\n", global_server_address); else sprintf(address_buffer, global_server_address); sprintf(port_buffer, "Port %s\n", global_server_port); /* Make changes for this users settings */ if((fp=fopen(PROFTPD_CONF, "r"))==NULL) { free(address_buffer); free(port_buffer); return; } fseek(fp, 0, SEEK_END); conf_size = ftell(fp); rewind(fp); old_buffer = allocate(conf_size+3); config = allocate(conf_size+profile_size+3); /* If the selected server is a vhost we collect everything up to the first vhost with the same name as the selected one */ if( strstr((char *)global_server_type, "Virtualhost") ) { if( conf_size > 1 ) while(fgets(old_buffer, conf_size, fp)!=NULL) { strcat(config, old_buffer); /* If its the correct address */ if( ! strcmp(old_buffer, address_buffer) ) { while(fgets(old_buffer, conf_size, fp)!=NULL) { strcat(config, old_buffer); /* This server was not the right one */ if( strstr(old_buffer, "") ) break; if( ! strcmp(old_buffer, port_buffer) ) { found = 1; break; } } } if( found ) break; } } /* We have scrolled to the correct VirtualHost or its the default server */ new_buffer = allocate(8192); /* Change the selected users settings */ if( conf_size > 1 ) while(fgets(old_buffer, conf_size, fp)!=NULL) { if( strstr(old_buffer, " 0 ) { strcat(config, new_buffer); new_buffer[0]='\0'; } strcat(config, old_buffer); break; } } } else strcat(config, old_buffer); } free(old_buffer); free(new_buffer); g_free(UserUsername); fclose(fp); free(address_buffer); free(port_buffer); free(user_profile); if( ! user_changed ) { info = g_strdup_printf(_("Error: user not found, couldnt change its settings.\n")); show_info(info); g_free(info); free(config); return; } /* Write the new config with the changed users settings */ if((fp=fopen(PROFTPD_CONF, "w+"))==NULL) { free(config); return; } fputs(config, fp); fclose(fp); free(config); /* Ban or unban the user in ftpusers depending on the selection */ if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widgets->user_set_checkbutton[0])) ) { /* Ban the user */ if( ! is_banned((char *)username) ) { if((fp=fopen(GP_FTPUSERS, "a"))==NULL) { } else { fputs("\n", fp); fputs(username, fp); fputs("\n", fp); fclose(fp); } } } else { /* Remove the user from ftpusers if its there */ if( is_banned((char *)username) ) { if((fp=fopen(GP_FTPUSERS, "r"))==NULL) { } else { fseek(fp, 0, SEEK_END); conf_size = ftell(fp); rewind(fp); config = allocate(conf_size+4096); old_buffer = allocate(conf_size+4096); temp_user = allocate(8192); if( conf_size > 1 ) while(fgets(old_buffer, conf_size, fp)!=NULL) { sscanf(old_buffer, "%s", temp_user); if( ! strcmp(temp_user, username) ) { } else strcat(config, old_buffer); } fclose(fp); free(old_buffer); free(temp_user); if((fp=fopen(GP_FTPUSERS, "w+"))==NULL) { } else { fputs(config, fp); fclose(fp); } free(config); } } } /* Change the users password if its >= MIN_PASS_LEN */ if( password_length >= MIN_PASS_LEN ) { #ifndef USE_DARWIN if( user_exists(username) ) #elif USE_DARWIN if( niutil_user_exists(username) ) #endif { #ifndef USE_DARWIN password_user(username, password); #elif USE_DARWIN niutil_password_user(username, password); #endif info = g_strdup_printf(_("\nThe Password was changed.\n")); show_info(info); g_free(info); } else { info = g_strdup_printf(_("The password was not changed.\nThe user didnt exist in shadow or passwd.\n")); show_info(info); g_free(info); } } fix_newlines_in_conf(); /* Update the userlist */ populate_users(widgets); /* Populate the user settings (it also populates the directories) */ populate_user_settings(widgets); /* Populate the conf tab */ populate_conf_tab(widgets); /* Update the server */ reread_conf(widgets); }