Package cu.ftpd.user.userbases

Source Code of cu.ftpd.user.userbases.UserbaseConverter

/**
* Copyright (c) 2007, Markus Jevring <markus@jevring.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
* 3. The names of the contributors may not be used to endorse or promote
*    products derived from this software without specific prior written
*    permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/

/**
* Copyright (c) 2005, Markus Jevring <markus@jevring.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
* 3. The names of the contributors may not be used to endorse or promote
*    products derived from this software without specific prior written
*    permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
package cu.ftpd.user.userbases;

import cu.ftpd.user.User;
import cu.ftpd.user.UserPermission;
import cu.ftpd.user.groups.Group;
import cu.ftpd.user.groups.GroupExistsException;
import cu.ftpd.user.groups.NoSuchGroupException;
import cu.ftpd.user.statistics.StatisticsEntry;
import cu.ftpd.user.statistics.UserStatistics;
import cu.ftpd.user.statistics.local.LocalUserStatistics;
import cu.ftpd.user.userbases.local.LocalUser;
import cu.ftpd.user.userbases.local.LocalUserbase;
import cu.ftpd.user.userbases.UserExistsException;

import java.io.*;
import java.util.HashMap;

/**
* This class converts a glftpd 2.01 userbase to a cuftpd userbase.
*
* @author Markus Jevring <markus@jevring.net>
* @since 2007-12-15 - 21:00:00
* @version $Id: UserbaseConverter.java 258 2008-10-26 12:47:23Z jevring $
*/
public class UserbaseConverter {
    /*
    get the location of the glftpd root installation directory
    get the location of the data directory
    read /etc/passwd
        store user->password hash
    read userfiles
        convert each entry to a cuftpd userfile entry
        convert the statistics to userstatistics entries
        insert the hashed password
    read general groupfile
    read groupfiles
        for each groupfile, create a line in our groupfile
     */
    private final HashMap<String, String> passwords = new HashMap<String, String>();
    private final LocalUserbase userbase;
    private final File glftpdRoot;
    private final LocalUserStatistics statistics;

    public UserbaseConverter(String glftpdRoot, String cuftpdDataDirectory) throws IOException {
        final File dataDirectory = new File(cuftpdDataDirectory);
        dataDirectory.mkdirs();
        new File(dataDirectory, "/users").mkdirs();
        final File statisticsDir = new File(dataDirectory, "/logs/userstatistics");
        statisticsDir.mkdirs();
        userbase = new LocalUserbase(dataDirectory, false, null);
        statistics = new LocalUserStatistics(statisticsDir);
        this.glftpdRoot = new File(glftpdRoot);
    }

    public void convert() {
        try {
            readPasswords();
        } catch (IOException e) {
            System.err.println("Failed to read glftpd passwd file: " + e.getMessage());
        }
        createUsers();
        try {
            createGroups();
        } catch (IOException e) {
            System.err.println("Failed to read groupfile: " + e.getMessage());
        }
    }

