int refreshpasswdcache()

in src/cache_refresh/cache_refresh.cc [55:119]


int refreshpasswdcache() {
  syslog(LOG_INFO, "Refreshing passwd entry cache");
  int error_code = 0;
  // Temporary buffer to hold passwd entries before writing.
  char buffer[kPasswdBufferSize];
  struct passwd pwd;
  NssCache nss_cache(kNssPasswdCacheSize);


  std::ofstream cache_file(kDefaultBackupFilePath);
  if (cache_file.fail()) {
    syslog(LOG_ERR, "Failed to open file %s.", kDefaultBackupFilePath);
    return -1;
  }
  cache_file << std::unitbuf; // enable automatic flushing
  chown(kDefaultBackupFilePath, 0, 0);
  chmod(kDefaultBackupFilePath, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

  nss_cache.Reset();
  while (!nss_cache.OnLastPage() || nss_cache.HasNextEntry()) {
    BufferManager buffer_manager(buffer, kPasswdBufferSize);
    if (!nss_cache.NssGetpwentHelper(&buffer_manager, &pwd, &error_code)) {
      if (error_code == ERANGE) {
        syslog(LOG_ERR, "passwd entry size out of range, skipping");
      } else if (error_code == EINVAL) {
        syslog(LOG_ERR, "Malformed passwd entry, skipping");
      } else if (error_code == ENOENT) {
        syslog(LOG_ERR, "Failure getting users, quitting");
        break;
      } else if (error_code == ENOMSG) {
        // ENOMSG means OS Login is not enabled.
        break;
      }
      continue;
    }
    if (strlen(pwd.pw_passwd) == 0) {
      pwd.pw_passwd = (char *)"*";
    }
    cache_file << pwd.pw_name << ":" << pwd.pw_passwd << ":" << pwd.pw_uid
               << ":" << pwd.pw_gid << ":" << pwd.pw_gecos << ":" << pwd.pw_dir
               << ":" << pwd.pw_shell << "\n";
  }
  cache_file.close();

  if (error_code == ENOMSG) {
    remove(kDefaultBackupFilePath);
    return 0;
  } else if (error_code == ENOENT) {
    syslog(LOG_ERR, "Failed to get users, not updating passwd cache file, removing %s.", kDefaultBackupFilePath);
    // If the cache file already exists, we don't want to overwrite it on a
    // server error. So remove the backup file and return here.
    struct stat buffer;
    if (stat(kDefaultFilePath, &buffer) == 0) {
      remove(kDefaultBackupFilePath);
      return 0;
    }
  }

  if (rename(kDefaultBackupFilePath, kDefaultFilePath) != 0) {
    syslog(LOG_ERR, "Error moving %s to %s.", kDefaultBackupFilePath, kDefaultFilePath);
    remove(kDefaultBackupFilePath);
  }

  return 0;
}