/*
 * Copyright (C) 2018 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
 * COPYRIGHT OWNER 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.
 */

#include "grp_pwd_file.h"

#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>

#include <async_safe/log.h>

#include "private/ErrnoRestorer.h"
#include "private/ScopedFd.h"

// This file mmap's /*/etc/passwd and /*/etc/group in order to return their contents without any
// allocations.  Note that these files and the strings contained within them are explicitly not
// null-terminated.  ':'s are used to deliminate fields and '\n's are used to deliminate lines.
// There is a check that the file ends with '\n', such that terminating loops at '\n' ensures that
// memory will be not read beyond the mmap region.

namespace {

void CopyFieldToString(char* dest, const char* source, size_t max) {
  while (*source != ':' && *source != '\n' && max > 1) {
    *dest++ = *source++;
    --max;
  }
  *dest = '\0';
}

bool FieldToUid(const char* field, uid_t* uid) {
  if (field == nullptr) {
    return false;
  }

  char* end = nullptr;
  errno = 0;
  uid_t result = strtoul(field, &end, 0);
  if (errno != 0 || field == end || *end != ':') {
    return false;
  }
  *uid = result;
  return true;
}

// Returns a pointer to one past the end of line.
const char* ParseLine(const char* begin, const char* end, const char** fields, size_t num_fields) {
  size_t fields_written = 0;
  const char* position = begin;
  fields[fields_written++] = position;

  while (position < end && fields_written < num_fields) {
    if (*position == '\n') {
      return position + 1;
    }
    if (*position == ':') {
      fields[fields_written++] = position + 1;
    }
    position++;
  }

  while (position < end && *position != '\n') {
    position++;
  }

  return position + 1;
}

struct PasswdLine {
  const char* name() const {
    return fields[0];
  }
  // Password is not supported.
  const char* uid() const {
    return fields[2];
  }
  const char* gid() const {
    return fields[3];
  }
  // User Info is not supported
  const char* dir() const {
    return fields[5];
  }
  const char* shell() const {
    return fields[6];
  }

  bool ToPasswdState(passwd_state_t* passwd_state) {
    if (name() == nullptr || dir() == nullptr || shell() == nullptr) {
      return false;
    }

    uid_t uid;
    if (!FieldToUid(this->uid(), &uid)) {
      return false;
    }

    gid_t gid;
    if (!FieldToUid(this->gid(), &gid)) {
      return false;
    }

    passwd_state->passwd_.pw_uid = uid;
    passwd_state->passwd_.pw_gid = gid;

    CopyFieldToString(passwd_state->name_buffer_, name(), sizeof(passwd_state->name_buffer_));
    passwd_state->passwd_.pw_name = passwd_state->name_buffer_;

    passwd_state->passwd_.pw_passwd = nullptr;

#ifdef __LP64__
    passwd_state->passwd_.pw_gecos = nullptr;
#endif

    CopyFieldToString(passwd_state->dir_buffer_, dir(), sizeof(passwd_state->dir_buffer_));
    passwd_state->passwd_.pw_dir = passwd_state->dir_buffer_;

    CopyFieldToString(passwd_state->sh_buffer_, shell(), sizeof(passwd_state->sh_buffer_));
    passwd_state->passwd_.pw_shell = passwd_state->sh_buffer_;

    return true;
  }

  static constexpr size_t kNumFields = 7;
  const char* fields[kNumFields] = {};
};

struct GroupLine {
  const char* name() const {
    return fields[0];
  }
  // Password is not supported.
  const char* gid() const {
    return fields[2];
  }
  // User list is not supported (returns simply name)

  bool ToGroupState(group_state_t* group_state) {
    if (name() == nullptr || gid() == nullptr) {
      return false;
    }

    gid_t gid;
    if (!FieldToUid(this->gid(), &gid)) {
      return false;
    }

    group_state->group_.gr_gid = gid;

    CopyFieldToString(group_state->group_name_buffer_, name(),
                      sizeof(group_state->group_name_buffer_));
    group_state->group_.gr_name = group_state->group_name_buffer_;

    group_state->group_.gr_passwd = nullptr;

    group_state->group_.gr_mem = group_state->group_members_;
    group_state->group_.gr_mem[0] = group_state->group_.gr_name;
    group_state->group_.gr_mem[1] = nullptr;

    return true;
  }

  static constexpr size_t kNumFields = 4;
  const char* fields[kNumFields] = {};
};

}  // namespace

MmapFile::MmapFile(const char* filename, const char* required_prefix)
    : filename_(filename), required_prefix_(required_prefix) {
  lock_.init(false);
}

