/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Tool to create a directory with the right SELinux context applied, or
 * apply the context if it's absent. Also fixes mode, uid, gid.
 */

#include <iostream>
#include <string>
#include <vector>

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <android-base/logging.h>
#include <android-base/scopeguard.h>

#include <cutils/fs.h>
#include <selinux/android.h>

#include "Utils.h"
#include "android/os/IVold.h"

#include <private/android_filesystem_config.h>

static void usage(const char* progname) {
    std::cerr << "Usage: " << progname << " [ prepare | destroy ] <volume_uuid> <user_id> <flags>"
              << std::endl;
    exit(-1);
}

static bool small_int(const std::string& s) {
    return !s.empty() && s.size() < 7 && s.find_first_not_of("0123456789") == std::string::npos;
}

static bool valid_uuid(const std::string& s) {
    return s.size() < 40 && s.find_first_not_of("0123456789abcdefABCDEF-_") == std::string::npos;
}

static bool prepare_dir_for_user(struct selabel_handle* sehandle, mode_t mode, uid_t uid, gid_t gid,
                                 const std::string& path, uid_t user_id) {
    auto clearfscreatecon = android::base::make_scope_guard([] { setfscreatecon(nullptr); });
    auto secontext = std::unique_ptr<char, void (*)(char*)>(nullptr, freecon);
    char* tmp_secontext;

    if (selabel_lookup(sehandle, &tmp_secontext, path.c_str(), S_IFDIR) == 0) {
        secontext.reset(tmp_secontext);
        if (user_id != (uid_t)-1) {
            if (selinux_android_context_with_level(secontext.get(), &tmp_secontext, user_id,
                                                   (uid_t)-1) != 0) {
                PLOG(ERROR) << "Unable to create context with level for: " << path;
                return false;
            }
            secontext.reset(tmp_secontext);
        }
        if (setfscreatecon(secontext.get()) != 0) {
            LOG(ERROR) << "Failed to setfscreatecon for directory " << path;
            return false;
        }
    } else if (errno == ENOENT) {
        LOG(DEBUG) << "No selabel defined for directory " << path;
    } else {
        PLOG(ERROR) << "Failed to look up selabel for directory " << path;
        return false;
    }

    LOG(DEBUG) << "Setting up mode " << std::oct << mode << std::dec << " uid " << uid << " gid "
               << gid << " context " << (secontext ? secontext.get() : "null")
               << " on path: " << path;
    if (fs_prepare_dir(path.c_str(), mode, uid, gid) != 0) {
        return false;
    }
    if (secontext) {
        char* tmp_oldsecontext = nullptr;
        if (lgetfilecon(path.c_str(), &tmp_oldsecontext) < 0) {
            PLOG(ERROR) << "Unable to read secontext for: " << path;
            return false;
        }
        auto oldsecontext = std::unique_ptr<char, void (*)(char*)>(tmp_oldsecontext, freecon);
        if (strcmp(secontext.get(), oldsecontext.get()) != 0) {
            LOG(INFO) << "Relabelling from " << ((char*)oldsecontext.get()) << " to "
                      << ((char*)secontext.get()) << ": " << path;
            if (lsetfilecon(path.c_str(), secontext.get()) != 0) {
                PLOG(ERROR) << "Relabelling failed for: " << path;
                return false;
            }
        }
    }
    return true;
}

static bool prepare_dir(struct selabel_handle* sehandle, mode_t mode, uid_t uid, gid_t gid,
                        const std::string& path) {
    return prepare_dir_for_user(sehandle, mode, uid, gid, path, (uid_t)-1);
}

