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

import_functions.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 "../config.h"
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "support.h"
#include "allocate.h"
#include "widgets.h"
#include "functions.h"
#include "show_info.h"
#include "import_functions.h"
#include "system_defines.h"
#include "populate_users.h"
#include "populate_conf_tab.h"
#include "reread_conf.h"

#define GP_OSX_PASS_DUMP "/etc/gp_osx_passdump"

extern char global_server_address[1024];
extern char global_server_port[1024];
extern char global_server_type[1024];
extern char global_user_name[1024];

extern int activated;

/* Temporary for option deprecations */
extern char global_version[1024];

/* Fixme: Set at import_button_pressed */ 
char import_root_dir[8192]="";
//int import_to_usernamed_dirs = 0;
long num_imported = 0;


/*
void import_namebased_checkbutton_toggled(GtkToggleButton *togglebutton, struct w *widgets)
{
    if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton)) )
      import_to_usernamed_dirs = 1;
    else
      import_to_usernamed_dirs = 0;
}
*/

void add_import_users(GtkTreeModel *model, GtkTreePath *path,
                     GtkTreeIter *iter, struct w *widgets)
{
    FILE *fp;
    long conf_size;
    char *user_settings, *user_check, *old_buffer=NULL, *new_buffer=NULL;
    char *address_buffer, *port_buffer;
    int limit_access=0, found_server=0;
    gchar *username, *groupname, *directory;
    gchar *info;

    gtk_tree_model_get(model, iter, 0, &username, -1);
    gtk_tree_model_get(model, iter, 1, &groupname, -1);
    /* local_username = g_locale_from_utf8(username, -1, NULL, NULL, NULL); */

    /* If theres no username */
    if( strlen(username) == 0 ) 
    {
      printf("The username length was too short (0)\n");
      return;
    }
    if( strlen(groupname) == 0 ) 
    {
      printf("The groupname length was too short (0)\n");
      return;
    }

    if( username[0]=='0' || username[0]=='1' || username[0]=='2' || username[0]=='3' || username[0]=='4' 
    ||  username[0]=='5' || username[0]=='6' || username[0]=='7' || username[0]=='8' || username[0]=='9') 
    {
      printf("Usernames cant have a digit first\n");
      return;
    }

    if( username[0]=='r' && username[1]=='o' && username[2]=='o' && username[3]=='t' && strlen(username)==4 ) 
    {
      printf("Refusing to add user root\n");
      return;
    }

    if( groupname[0]=='r' && groupname[1]=='o' && groupname[2]=='o' && groupname[3]=='t' && strlen(groupname)==4 ) 
    {
      printf("Refusing to add group root\n");
      return;
    }

    if( strstr((char *)username, "<") || strstr((char *)username, ">") ) 
    {
      printf("A username containing < or > is not allowed.\n");
      return;
    }
    if( strstr((char *)groupname, "<") || strstr((char *)groupname, ">") ) 
    {
      printf("A username containing < or > is not allowed.\n");
      return;
    }

    /* If the directory field has less then 3 chars we inform that this cant be done */
    if( strlen(import_root_dir) < 6 )
    {
      printf("The minimum directory path length is 5 chars.\n");
      return;
    }

    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);


    /* Checks if the user exists in proftpd.conf, if so just shows a popup */
    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);
    user_check = allocate(4096);

    snprintf(user_check, 4000, "%s\n", username);

    /* Standard server selected, start checking users directly */
    if( ! strstr((char *)global_server_type, "Virtualhost") )
      found_server = 1;

    if( conf_size > 1 )
    while(fgets(old_buffer, conf_size, fp)!=NULL)
    {
      if( strlen(old_buffer) > 8000 )
      {
          fclose(fp);
          free(old_buffer);
          free(user_check);
          free(address_buffer);
          free(port_buffer);
          return;
      }


        if( strstr("Virtualhost", (char *)global_server_type) && ! found_server
      &&  ! strcmp(old_buffer, address_buffer) ) 
      {
          /* Lets see if its the same port as the selected one */
          /* If this server has the same port its the correct server */
          while(fgets(old_buffer, conf_size, fp)!=NULL)
          {
            if( strlen(old_buffer) > 8000 )
            {
                fclose(fp);
                free(old_buffer);
                free(user_check);
                free(address_buffer);
                free(port_buffer);
                return;
            }
          
            /* This will expect the servers port on the second line ! 
             * else itll miss some vaules .. */
            if( strstr(old_buffer, "Port") && ! strcmp(old_buffer, port_buffer) )
            {
                found_server = 1;
                break;
            }
            
            if( strstr(old_buffer, "</VirtualHost>") )
              break;
          }    
      }

      /* Continue until we find the selected server */
      if( ! found_server )
        continue;

      if( found_server )
        break;

      /* Dont change AllowFrom... */
      if( strstr(old_buffer, "<Anonymous") )
        break;
    }


    /* Check if the user exists in this server.... */
    if( conf_size > 1 )
    while(fgets(old_buffer, conf_size, fp)!=NULL)
    {
      if( strlen(old_buffer) > 8000 )
      {
          fclose(fp);
          free(old_buffer);
          free(user_check);
          free(address_buffer);
          free(port_buffer);
          return;
      }

      /* Does this user exist in this server... */
      if( ! strcmp(old_buffer, user_check) && ! strstr(old_buffer, "AllowUser") )
      {
          info = g_strdup_printf(_("The user: \"%s\" was not imported\nbecause it already existed in this server.\n"), username);
          show_info(info);
          g_free(info);
          free(old_buffer);
          free(user_check);
          free(address_buffer);
          free(port_buffer);
          fclose(fp);
          return;
      }

      /* Dont match users in vhosts for the defualt server */
      if( ! strstr((char *)global_server_type, "Virtualhost") )
      {
          if( strstr(old_buffer, "<VirtualHost") )
            break;
      }

      if( strstr(old_buffer, "</VirtualHost>") )
        break;
    }
    free(user_check);
    free(old_buffer);
    fclose(fp);


    /* Make the users ftp home directory and chmod it to 0755 if it doesnt exist */
    if( ! gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widgets->import_with_username_checkbutton)) )
      directory = g_strdup_printf("%s", import_root_dir);
    else
      directory = g_strdup_printf("%s/%s", import_root_dir, username);

    if( ! file_exists((gchar *)directory) ) 
      make_dir_chmod((gchar *)directory, "0755");

    /* Create the users profile */
    user_settings = allocate(16384);
    strcpy(user_settings, "\n<Anonymous ");
    strcat(user_settings, directory);
    strcat(user_settings, ">\n");
    strcat(user_settings, "User ");
    strcat(user_settings, username);
    strcat(user_settings, "\nGroup ");
    strcat(user_settings, groupname);
    strcat(user_settings, "\n");
    strcat(user_settings, "AnonRequirePassword on\n");
    strcat(user_settings, "MaxClients 3 \"The server is full, hosting %m users\"\n");
    strcat(user_settings, "DisplayLogin welcome.msg\n");

