Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d65988fcf0 | ||
|
|
4360d2fd2e |
+1
-1
@@ -64,7 +64,7 @@ typedef struct __res_state {
|
||||
#define __RES 19960801
|
||||
|
||||
#ifndef _PATH_RESCONF
|
||||
#define _PATH_RESCONF "/etc/resolv.conf"
|
||||
#define _PATH_RESCONF "/var/config/network/resolv.conf"
|
||||
#endif
|
||||
|
||||
struct res_sym {
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@
|
||||
#define ICONV_ERR_ILLEGAL_OPCODE -4
|
||||
#define ICONV_ERR_MEMORY_OVERFLOW -5
|
||||
|
||||
#define ICONV_CHARSET_PATH_PREFIX "/etc/iconv/"
|
||||
#define ICONV_CHARSET_PATH_PREFIX "/share/iconv/"
|
||||
|
||||
static const uint8_t vm_binary_magic[4] = { 'S', 'I', 'C', 'V' };
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ static void reverse_hosts(char *buf, const unsigned char *a, unsigned scopeid, i
|
||||
char line[512], *p, *z;
|
||||
unsigned char _buf[1032], atmp[16];
|
||||
struct address iplit;
|
||||
FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
|
||||
FILE _f, *f = __fopen_rb_ca("/var/config/network/hosts", &_f, _buf, sizeof _buf);
|
||||
if (!f) return;
|
||||
if (family == AF_INET) {
|
||||
memcpy(atmp+12, a, 4);
|
||||
@@ -71,7 +71,7 @@ static void reverse_hosts(char *buf, const unsigned char *a, unsigned scopeid, i
|
||||
|
||||
if (memcmp(a, iplit.addr, 16) || iplit.scopeid != scopeid)
|
||||
continue;
|
||||
|
||||
|
||||
for (; *p && isspace(*p); p++);
|
||||
for (z=p; *z && !isspace(*z); z++);
|
||||
*z = 0;
|
||||
@@ -116,7 +116,7 @@ static int dns_parse_callback(void *c, int rr, const void *data, int len, const
|
||||
data, c, 256) <= 0)
|
||||
*(char *)c = 0;
|
||||
return 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int getnameinfo(const struct sockaddr *restrict sa, socklen_t sl,
|
||||
|
||||
@@ -52,7 +52,7 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
|
||||
size_t l = strlen(name);
|
||||
int cnt = 0, badfam = 0, have_canon = 0;
|
||||
unsigned char _buf[1032];
|
||||
FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
|
||||
FILE _f, *f = __fopen_rb_ca("/var/config/network/hosts", &_f, _buf, sizeof _buf);
|
||||
if (!f) switch (errno) {
|
||||
case ENOENT:
|
||||
case ENOTDIR:
|
||||
|
||||
@@ -18,7 +18,7 @@ int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
|
||||
conf->attempts = 2;
|
||||
if (search) *search = 0;
|
||||
|
||||
f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
|
||||
f = __fopen_rb_ca("/var/config/network/resolv.conf", &_f, _buf, sizeof _buf);
|
||||
if (!f) switch (errno) {
|
||||
case ENOENT:
|
||||
case ENOTDIR:
|
||||
|
||||
@@ -0,0 +1,404 @@
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "spp.h"
|
||||
#include "json.h"
|
||||
|
||||
#ifndef _ACCOUNT_CLIENT
|
||||
#define _ACCOUNT_CLIENT
|
||||
|
||||
#define REQ2(condition, err) if (!(condition)) { errno = err; return -1; }
|
||||
#define REQ(condition) REQ2(condition, EPERM)
|
||||
#define REQP2(condition, err) if (!(condition)) { errno = err; return NULL; }
|
||||
#define REQP(condition) REQP2(condition, EPERM)
|
||||
#define ITEROBJ(obj, it) for (struct json_object_element_s *it = obj->start; it != NULL; it = it->next)
|
||||
#define DECLPOOL(pool, buf, size) struct account_memory_pool pool = { .ptr = buf, .len = size, .cursor = 0 }
|
||||
|
||||
#ifdef __linux__
|
||||
static inline int account_connect() {
|
||||
return spp_connect_linux("verified:org.semilabs.os/accountd");
|
||||
}
|
||||
#else
|
||||
static inline int account_connect() {
|
||||
return spp_connect_unix("/var/run/accountd.sock");
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
|
||||
struct account_memory_pool {
|
||||
void *ptr;
|
||||
size_t cursor;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
static inline void *account_allocate_pool(struct account_memory_pool *pool, size_t size) {
|
||||
if (!pool || !pool->ptr || size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (pool->cursor + size > pool->len) {
|
||||
return NULL;
|
||||
}
|
||||
void *result = (char *)pool->ptr + pool->cursor;
|
||||
pool->cursor += size;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline int account_recordpw(
|
||||
struct json_value_s *root,
|
||||
struct passwd *passwd,
|
||||
struct account_memory_pool *pool
|
||||
) {
|
||||
passwd->pw_passwd = account_allocate_pool(pool, 2);
|
||||
REQ2(passwd->pw_passwd, ERANGE);
|
||||
strcpy(passwd->pw_passwd, "x");
|
||||
|
||||
passwd->pw_gecos = account_allocate_pool(pool, 1);
|
||||
REQ2(passwd->pw_gecos, ERANGE);
|
||||
strcpy(passwd->pw_gecos, "");
|
||||
|
||||
struct json_object_s *object = json_value_as_object(root);
|
||||
REQ(object);
|
||||
ITEROBJ(object, it) {
|
||||
const char *name = it->name->string;
|
||||
struct json_value_s *value = it->value;
|
||||
|
||||
if (strcmp(name, "username") == 0) {
|
||||
struct json_string_s *username = json_value_as_string(value);
|
||||
REQ(username);
|
||||
passwd->pw_name = account_allocate_pool(pool, username->string_size + 1);
|
||||
REQ2(passwd->pw_name, ERANGE);
|
||||
strcpy(passwd->pw_name, username->string);
|
||||
continue;
|
||||
}
|
||||
if (strcmp(name, "home_directory") == 0) {
|
||||
struct json_string_s *homedir = json_value_as_string(value);
|
||||
REQ(homedir);
|
||||
passwd->pw_dir = account_allocate_pool(pool, homedir->string_size + 1);
|
||||
REQ2(passwd->pw_dir, ERANGE);
|
||||
strcpy(passwd->pw_dir, homedir->string);
|
||||
continue;
|
||||
}
|
||||
if (strcmp(name, "defaults") == 0) {
|
||||
struct json_object_s *defaults = json_value_as_object(value);
|
||||
REQ(defaults);
|
||||
ITEROBJ(defaults, def) {
|
||||
name = def->name->string;
|
||||
value = def->value;
|
||||
if (strcmp(name, "CliLoginShell") == 0) {
|
||||
struct json_string_s *shell = json_value_as_string(value);
|
||||
REQ(shell);
|
||||
passwd->pw_shell = account_allocate_pool(pool, shell->string_size + 1);
|
||||
REQ2(passwd->pw_shell, ERANGE);
|
||||
strcpy(passwd->pw_shell, shell->string);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (strcmp(name, "host_uid") == 0) {
|
||||
struct json_number_s *uid = json_value_as_number(value);
|
||||
REQ(uid);
|
||||
passwd->pw_uid = atoi(uid->number);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int account_recordgr(
|
||||
struct json_value_s *root,
|
||||
struct group *group,
|
||||
struct account_memory_pool *pool
|
||||
) {
|
||||
group->gr_passwd = account_allocate_pool(pool, 2);
|
||||
REQ2(group->gr_passwd, ERANGE);
|
||||
strcpy(group->gr_passwd, "x");
|
||||
|
||||
struct json_object_s *object = json_value_as_object(root);
|
||||
REQ(object);
|
||||
ITEROBJ(object, it) {
|
||||
const char *name = it->name->string;
|
||||
struct json_value_s *value = it->value;
|
||||
|
||||
if (strcmp(name, "groupname") == 0) {
|
||||
struct json_string_s *groupname = json_value_as_string(value);
|
||||
REQ(groupname);
|
||||
group->gr_name = account_allocate_pool(pool, groupname->string_size + 1);
|
||||
REQ2(group->gr_name, ERANGE);
|
||||
strcpy(group->gr_name, groupname->string);
|
||||
continue;
|
||||
}
|
||||
if (strcmp(name, "host_gid") == 0) {
|
||||
struct json_number_s *gid = json_value_as_number(value);
|
||||
REQ(gid);
|
||||
group->gr_gid = atoi(gid->number);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef int (*pwgr_parser_t)(struct json_value_s*, void*, struct account_memory_pool*);
|
||||
|
||||
static inline int account_getpwgrkey(
|
||||
int fd,
|
||||
const char *method,
|
||||
const char *key,
|
||||
const char *valueborder,
|
||||
const char *name,
|
||||
pwgr_parser_t parser,
|
||||
void *pwgr,
|
||||
struct account_memory_pool *pool
|
||||
) {
|
||||
int status;
|
||||
|
||||
const char *request_template = "{\"method\": \"%s\", \"params\": {\"%s\": %s%s%s}}";
|
||||
int request_need = snprintf(NULL, 0, request_template, method, key, valueborder, name, valueborder);
|
||||
REQ(request_need > 0);
|
||||
char *request_json = malloc(request_need + 1);
|
||||
REQ2(request_json, ENOMEM);
|
||||
snprintf(request_json, request_need + 1, request_template, method, key, valueborder, name, valueborder);
|
||||
status = spp_send(fd, request_json);
|
||||
free(request_json);
|
||||
REQ(status == 0);
|
||||
|
||||
const char *reply_str = spp_recv(fd);
|
||||
REQ(reply_str);
|
||||
|
||||
struct json_value_s *reply = json_parse(reply_str, strlen(reply_str));
|
||||
spp_free((void*)reply_str);
|
||||
REQ(reply);
|
||||
struct json_object_s *reply_object = json_value_as_object(reply);
|
||||
if (!reply_object) goto format_error;
|
||||
ITEROBJ(reply_object, it) {
|
||||
if (strcmp(it->name->string, "success") == 0) {
|
||||
if (json_value_is_false(it->value)) goto not_found;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(it->name->string, "value") == 0) {
|
||||
status = parser(it->value, pwgr, pool);
|
||||
if (status != 0) goto not_found;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
free(reply);
|
||||
return 0;
|
||||
|
||||
format_error:
|
||||
errno = EPERM;
|
||||
not_found:
|
||||
free(reply);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline char *account_list_uuid_next(
|
||||
int fd,
|
||||
const char *method,
|
||||
unsigned int no
|
||||
) {
|
||||
int status;
|
||||
|
||||
const char *request_template = "{\"method\": \"%s\", \"params\": {\"start\": %u, \"len\": 1}}";
|
||||
int request_need = snprintf(NULL, 0, request_template, method, no);
|
||||
REQP(request_need > 0);
|
||||
char *request_json = malloc(request_need + 1);
|
||||
REQP2(request_json, ENOMEM);
|
||||
snprintf(request_json, request_need + 1, request_template, method, no);
|
||||
status = spp_send(fd, request_json);
|
||||
free(request_json);
|
||||
REQP(status == 0);
|
||||
|
||||
const char *reply_str = spp_recv(fd);
|
||||
REQP(reply_str);
|
||||
|
||||
struct json_value_s *reply = json_parse(reply_str, strlen(reply_str));
|
||||
spp_free((void*)reply_str);
|
||||
REQP(reply);
|
||||
struct json_object_s *reply_object = json_value_as_object(reply);
|
||||
if (!reply_object) goto format_error;
|
||||
ITEROBJ(reply_object, it) {
|
||||
if (strcmp(it->name->string, "success") == 0) {
|
||||
if (json_value_is_false(it->value)) goto not_found;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(it->name->string, "value") == 0) {
|
||||
struct json_array_s *list = json_value_as_array(it->value);
|
||||
if (!list) goto not_found;
|
||||
struct json_array_element_s *first = list->start;
|
||||
if (!first) goto not_found;
|
||||
struct json_string_s *item = json_value_as_string(first->value);
|
||||
if (!item) goto format_error;
|
||||
return strdup(item->string);
|
||||
}
|
||||
}
|
||||
|
||||
free(reply);
|
||||
return NULL;
|
||||
|
||||
format_error:
|
||||
errno = EPERM;
|
||||
not_found:
|
||||
free(reply);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int account_getpwuid(
|
||||
int fd,
|
||||
uid_t uid,
|
||||
struct passwd *passwd,
|
||||
struct account_memory_pool *pool
|
||||
) {
|
||||
char uid_str[32];
|
||||
int len = snprintf(uid_str, sizeof(uid_str), "%u", (unsigned int)uid);
|
||||
REQ(len > 0 && (size_t)len < sizeof(uid_str));
|
||||
|
||||
return account_getpwgrkey(
|
||||
fd,
|
||||
"GetUserInfo",
|
||||
"host_uid",
|
||||
"",
|
||||
uid_str,
|
||||
(pwgr_parser_t)account_recordpw,
|
||||
passwd,
|
||||
pool
|
||||
);
|
||||
}
|
||||
|
||||
static inline int account_getpwnam(
|
||||
int fd,
|
||||
const char *name,
|
||||
struct passwd *passwd,
|
||||
struct account_memory_pool *pool
|
||||
) {
|
||||
return account_getpwgrkey(
|
||||
fd,
|
||||
"GetUserInfo",
|
||||
"username",
|
||||
"\"",
|
||||
name,
|
||||
(pwgr_parser_t)account_recordpw,
|
||||
passwd,
|
||||
pool
|
||||
);
|
||||
}
|
||||
|
||||
static inline int account_getpwuuid(
|
||||
int fd,
|
||||
const char *uuid,
|
||||
struct passwd *passwd,
|
||||
struct account_memory_pool *pool
|
||||
) {
|
||||
return account_getpwgrkey(
|
||||
fd,
|
||||
"GetUserInfo",
|
||||
"uuid",
|
||||
"\"",
|
||||
uuid,
|
||||
(pwgr_parser_t)account_recordpw,
|
||||
passwd,
|
||||
pool
|
||||
);
|
||||
}
|
||||
|
||||
static inline int account_getgrgid(
|
||||
int fd,
|
||||
gid_t gid,
|
||||
struct group *group,
|
||||
struct account_memory_pool *pool
|
||||
) {
|
||||
char gid_str[32];
|
||||
int len = snprintf(gid_str, sizeof(gid_str), "%u", (unsigned int)gid);
|
||||
REQ(len > 0 && (size_t)len < sizeof(gid_str));
|
||||
|
||||
return account_getpwgrkey(
|
||||
fd,
|
||||
"GetGroupInfo",
|
||||
"host_gid",
|
||||
"",
|
||||
gid_str,
|
||||
(pwgr_parser_t)account_recordgr,
|
||||
group,
|
||||
pool
|
||||
);
|
||||
}
|
||||
|
||||
static inline int account_getgrnam(
|
||||
int fd,
|
||||
const char *name,
|
||||
struct group *group,
|
||||
struct account_memory_pool *pool
|
||||
) {
|
||||
return account_getpwgrkey(
|
||||
fd,
|
||||
"GetGroupInfo",
|
||||
"groupname",
|
||||
"\"",
|
||||
name,
|
||||
(pwgr_parser_t)account_recordgr,
|
||||
group,
|
||||
pool
|
||||
);
|
||||
}
|
||||
|
||||
static inline int account_getgruuid(
|
||||
int fd,
|
||||
const char *uuid,
|
||||
struct group *group,
|
||||
struct account_memory_pool *pool
|
||||
) {
|
||||
return account_getpwgrkey(
|
||||
fd,
|
||||
"GetGroupInfo",
|
||||
"uuid",
|
||||
"\"",
|
||||
uuid,
|
||||
(pwgr_parser_t)account_recordgr,
|
||||
group,
|
||||
pool
|
||||
);
|
||||
}
|
||||
|
||||
static inline int account_getpwent(
|
||||
int fd,
|
||||
unsigned int *no,
|
||||
struct passwd *passwd,
|
||||
struct account_memory_pool *pool
|
||||
) {
|
||||
int status;
|
||||
|
||||
char *next_uuid = account_list_uuid_next(fd, "ListUser", *no);
|
||||
REQ2(next_uuid, errno);
|
||||
status = account_getpwuuid(fd, next_uuid, passwd, pool);
|
||||
free(next_uuid);
|
||||
REQ(status == 0);
|
||||
*no += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int account_getgrent(
|
||||
int fd,
|
||||
unsigned int *no,
|
||||
struct group *group,
|
||||
struct account_memory_pool *pool
|
||||
) {
|
||||
int status;
|
||||
|
||||
char *next_uuid = account_list_uuid_next(fd, "ListGroup", *no);
|
||||
REQ2(next_uuid, errno);
|
||||
status = account_getgruuid(fd, next_uuid, group, pool);
|
||||
free(next_uuid);
|
||||
REQ(status == 0);
|
||||
*no += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _ACCOUNT_CLIENT */
|
||||
+53
-40
@@ -1,49 +1,62 @@
|
||||
#include "pwf.h"
|
||||
#include <pthread.h>
|
||||
#include "account_client.h"
|
||||
#include <grp.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define FIX(x) (gr->gr_##x = gr->gr_##x-line+buf)
|
||||
|
||||
static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
|
||||
{
|
||||
char *line = 0;
|
||||
size_t len = 0;
|
||||
char **mem = 0;
|
||||
size_t nmem = 0;
|
||||
int rv = 0;
|
||||
size_t i;
|
||||
int cs;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
|
||||
|
||||
rv = __getgr_a(name, gid, gr, &line, &len, &mem, &nmem, res);
|
||||
if (*res && size < len + (nmem+1)*sizeof(char *) + 32) {
|
||||
*res = 0;
|
||||
rv = ERANGE;
|
||||
}
|
||||
if (*res) {
|
||||
buf += (16-(uintptr_t)buf)%16;
|
||||
gr->gr_mem = (void *)buf;
|
||||
buf += (nmem+1)*sizeof(char *);
|
||||
memcpy(buf, line, len);
|
||||
FIX(name);
|
||||
FIX(passwd);
|
||||
for (i=0; mem[i]; i++)
|
||||
gr->gr_mem[i] = mem[i]-line+buf;
|
||||
gr->gr_mem[i] = 0;
|
||||
}
|
||||
free(mem);
|
||||
free(line);
|
||||
pthread_setcancelstate(cs, 0);
|
||||
if (rv) errno = rv;
|
||||
return rv;
|
||||
}
|
||||
#define VERIFYPOOL(pool) if (!pool.ptr || pool.len == 0) { if (res) *res = NULL; return EINVAL; }
|
||||
|
||||
int getgrnam_r(const char *name, struct group *gr, char *buf, size_t size, struct group **res)
|
||||
{
|
||||
return getgr_r(name, 0, gr, buf, size, res);
|
||||
int ret;
|
||||
int saved_errno;
|
||||
|
||||
DECLPOOL(pool, buf, size);
|
||||
VERIFYPOOL(pool);
|
||||
|
||||
int fd = account_connect();
|
||||
if (fd < 0) {
|
||||
saved_errno = errno;
|
||||
*res = NULL;
|
||||
return saved_errno != 0 ? saved_errno : EIO;
|
||||
}
|
||||
|
||||
ret = account_getgrnam(fd, name, gr, &pool);
|
||||
saved_errno = errno;
|
||||
spp_close(fd);
|
||||
|
||||
if (ret != 0) {
|
||||
*res = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*res = gr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getgrgid_r(gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
|
||||
{
|
||||
return getgr_r(0, gid, gr, buf, size, res);
|
||||
int ret;
|
||||
int saved_errno;
|
||||
|
||||
DECLPOOL(pool, buf, size);
|
||||
VERIFYPOOL(pool);
|
||||
|
||||
int fd = account_connect();
|
||||
if (fd < 0) {
|
||||
saved_errno = errno;
|
||||
*res = NULL;
|
||||
return saved_errno != 0 ? saved_errno : EIO;
|
||||
}
|
||||
|
||||
ret = account_getgrgid(fd, gid, gr, &pool);
|
||||
saved_errno = errno;
|
||||
spp_close(fd);
|
||||
|
||||
if (ret != 0) {
|
||||
*res = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*res = gr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+50
-19
@@ -1,39 +1,70 @@
|
||||
#include "pwf.h"
|
||||
#include <grp.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "account_client.h"
|
||||
|
||||
static FILE *f;
|
||||
static char *line, **mem;
|
||||
static struct group gr;
|
||||
static char grs_buf[16384];
|
||||
unsigned int igrent = 0;
|
||||
|
||||
void setgrent()
|
||||
{
|
||||
if (f) fclose(f);
|
||||
f = 0;
|
||||
igrent = 0;
|
||||
}
|
||||
|
||||
weak_alias(setgrent, endgrent);
|
||||
|
||||
struct group *getgrent()
|
||||
{
|
||||
struct group *res;
|
||||
size_t size=0, nmem=0;
|
||||
if (!f) f = fopen("/etc/group", "rbe");
|
||||
if (!f) return 0;
|
||||
__getgrent_a(f, &gr, &line, &size, &mem, &nmem, &res);
|
||||
return res;
|
||||
memset(&gr, 0, sizeof(gr));
|
||||
memset(grs_buf, 0, sizeof(grs_buf));
|
||||
DECLPOOL(pool, grs_buf, sizeof(grs_buf));
|
||||
|
||||
int fd = account_connect();
|
||||
int status = account_getgrent(fd, &igrent, &gr, &pool);
|
||||
spp_close(fd);
|
||||
if (status != 0) return NULL;
|
||||
return &gr;
|
||||
}
|
||||
|
||||
struct group *getgrgid(gid_t gid)
|
||||
{
|
||||
struct group *res;
|
||||
size_t size=0, nmem=0;
|
||||
__getgr_a(0, gid, &gr, &line, &size, &mem, &nmem, &res);
|
||||
return res;
|
||||
struct group *result;
|
||||
int ret;
|
||||
|
||||
memset(&gr, 0, sizeof(gr));
|
||||
memset(grs_buf, 0, sizeof(grs_buf));
|
||||
|
||||
ret = getgrgid_r(gid, &gr, grs_buf, sizeof(grs_buf), &result);
|
||||
if (ret != 0) {
|
||||
errno = ret;
|
||||
return NULL;
|
||||
}
|
||||
if (result == NULL) {
|
||||
errno = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &gr;
|
||||
}
|
||||
|
||||
struct group *getgrnam(const char *name)
|
||||
{
|
||||
struct group *res;
|
||||
size_t size=0, nmem=0;
|
||||
__getgr_a(name, 0, &gr, &line, &size, &mem, &nmem, &res);
|
||||
return res;
|
||||
struct group *result;
|
||||
int ret;
|
||||
|
||||
memset(&gr, 0, sizeof(gr));
|
||||
memset(grs_buf, 0, sizeof(grs_buf));
|
||||
|
||||
ret = getgrnam_r(name, &gr, grs_buf, sizeof(grs_buf), &result);
|
||||
if (ret != 0) {
|
||||
errno = ret;
|
||||
return NULL;
|
||||
}
|
||||
if (result == NULL) {
|
||||
errno = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &gr;
|
||||
}
|
||||
|
||||
+53
-33
@@ -1,42 +1,62 @@
|
||||
#include "pwf.h"
|
||||
#include <pthread.h>
|
||||
#include "account_client.h"
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define FIX(x) (pw->pw_##x = pw->pw_##x-line+buf)
|
||||
|
||||
static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
|
||||
{
|
||||
char *line = 0;
|
||||
size_t len = 0;
|
||||
int rv = 0;
|
||||
int cs;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
|
||||
|
||||
rv = __getpw_a(name, uid, pw, &line, &len, res);
|
||||
if (*res && size < len) {
|
||||
*res = 0;
|
||||
rv = ERANGE;
|
||||
}
|
||||
if (*res) {
|
||||
memcpy(buf, line, len);
|
||||
FIX(name);
|
||||
FIX(passwd);
|
||||
FIX(gecos);
|
||||
FIX(dir);
|
||||
FIX(shell);
|
||||
}
|
||||
free(line);
|
||||
pthread_setcancelstate(cs, 0);
|
||||
if (rv) errno = rv;
|
||||
return rv;
|
||||
}
|
||||
#define VERIFYPOOL(pool) if (!pool.ptr || pool.len == 0) { if (res) *res = NULL; return EINVAL; }
|
||||
|
||||
int getpwnam_r(const char *name, struct passwd *pw, char *buf, size_t size, struct passwd **res)
|
||||
{
|
||||
return getpw_r(name, 0, pw, buf, size, res);
|
||||
int ret;
|
||||
int saved_errno;
|
||||
|
||||
DECLPOOL(pool, buf, size);
|
||||
VERIFYPOOL(pool);
|
||||
|
||||
int fd = account_connect();
|
||||
if (fd < 0) {
|
||||
saved_errno = errno;
|
||||
*res = NULL;
|
||||
return saved_errno != 0 ? saved_errno : EIO;
|
||||
}
|
||||
|
||||
ret = account_getpwnam(fd, name, pw, &pool);
|
||||
saved_errno = errno;
|
||||
spp_close(fd);
|
||||
|
||||
if (ret != 0) {
|
||||
*res = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*res = pw;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
|
||||
{
|
||||
return getpw_r(0, uid, pw, buf, size, res);
|
||||
int ret;
|
||||
int saved_errno;
|
||||
|
||||
DECLPOOL(pool, buf, size);
|
||||
VERIFYPOOL(pool);
|
||||
|
||||
int fd = account_connect();
|
||||
if (fd < 0) {
|
||||
saved_errno = errno;
|
||||
*res = NULL;
|
||||
return saved_errno != 0 ? saved_errno : EIO;
|
||||
}
|
||||
|
||||
ret = account_getpwuid(fd, uid, pw, &pool);
|
||||
saved_errno = errno;
|
||||
spp_close(fd);
|
||||
|
||||
if (ret != 0) {
|
||||
*res = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*res = pw;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+50
-17
@@ -1,37 +1,70 @@
|
||||
#include "pwf.h"
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "account_client.h"
|
||||
|
||||
static FILE *f;
|
||||
static char *line;
|
||||
static struct passwd pw;
|
||||
static size_t size;
|
||||
static char pwr_buf[16384];
|
||||
unsigned int ipwent = 0;
|
||||
|
||||
void setpwent()
|
||||
{
|
||||
if (f) fclose(f);
|
||||
f = 0;
|
||||
ipwent = 0;
|
||||
}
|
||||
|
||||
weak_alias(setpwent, endpwent);
|
||||
|
||||
struct passwd *getpwent()
|
||||
{
|
||||
struct passwd *res;
|
||||
if (!f) f = fopen("/etc/passwd", "rbe");
|
||||
if (!f) return 0;
|
||||
__getpwent_a(f, &pw, &line, &size, &res);
|
||||
return res;
|
||||
memset(&pw, 0, sizeof(pw));
|
||||
memset(pwr_buf, 0, sizeof(pwr_buf));
|
||||
DECLPOOL(pool, pwr_buf, sizeof(pwr_buf));
|
||||
|
||||
int fd = account_connect();
|
||||
int status = account_getpwent(fd, &ipwent, &pw, &pool);
|
||||
spp_close(fd);
|
||||
if (status != 0) return NULL;
|
||||
return &pw;
|
||||
}
|
||||
|
||||
struct passwd *getpwuid(uid_t uid)
|
||||
{
|
||||
struct passwd *res;
|
||||
__getpw_a(0, uid, &pw, &line, &size, &res);
|
||||
return res;
|
||||
struct passwd *result;
|
||||
int ret;
|
||||
|
||||
memset(&pw, 0, sizeof(pw));
|
||||
memset(pwr_buf, 0, sizeof(pwr_buf));
|
||||
|
||||
ret = getpwuid_r(uid, &pw, pwr_buf, sizeof(pwr_buf), &result);
|
||||
if (ret != 0) {
|
||||
errno = ret;
|
||||
return NULL;
|
||||
}
|
||||
if (result == NULL) {
|
||||
errno = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &pw;
|
||||
}
|
||||
|
||||
struct passwd *getpwnam(const char *name)
|
||||
{
|
||||
struct passwd *res;
|
||||
__getpw_a(name, 0, &pw, &line, &size, &res);
|
||||
return res;
|
||||
struct passwd *result;
|
||||
int ret;
|
||||
|
||||
memset(&pw, 0, sizeof(pw));
|
||||
memset(pwr_buf, 0, sizeof(pwr_buf));
|
||||
|
||||
ret = getpwnam_r(name, &pw, pwr_buf, sizeof(pwr_buf), &result);
|
||||
if (ret != 0) {
|
||||
errno = ret;
|
||||
return NULL;
|
||||
}
|
||||
if (result == NULL) {
|
||||
errno = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &pw;
|
||||
}
|
||||
|
||||
+3516
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,124 @@
|
||||
#ifndef SPP_H
|
||||
#define SPP_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
static inline int write_all(int fd, const void *buf, size_t len)
|
||||
{
|
||||
const char *p = buf;
|
||||
size_t remaining = len;
|
||||
while (remaining > 0) {
|
||||
ssize_t n = write(fd, p, remaining);
|
||||
if (n <= 0) return -1;
|
||||
p += n;
|
||||
remaining -= (size_t)n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int read_all(int fd, void *buf, size_t len)
|
||||
{
|
||||
char *p = buf;
|
||||
size_t remaining = len;
|
||||
while (remaining > 0) {
|
||||
ssize_t n = read(fd, p, remaining);
|
||||
if (n <= 0) return -1;
|
||||
p += n;
|
||||
remaining -= (size_t)n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int spp_connect_common(const char *path, int abstract)
|
||||
{
|
||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == -1) return -1;
|
||||
|
||||
struct sockaddr_un addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
|
||||
size_t len = strlen(path);
|
||||
if (len >= sizeof(addr.sun_path)) {
|
||||
close(fd);
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
socklen_t addrlen;
|
||||
|
||||
if (abstract) {
|
||||
addr.sun_path[0] = '\0';
|
||||
memcpy(addr.sun_path + 1, path, len);
|
||||
addrlen = offsetof(struct sockaddr_un, sun_path) + 1 + len;
|
||||
} else {
|
||||
memcpy(addr.sun_path, path, len);
|
||||
addrlen = offsetof(struct sockaddr_un, sun_path) + len;
|
||||
}
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&addr, addrlen) == -1) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static inline int spp_connect_unix(char *path)
|
||||
{
|
||||
return spp_connect_common(path, 0);
|
||||
}
|
||||
|
||||
static inline int spp_connect_linux(char *abstract_name)
|
||||
{
|
||||
return spp_connect_common(abstract_name, 1);
|
||||
}
|
||||
|
||||
static inline void spp_close(int fd)
|
||||
{
|
||||
if (fd >= 0) close(fd);
|
||||
}
|
||||
|
||||
static inline int spp_send(int fd, char *packet)
|
||||
{
|
||||
size_t data_len = strlen(packet);
|
||||
if (data_len > UINT32_MAX) return -1;
|
||||
|
||||
uint32_t len = (uint32_t)data_len;
|
||||
|
||||
if (write_all(fd, &len, sizeof(len)) == -1) return -1;
|
||||
if (data_len > 0 && write_all(fd, packet, data_len) == -1) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline char *spp_recv(int fd)
|
||||
{
|
||||
uint32_t len;
|
||||
if (read_all(fd, &len, sizeof(len)) == -1) return NULL;
|
||||
|
||||
char *buf = malloc(len + 1);
|
||||
if (!buf) return NULL;
|
||||
|
||||
if (len > 0 && read_all(fd, buf, len) == -1) {
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf[len] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline void spp_free(void *p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
|
||||
#endif
|
||||
+3
-3
@@ -132,7 +132,7 @@ static void do_tzset()
|
||||
"/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
|
||||
|
||||
s = getenv("TZ");
|
||||
if (!s) s = "/etc/localtime";
|
||||
if (!s) s = "/var/config/localtime";
|
||||
if (!*s) s = __utc;
|
||||
|
||||
if (old_tz && !strcmp(s, old_tz)) return;
|
||||
@@ -163,7 +163,7 @@ static void do_tzset()
|
||||
|| !strcmp(dummy_name, "UTC")
|
||||
|| !strcmp(dummy_name, "GMT")))
|
||||
posix_form = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Non-suid can use an absolute tzfile pathname or a relative
|
||||
* pathame beginning with "."; in secure mode, only the
|
||||
@@ -171,7 +171,7 @@ static void do_tzset()
|
||||
if (!posix_form) {
|
||||
if (*s == ':') s++;
|
||||
if (*s == '/' || *s == '.') {
|
||||
if (!libc.secure || !strcmp(s, "/etc/localtime"))
|
||||
if (!libc.secure || !strcmp(s, "/var/config/localtime"))
|
||||
map = __map_file(s, &map_size);
|
||||
} else {
|
||||
size_t l = strlen(s);
|
||||
|
||||
@@ -11,8 +11,7 @@ fn main() {
|
||||
let dst = args.next().expect("please specify output file");
|
||||
|
||||
let mut octos = Vec::new();
|
||||
let src_content = std::fs::read_to_string(&src)
|
||||
.expect("cannot read source file");
|
||||
let src_content = std::fs::read_to_string(&src).expect("cannot read source file");
|
||||
let mut current_tag = None;
|
||||
for (nline, line) in src_content.lines().enumerate() {
|
||||
let line = line.trim();
|
||||
@@ -129,7 +128,9 @@ fn do_arg(s: &str, content: &mut [u8; 8], cursor: &mut usize) -> Option<(usize,
|
||||
_ => panic!("unknown radix"),
|
||||
};
|
||||
*cursor = 8;
|
||||
*content = u64::from_str_radix(&digit[1..], radix).unwrap().to_be_bytes();
|
||||
*content = u64::from_str_radix(&digit[1..], radix)
|
||||
.unwrap()
|
||||
.to_be_bytes();
|
||||
None
|
||||
} else if let Some(reg_id) = s.strip_prefix("&r") {
|
||||
content[*cursor] = reg_id.parse::<u8>().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user