static bool rmrf_contents(const std::string& path) {
    auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(path.c_str()), closedir);
    if (!dirp) {
        if (errno == ENOENT) {
            return true;
        }
        PLOG(ERROR) << "Unable to open directory: " << path;
        return false;
    }
    bool res = true;
    for (;;) {
        errno = 0;
        auto const entry = readdir(dirp.get());
        if (!entry) {
            if (errno) {
                PLOG(ERROR) << "readdir failed on: " << path;
                return false;
            }
            return res;
        }
        if (entry->d_name[0] == '.') continue;
        auto subdir = path + "/" + entry->d_name;
        if (0 !=
            android::vold::ForkExecvp(std::vector<std::string>{"/system/bin/rm", "-rf", subdir})) {
            LOG(ERROR) << "rm -rf failed on " << subdir;
            res = false;
        }
    }
}

static bool prepare_apex_subdirs(struct selabel_handle* sehandle, const std::string& path) {
    if (!prepare_dir(sehandle, 0711, 0, 0, path + "/apexdata")) return false;

    // Since vold/vold_prepare_subdirs run in the bootstrap mount namespace
    // we can't get the full list of APEXes by scanning /apex directory.
    // Instead, we can look up /data/misc/apexdata for the list of APEXes,
    // which is populated during `perform_apex_config` in init.
    // Note: `init_user0` should be invoked after `perform_apex_config`.
    auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/data/misc/apexdata"), closedir);
    if (!dirp) {
        PLOG(ERROR) << "Unable to open apex directory";
        return false;
    }
    struct dirent* entry;
    while ((entry = readdir(dirp.get())) != nullptr) {
        if (entry->d_type != DT_DIR) continue;

        const char* name = entry->d_name;
        // skip any starting with "."
        if (name[0] == '.') continue;

        if (!prepare_dir(sehandle, 0771, AID_ROOT, AID_SYSTEM, path + "/apexdata/" + name)) {
            return false;
        }
    }
    return true;
}

static bool prepare_subdirs(const std::string& volume_uuid, int user_id, int flags) {
    struct selabel_handle* sehandle = selinux_android_file_context_handle();
    if (!sehandle) {
        LOG(ERROR) << "Failed to get SELinux file contexts handle";
        return false;
    }

    if (flags & android::os::IVold::STORAGE_FLAG_DE) {
        auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
        if (!prepare_dir_for_user(sehandle, 0771, AID_SYSTEM, AID_SYSTEM, user_de_path, user_id)) {
            return false;
        }

        auto misc_de_path = android::vold::BuildDataMiscDePath(volume_uuid, user_id);
        if (!prepare_dir_for_user(sehandle, 0771, AID_SYSTEM, AID_SYSTEM,
                                  misc_de_path + "/sdksandbox", user_id)) {
            return false;
        }

        if (volume_uuid.empty()) {
            if (!prepare_dir(sehandle, 0700, 0, 0, misc_de_path + "/vold")) return false;
            if (!prepare_dir(sehandle, 0700, 0, 0, misc_de_path + "/storaged")) return false;
            if (!prepare_dir(sehandle, 0700, 0, 0, misc_de_path + "/rollback")) return false;
            // TODO: Return false if this returns false once sure this should succeed.
            prepare_dir(sehandle, 0700, 0, 0, misc_de_path + "/apexrollback");
            prepare_apex_subdirs(sehandle, misc_de_path);

            auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
            if (!prepare_dir_for_user(sehandle, 0771, AID_SYSTEM, AID_SYSTEM, profiles_de_path,
                                      user_id)) {
                return false;
            }

            auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
            if (!prepare_dir(sehandle, 0700, AID_SYSTEM, AID_SYSTEM, vendor_de_path + "/fpdata")) {
                return false;
            }
            auto facedata_path = vendor_de_path + "/facedata";
            if (!prepare_dir(sehandle, 0700, AID_SYSTEM, AID_SYSTEM, facedata_path)) {
                return false;
            }
        }
    }
    if (flags & android::os::IVold::STORAGE_FLAG_CE) {
        auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
        if (!prepare_dir_for_user(sehandle, 0771, AID_SYSTEM, AID_SYSTEM, user_ce_path, user_id)) {
            return false;
        }

        auto misc_ce_path = android::vold::BuildDataMiscCePath(volume_uuid, user_id);
        if (!prepare_dir_for_user(sehandle, 0771, AID_SYSTEM, AID_SYSTEM,
                                  misc_ce_path + "/sdksandbox", user_id)) {
            return false;
        }

        if (volume_uuid.empty()) {
            if (!prepare_dir(sehandle, 0700, 0, 0, misc_ce_path + "/vold")) return false;
            if (!prepare_dir(sehandle, 0700, 0, 0, misc_ce_path + "/storaged")) return false;
            if (!prepare_dir(sehandle, 0700, 0, 0, misc_ce_path + "/rollback")) return false;
            // TODO: Return false if this returns false once sure this should succeed.
            prepare_dir(sehandle, 0700, 0, 0, misc_ce_path + "/apexrollback");
            prepare_apex_subdirs(sehandle, misc_ce_path);
            // Give gmscore (who runs in cache group) access to the checkin directory. Also provide
            // the user id to set the correct selinux mls_level.
            if (!prepare_dir_for_user(sehandle, 0770, AID_SYSTEM, AID_CACHE,
                                      misc_ce_path + "/checkin", user_id)) {
                // TODO(b/203742483) the checkin directory was created with the wrong permission &
                // context. Delete the directory to get these devices out of the bad state. Revert
                // the change once the droidfood population is on newer build.
                LOG(INFO) << "Failed to prepare the checkin directory, deleting for recreation";
                android::vold::DeleteDirContentsAndDir(misc_ce_path + "/checkin");
                if (!prepare_dir_for_user(sehandle, 0770, AID_SYSTEM, AID_CACHE,
                                          misc_ce_path + "/checkin", user_id)) {
                    return false;
                }
            }

            auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
            if (!prepare_dir(sehandle, 0700, AID_SYSTEM, AID_SYSTEM, system_ce_path + "/backup")) {
                return false;
            }
            if (!prepare_dir(sehandle, 0700, AID_SYSTEM, AID_SYSTEM,
                             system_ce_path + "/backup_stage")) {
                return false;
            }
            auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
            auto facedata_path = vendor_ce_path + "/facedata";
            if (!prepare_dir(sehandle, 0700, AID_SYSTEM, AID_SYSTEM, facedata_path)) {
                return false;
            }
        }
    }
    return true;
}