//  Sorry, Fedora backported but forgot this ?
//    if( strstr(global_version, "1.2.") || strstr(global_version, "1.3.0") )
//      strcat(user_settings, "DisplayFirstChdir .msg\n");
//    else
//      strcat(user_settings, "DisplayChdir .msg\n");

    strcat(user_settings, "AllowOverwrite off\n");
    strcat(user_settings, "<Limit LOGIN>\n");
    strcat(user_settings, " Allow from all\n");
    strcat(user_settings, " Deny from all\n");
    strcat(user_settings, "</Limit>\n");
    strcat(user_settings, "<Limit RETR LIST NLST MDTM SIZE STAT CWD XCWD PWD XPWD CDUP XCUP>\n");
    strcat(user_settings, " AllowAll\n");
    strcat(user_settings, "</Limit>\n");
    strcat(user_settings, "<Limit DELE APPE STOR STOU SITE_CHMOD SITE_CHGRP RNFR RNTO MKD XMKD RMD XRMD>\n");
    strcat(user_settings, " DenyAll\n");
    strcat(user_settings, "</Limit>\n");
    strcat(user_settings, "</Anonymous>\n");

    g_free(directory);


    /* Add the new user settings to proftpd.conf in the correct server context.
     * Add AllowUser to the selected server. */
    
    found_server = 0;

    /* Standard server selected, start adding users directly */
    if( ! strstr((char *)global_server_type, "Virtualhost") )
      found_server = 1;


    /* Add AllowUser UserName to proftpd.conf to the right server */
    if((fp=fopen(PROFTPD_CONF,"r"))==NULL)
    {
      free(address_buffer);
      free(port_buffer);
      free(user_settings);
      return;
    }
    fseek(fp, 0, SEEK_END);
    conf_size = ftell(fp);
    rewind(fp);

    old_buffer = allocate(conf_size);
    /* The new_buffer will probably also contain the user_settings */
    new_buffer = allocate(conf_size+8192);

    /* Add the new user to the new conf */
    if( conf_size > 1 )
    while(fgets(old_buffer, conf_size, fp)!=NULL)
    {
      if( strlen(old_buffer) > 4000 )
      {
          fclose(fp);
          free(old_buffer);
          free(address_buffer);
          free(port_buffer);
          free(new_buffer);
          free(user_settings);
          return;
      }

      strcat(new_buffer, old_buffer);

        if( strstr("Virtualhost", (char *)global_server_type) && ! found_server
      &&  ! strcmp(old_buffer, address_buffer) )
      {
          /* Lets see if its the same port as the selected one */
          /* If this server has the same port its the correct server. */
          while(fgets(old_buffer, conf_size, fp)!=NULL)
          {
            if( strlen(old_buffer) > 4000 )
              continue;

            strcat(new_buffer, old_buffer);

            /* This will expect the servers port on the second line ! 
             * else itll miss some values .. */
            if( strstr(old_buffer, "Port") && ! strcmp(old_buffer, port_buffer) )
            {
                found_server = 1;
                break;
            }
            
            if( strstr(old_buffer, "</Virtualhost>") )
              break;
          }    
      }

      
      /* Continue until we find the selected server */
      if( ! found_server )
        continue;


      /* Add AllowUSer Username .. to this server only */
      if( strstr(old_buffer, "<Limit LOGIN>") && found_server && ! limit_access )
      {
          strcat(new_buffer, "  AllowUser ");
          strcat(new_buffer, username);
          strcat(new_buffer, "\n");
          limit_access = 1; /* just incase so we just change the first occurance */
          
          /* Add the user after </Limit> */
          while(fgets(old_buffer, conf_size, fp)!=NULL)
          {
             strcat(new_buffer, old_buffer);
             if( strstr(old_buffer, "</Limit>") && limit_access==1 )
             {
                /* Only add it once */
                limit_access = 2;
                /* The user was added after </Limit> */               

                /* Global */
                num_imported++;
                
                strcat(new_buffer, user_settings);
             }
          }
      }
      
      /* Add the new user_settings if we have another user (once) */
      if( strstr(old_buffer, "</Anonymous") && limit_access==1 )
      {
         /* Only add it once */
         limit_access = 2;
         /* The user was added after the first user */

          /* Global */
          num_imported++;

         strcat(new_buffer, user_settings);
      }
    }
    fclose(fp);
    free(old_buffer);      
    free(address_buffer);
    free(port_buffer);
    free(user_settings);

    g_free(username);
    g_free(groupname);

    /* Write the new configuration */
    if((fp=fopen(PROFTPD_CONF,"w+"))==NULL)
    {
      free(new_buffer);
        return;
    }

    fputs(new_buffer, fp);
    fclose(fp);
    free(new_buffer);      
}


