Logo Search packages:      
Sourcecode: gadmin-proftpd version File versions  Download package

apply_user.c

/* GADMIN-PROFTPD - An easy to use GTK+ frontend for the ProFTPD standalone server.
 * Copyright (C) 2001 - 2008 Magnus Loef <magnus-swe@telia.com> 
 *
 * 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 3 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
*/



#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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<Anonymous %s>\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, "<Limit LOGIN>\n");
      strcat(user_profile, "Allow from all\nDeny from all\n");
      strcat(user_profile, "</Limit>\n");
    }
    else
      {
       strcat(user_profile, "<Limit LOGIN>\n");
       strcat(user_profile, "Allow from ");
       strcat(user_profile, login_from);
       strcat(user_profile, "\nDeny from all\n");
       strcat(user_profile, "</Limit>\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, "</Anonymous>\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, "<VirtualHost %s>\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, "</VirtualHost>") )
                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, "<Anonymous ") )
      {
          /* Save this directory incase its not the correct user */
          strcat(new_buffer, old_buffer);

          while(fgets(old_buffer, conf_size, fp)!=NULL)
          {
            /* This is the correct user in the correct server */
            if( strstr(old_buffer, UserUsername) 
            && ! strstr(old_buffer, "AllowUser") 
            && ! strstr(old_buffer, "DirFakeUser") && ! user_changed )
            {
                /* The new profile is added */
                strcat(config, user_profile);
                new_buffer[0]='\0';
                user_changed = 1;

                /* The old profile is deleted */
                while(fgets(old_buffer, conf_size, fp)!=NULL)
                {
                  if( strstr(old_buffer, "</Anonymous") )
                    break;

                  /* Some more safety breaks */
                  if( strstr(old_buffer, "<Anonymous") )
                    break;

                  if( strstr(old_buffer, "</VirutalHost") )
                    break;

                  if( strstr(old_buffer, "<VirutalHost") )
                    break;
                }
            }
            else
              {
                 if( strlen(new_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);
}

Generated by  Doxygen 1.6.0   Back to index