117 lines
2.8 KiB
C++
117 lines
2.8 KiB
C++
#include <fcntl.h>
|
|
#include <shadow.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
static struct spwd spwd;
|
|
static FILE* f { nullptr };
|
|
static char s_buf[4096];
|
|
|
|
extern char* _strtok_once(char* str, const char* delim);
|
|
|
|
extern "C"
|
|
{
|
|
struct spwd* getspent()
|
|
{
|
|
struct spwd* result;
|
|
|
|
if (getspent_r(&spwd, s_buf, sizeof(s_buf), &result) < 0) return nullptr;
|
|
|
|
return result;
|
|
}
|
|
|
|
int getspent_r(struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp)
|
|
{
|
|
*spbufp = nullptr;
|
|
|
|
if (!f)
|
|
{
|
|
f = fopen("/etc/shadow", "r");
|
|
if (!f) return -1;
|
|
fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
|
|
}
|
|
|
|
return fgetspent_r(f, spbuf, buf, buflen, spbufp);
|
|
}
|
|
|
|
int fgetspent_r(FILE* stream, struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp)
|
|
{
|
|
*spbufp = nullptr;
|
|
|
|
while (true)
|
|
{
|
|
char* rc = fgets(buf, buflen, stream);
|
|
if (!rc) return -1;
|
|
|
|
char* name = _strtok_once(rc, ":\n");
|
|
if (!name) continue;
|
|
|
|
char* passwd = _strtok_once(nullptr, ":\n");
|
|
if (!passwd) continue;
|
|
|
|
char* lstchg = _strtok_once(nullptr, ":\n");
|
|
if (!lstchg) continue;
|
|
|
|
char* min = _strtok_once(nullptr, ":\n");
|
|
if (!min) continue;
|
|
|
|
char* max = _strtok_once(nullptr, ":\n");
|
|
if (!max) continue;
|
|
|
|
char* warn = _strtok_once(nullptr, ":\n");
|
|
if (!warn) continue;
|
|
|
|
char* inact = _strtok_once(nullptr, ":\n");
|
|
if (!inact) continue;
|
|
|
|
char* expire = _strtok_once(nullptr, ":\n");
|
|
if (!expire) continue;
|
|
|
|
char* flag = _strtok_once(nullptr, ":\n");
|
|
if (!flag) continue;
|
|
|
|
spbuf->sp_namp = name;
|
|
spbuf->sp_pwdp = passwd;
|
|
spbuf->sp_lstchg = (long)strtol(lstchg, nullptr, 10);
|
|
spbuf->sp_min = (long)strtol(min, nullptr, 10);
|
|
spbuf->sp_max = (long)strtol(max, nullptr, 10);
|
|
spbuf->sp_warn = (long)strtol(warn, nullptr, 10);
|
|
spbuf->sp_inact = (long)strtol(inact, nullptr, 10);
|
|
spbuf->sp_expire = (long)strtol(expire, nullptr, 10);
|
|
spbuf->sp_flag = (unsigned long)strtoul(flag, nullptr, 10);
|
|
|
|
*spbufp = spbuf;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
struct spwd* getspnam(const char* name)
|
|
{
|
|
setspent();
|
|
|
|
struct spwd* entry;
|
|
|
|
while ((entry = getspent()))
|
|
{
|
|
if (!strcmp(entry->sp_namp, name)) { return entry; }
|
|
}
|
|
|
|
return entry;
|
|
}
|
|
|
|
void setspent()
|
|
{
|
|
if (f) rewind(f);
|
|
}
|
|
|
|
void endspent()
|
|
{
|
|
if (f)
|
|
{
|
|
fclose(f);
|
|
f = nullptr;
|
|
}
|
|
}
|
|
}
|