static bool destroy_subdirs(const std::string& volume_uuid, int user_id, int flags) {
    bool res = true;
    if (flags & android::os::IVold::STORAGE_FLAG_CE) {
        auto misc_ce_path = android::vold::BuildDataMiscCePath(volume_uuid, user_id);
        res &= rmrf_contents(misc_ce_path);

        if (volume_uuid.empty()) {
            auto vendor_ce_path = android::vold::BuildDataVendorCePath(user_id);
            res &= rmrf_contents(vendor_ce_path);
        }
    }
    if (flags & android::os::IVold::STORAGE_FLAG_DE) {
        auto misc_de_path = android::vold::BuildDataMiscDePath(volume_uuid, user_id);
        res &= rmrf_contents(misc_de_path);

        if (volume_uuid.empty()) {
            auto vendor_de_path = android::vold::BuildDataVendorDePath(user_id);
            res &= rmrf_contents(vendor_de_path);
        }
    }
    return res;
}

int main(int argc, const char* const argv[]) {
    android::base::InitLogging(const_cast<char**>(argv));
    std::vector<std::string> args(argv + 1, argv + argc);

    if (args.size() != 4 || !valid_uuid(args[1]) || !small_int(args[2]) || !small_int(args[3])) {
        usage(argv[0]);
        return -1;
    }

    auto volume_uuid = args[1];
    int user_id = stoi(args[2]);
    int flags = stoi(args[3]);
    if (args[0] == "prepare") {
        if (!prepare_subdirs(volume_uuid, user_id, flags)) return -1;
    } else if (args[0] == "destroy") {
        if (!destroy_subdirs(volume_uuid, user_id, flags)) return -1;
    } else {
        usage(argv[0]);
        return -1;
    }
    return 0;
}