void MmapFile::Unmap() {
  if (status_ == FileStatus::Initialized) {
    size_t size = end_ - start_ + 1;
    munmap(const_cast<char*>(start_), size);
    status_ = FileStatus::Uninitialized;
    start_ = nullptr;
    end_ = nullptr;
  }
}

bool MmapFile::GetFile(const char** start, const char** end) {
  LockGuard guard(lock_);
  if (status_ == FileStatus::Initialized) {
    *start = start_;
    *end = end_;
    return true;
  }
  if (status_ == FileStatus::Error) {
    return false;
  }

  if (!DoMmap()) {
    status_ = FileStatus::Error;
    return false;
  }

  status_ = FileStatus::Initialized;
  *start = start_;
  *end = end_;
  return true;
}

bool MmapFile::DoMmap() {
  ScopedFd fd(open(filename_, O_CLOEXEC | O_NOFOLLOW | O_RDONLY));

  struct stat fd_stat;
  if (fstat(fd.get(), &fd_stat) == -1) {
    return false;
  }

  auto mmap_size = fd_stat.st_size;

  void* map_result = mmap(nullptr, mmap_size, PROT_READ, MAP_SHARED, fd.get(), 0);
  if (map_result == MAP_FAILED) {
    return false;
  }

  start_ = static_cast<const char*>(map_result);
  end_ = start_ + mmap_size - 1;

  if (*end_ != '\n') {
    munmap(map_result, mmap_size);
    return false;
  }

  return true;
}

template <typename Line, typename Predicate>
bool MmapFile::Find(Line* line, Predicate predicate) {
  const char* start;
  const char* end;
  if (!GetFile(&start, &end)) {
    return false;
  }

  const char* line_beginning = start;

  while (line_beginning < end) {
    line_beginning = ParseLine(line_beginning, end, line->fields, line->kNumFields);
#if defined(__ANDROID__)
    // To comply with Treble, users/groups from each partition need to be prefixed with
    // the partition name.
    if (required_prefix_ != nullptr) {
      if (strncmp(line->fields[0], required_prefix_, strlen(required_prefix_)) != 0) {
        char name[kGrpPwdBufferSize];
        CopyFieldToString(name, line->fields[0], sizeof(name));
        async_safe_format_log(ANDROID_LOG_ERROR, "libc",
                              "Found user/group name '%s' in '%s' without required prefix '%s'",
                              name, filename_, required_prefix_);
        continue;
      }
    }
#endif
    if (predicate(line)) return true;
  }

  return false;
}

template <typename Line>
bool MmapFile::FindById(uid_t uid, Line* line) {
  return Find(line, [uid](const auto& line) {
    uid_t line_id;
    if (!FieldToUid(line->fields[2], &line_id)) {
      return false;
    }

    return line_id == uid;
  });
}

template <typename Line>
bool MmapFile::FindByName(const char* name, Line* line) {
  return Find(line, [name](const auto& line) {
    const char* line_name = line->fields[0];
    if (line_name == nullptr) {
      return false;
    }

    const char* match_name = name;
    while (*line_name != '\n' && *line_name != ':' && *match_name != '\0') {
      if (*line_name++ != *match_name++) {
        return false;
      }
    }

    return *line_name == ':' && *match_name == '\0';
  });
}

PasswdFile::PasswdFile(const char* filename, const char* required_prefix)
    : mmap_file_(filename, required_prefix) {
}

bool PasswdFile::FindById(uid_t id, passwd_state_t* passwd_state) {
  ErrnoRestorer errno_restorer;
  PasswdLine passwd_line;
  return mmap_file_.FindById(id, &passwd_line) && passwd_line.ToPasswdState(passwd_state);
}

bool PasswdFile::FindByName(const char* name, passwd_state_t* passwd_state) {
  ErrnoRestorer errno_restorer;
  PasswdLine passwd_line;
  return mmap_file_.FindByName(name, &passwd_line) && passwd_line.ToPasswdState(passwd_state);
}

GroupFile::GroupFile(const char* filename, const char* required_prefix)
    : mmap_file_(filename, required_prefix) {
}

bool GroupFile::FindById(gid_t id, group_state_t* group_state) {
  ErrnoRestorer errno_restorer;
  GroupLine group_line;
  return mmap_file_.FindById(id, &group_line) && group_line.ToGroupState(group_state);
}

bool GroupFile::FindByName(const char* name, group_state_t* group_state) {
  ErrnoRestorer errno_restorer;
  GroupLine group_line;
  return mmap_file_.FindByName(name, &group_line) && group_line.ToGroupState(group_state);
}
