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