    private void createGroups() throws IOException {
        // read the groups-file, and for each group, read the correspoding groupfile, and create a cuftpd group with the same name, description, and slots (and allotment)
        BufferedReader in = null;
        try {
            File groupfile = new File(glftpdRoot, "/etc/group");
            in = new BufferedReader(new InputStreamReader(new FileInputStream(groupfile)));
            String line;
            while ((line = in.readLine()) != null) {
                String[] parts = line.split(":");
                Group g = null;
                try {
                    g = userbase.createGroup(parts[0], parts[1]);
                } catch (GroupExistsException e) {
                    System.err.println(e.getMessage());
                    System.err.println("skipping...");
                    continue;
                }
                File detailedGroupfile = new File(glftpdRoot, "/ftp-data/groups/" + g.getName());
                try {
                    fillGroup(g, detailedGroupfile);
                } catch (IOException e) {
                    System.err.println("Failed to read groupfile: " + e.getMessage());
                }
            }
            userbase.saveGroups();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void fillGroup(Group group, File groupfile) throws IOException {
        BufferedReader in = null;
        try {
            in = new BufferedReader(new InputStreamReader(new FileInputStream(groupfile)));
            String line;
            while ((line = in.readLine()) != null) {
                if (line.startsWith("SLOTS")) {
                    String[] parts = line.substring(5).trim().split(" ");
                    // SLOTS, LEECH SLOTS, ALLOTMENT SLOTS, MAX. ALLOTMENT SIZE
                    group.setSlots(Integer.parseInt(parts[0]));
                    group.setLeechSlots(Integer.parseInt(parts[1]));
                    group.setAllotmentSlots(Integer.parseInt(parts[2]));
                    group.setMaxAllotment(Integer.parseInt(parts[3]));
                }
            }
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void createUsers() {
        File userdir = new File(glftpdRoot, "/ftp-data/users");
        File[] users = userdir.listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                // don't include users glftpd or default.user
                return (!"glftpd".equals(name) && !"default.user".equals(name));
            }
        });
        for (int i = 0; i < users.length; i++) {
            File user = users[i];
            try {
                addUser(user);
            } catch (IOException e) {
                System.err.println("Could not read userfile for " + user.getName());
            } catch (NoSuchUserException e) {
                System.err.println(e.getMessage());
            } catch (NoSuchGroupException e) {
                System.err.println(e.getMessage());
            } catch (UserExistsException e) {
                System.err.println(e.getMessage());
            }
        }
    }

    private void addUser(File userfile) throws IOException, UserExistsException, NoSuchUserException, NoSuchGroupException {
        // read the userfile, and for each value, add the corresponding value to a cuftpd user
        if (!userfile.getName().matches("[\\w-]+")) {
            System.err.println("Illegal username: " + userfile.getName());
            return;
        }
        LocalUser user = userbase.addUser(userfile.getName(), "WILL_BE_CHANGED", false);
        user.passwd(passwords.get(user.getUsername()), false);
        BufferedReader in = null;
        try {
            in = new BufferedReader(new InputStreamReader(new FileInputStream(userfile)));
            String line;
            boolean hasPrimaryGroupSet = false;
            while ((line = in.readLine()) != null) {
                if (line.startsWith("RATIO")) {
                    String[] parts = line.substring(5).trim().split(" ");
                    if ("0".equals(parts[0].trim())) {
                        userbase.setLeechForUser(true, user.getUsername(), null, false);
                    }
                } else if (line.startsWith("CREDITS")) {
                    String[] parts = line.substring(7).trim().split(" ");
                    user.setCredits(Long.parseLong(parts[0].trim()), false);
                } else if (line.startsWith("TAGLINE")) {
                    user.setTagline(line.substring(7).trim(), false);
                } else if (line.startsWith("TIME")) {
                    String[] parts = line.substring(4).trim().split(" ");
                    user.setLastlog(Long.parseLong(parts[1].trim()), false);
                } else if (line.startsWith("ADDED")) {
                    /* _todo: we can't set created from the inside. we'll let them be created when the script is run then instead
                    String[] parts = line.substring(5).trim().split(" ");
                    user.setCreated(line.substring(5).trim());
                    */
                } else if (line.startsWith("IP")) {
                    user.addIp(line.substring(2).trim(), false);
                } else if (line.startsWith("DNS")) {
                    user.addIp(line.substring(3).trim(), false);
                } else if (line.startsWith("LOGINS")) {
                    String[] parts = line.substring(6).trim().split(" ");
                    user.setLastlog(Long.parseLong(parts[0].trim()), false);
                } else if (line.startsWith("GENERAL")) {
                    String[] parts = line.substring(7).trim().split(" ");
                    userbase.setAllotmentForUser(Long.parseLong(parts[0].substring(parts[0].indexOf(',') + 1)), user.getUsername(), null, false);
                } else if (line.startsWith("FLAGS")) {
                    String flags = line.substring(5);
                    if (flags.contains("D")) {
                        user.addPermission(UserPermission.KICK, false);
                    }
                    if (flags.contains("F") || flags.contains("G")) {
                        user.addPermission(UserPermission.CREDITS, false);
                    }
                    if (flags.contains("H")) {
                        user.addPermission(UserPermission.VIEWUSER, false);
                    }

                    // flag D = UserPermission.KICK
                    // flag F | G = UserPermission.CREDITS
                    // flag H = UserPermission.VIEWUSER
                } else if (line.startsWith("ALLUP")) {
                    // _todo: find out the real format for stats
                    // one "set" of values for each section
                    StatisticsEntry se = statistics.getUserStatistics(user.getUsername(), "default");
                    String[] parts = line.substring(5).trim().split(" ");
                    se.set(UserStatistics.ALLUP_FILES, Long.parseLong(parts[0]));
                    se.set(UserStatistics.ALLUP_BYTES, Long.parseLong(parts[1]) / 1024);
                    se.set(UserStatistics.ALLUP_TIME, Long.parseLong(parts[2]) / 1000);
                    statistics.store(se);
                } else if (line.startsWith("ALLDN")) {
                    StatisticsEntry se = statistics.getUserStatistics(user.getUsername(), "default");
                    String[] parts = line.substring(5).trim().split(" ");
                    se.set(UserStatistics.ALLDN_FILES, Long.parseLong(parts[0]));
                    se.set(UserStatistics.ALLDN_BYTES, Long.parseLong(parts[1]) / 1024);
                    se.set(UserStatistics.ALLUP_TIME, Long.parseLong(parts[2]) / 1000);
                    statistics.store(se);
                } else if (line.startsWith("MNUP")) {
                    StatisticsEntry se = statistics.getUserStatistics(user.getUsername(), "default");
                    String[] parts = line.substring(5).trim().split(" ");
                    se.set(UserStatistics.MNUP_FILES, Long.parseLong(parts[0]));
                    se.set(UserStatistics.MNUP_BYTES, Long.parseLong(parts[1]) / 1024);
                    se.set(UserStatistics.MNUP_TIME, Long.parseLong(parts[2]) / 1000);
                    statistics.store(se);
                } else if (line.startsWith("MNDN")) {
                    StatisticsEntry se = statistics.getUserStatistics(user.getUsername(), "default");
                    String[] parts = line.substring(5).trim().split(" ");
                    se.set(UserStatistics.MNDN_FILES, Long.parseLong(parts[0]));
                    se.set(UserStatistics.MNDN_BYTES, Long.parseLong(parts[1]) / 1024);
                    se.set(UserStatistics.MNUP_TIME, Long.parseLong(parts[2]) / 1000);
                    statistics.store(se);
                } else if (line.startsWith("WKUP")) {
                    StatisticsEntry se = statistics.getUserStatistics(user.getUsername(), "default");
                    String[] parts = line.substring(5).trim().split(" ");
                    se.set(UserStatistics.WKUP_FILES, Long.parseLong(parts[0]));
                    se.set(UserStatistics.WKUP_BYTES, Long.parseLong(parts[1]) / 1024);
                    se.set(UserStatistics.WKUP_TIME, Long.parseLong(parts[2]) / 1000);
                    statistics.store(se);
                } else if (line.startsWith("WKDN")) {
                    StatisticsEntry se = statistics.getUserStatistics(user.getUsername(), "default");
                    String[] parts = line.substring(5).trim().split(" ");
                    se.set(UserStatistics.WKDN_FILES, Long.parseLong(parts[0]));
                    se.set(UserStatistics.WKDN_BYTES, Long.parseLong(parts[1]) / 1024);
                    se.set(UserStatistics.WKUP_TIME, Long.parseLong(parts[2]) / 1000);
                    statistics.store(se);
                } else if (line.startsWith("DAYUP")) {
                    StatisticsEntry se = statistics.getUserStatistics(user.getUsername(), "default");
                    String[] parts = line.substring(5).trim().split(" ");
                    se.set(UserStatistics.DAYUP_FILES, Long.parseLong(parts[0]));
                    se.set(UserStatistics.DAYUP_BYTES, Long.parseLong(parts[1]) / 1024);
                    se.set(UserStatistics.DAYUP_TIME, Long.parseLong(parts[2]) / 1000);
                    statistics.store(se);
                } else if (line.startsWith("DAYDN")) {
                    StatisticsEntry se = statistics.getUserStatistics(user.getUsername(), "default");
                    String[] parts = line.substring(5).trim().split(" ");
                    se.set(UserStatistics.DAYDN_FILES, Long.parseLong(parts[0]));
                    se.set(UserStatistics.DAYDN_BYTES, Long.parseLong(parts[1]) / 1024);
                    se.set(UserStatistics.DAYUP_TIME, Long.parseLong(parts[2]) / 1000);
                    statistics.store(se);
                } else if (line.startsWith("GROUP")) {
                    String[] groupdata = line.substring(5).trim().split(" ", 2);
                    final String group = groupdata[0].trim();
                    user.addGroup(group);
                    if ("1".equals(groupdata[1].trim())) {
                        user.addGadminForGroup(group, false);
                    }
                    if (!hasPrimaryGroupSet) {
                        hasPrimaryGroupSet = true;
                        user.setPrimaryGroup(group, false);
                    }
                }
            }
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }

    private void readPasswords() throws IOException {
        BufferedReader passwords = new BufferedReader(new InputStreamReader(new FileInputStream(new File(glftpdRoot, "/etc/passwd"))));
        String password;
        while ((password = passwords.readLine()) != null) {
            String[] parts = password.split(":");
            this.passwords.put(parts[0], parts[1]);
        }
        passwords.close();
    }

    public static void main(String[] args) {
        if (args.length == 2) {
            System.out.println("glftpd dir: " + args[0]);
            System.out.println("cuftpd data dir: " + args[1]);
            System.out.println("NOTE: this will only process the first section in the userfiles.");
            UserbaseConverter uc = null;
            try {
                uc = new UserbaseConverter(args[0], args[1]);
                uc.convert();
                System.out.println("Conversion complete.");
            } catch (IOException e) {
                System.err.println("Conversion FAILED");
                System.err.println(e.getMessage());
            }
        } else {
            System.out.println("Use: java -jar converter.jar glftpd_root_path cuftpd_data_directory");
        }

    }
}
TOP

Related Classes of cu.ftpd.user.userbases.UserbaseConverter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.