void import_button_clicked(GtkButton *button, struct w *widgets)
{
    /* Add all the marked users to the selected server, 
     * make dirs and allow them to login */
    GtkTreeSelection *selection;
    G_CONST_RETURN gchar *g_home_dir;
    gchar *info=NULL;

    /* Globals */
    num_imported = 0;
    strcpy(import_root_dir, "");

    g_home_dir = gtk_entry_get_text(GTK_ENTRY(widgets->import_home_entry));

    if( strlen(g_home_dir) <= 4000 )
      sprintf(import_root_dir, g_home_dir);
    else
      {
       info = g_strdup_printf(_("Error: Home directory too long: %s\n"), g_home_dir);
       show_info(info);
       g_free(info);
         return;
      }

    /* Call foreach on the users */
    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widgets->import_treeview));

    gtk_tree_selection_selected_foreach(GTK_TREE_SELECTION(selection),
                                       (GtkTreeSelectionForeachFunc) &add_import_users, widgets);

    /* Update the user treeview and settings and the conf tab. */
    populate_users(widgets);
    populate_conf_tab(widgets);

    gtk_widget_destroy(widgets->import_window);

    info = g_strdup_printf(_("Total number of imported users: %ld\n"), num_imported);
    show_info(info);
    g_free(info);

    reread_conf(widgets);
}

Generated by  Doxygen 1.6.0   Back to index