Skip to content
Snippets Groups Projects
Commit 35fa86e8 authored by Eric Vidal's avatar Eric Vidal :speech_balloon:
Browse files

add sanitize_xxx function family

parent 5cafaeab
No related branches found
No related tags found
No related merge requests found
sanitize_fdholder.o
sanitize_init.o
sanitize_livestate.o
sanitize_scandir.o
sanitize_source.o
sanitize_system.o
-loblibs
-lskarnet
/*
* sanitize_fdholder.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <stdint.h>
#include <string.h>
#include <stdint.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <oblibs/sastr.h>
#include <skalibs/tai.h>
#include <skalibs/djbunix.h>
#include <skalibs/types.h>
#include <66/service.h>
#include <66/constants.h>
#include <66/state.h>
#include <s6/fdholder.h>
/**
* Accepted flag are
* - STATE_FLAGS_TRUE -> store the service A.K.A identifier
* - STATE_FLAGS_FALSE -> delete the service A.K.A identifier
*
* */
void sanitize_fdholder(resolve_service_t *res, uint32_t flag)
{
log_flow() ;
if (res->logger.name) {
stralloc list = STRALLOC_ZERO ;
char *sa = res->sa.s ;
char *name = sa + res->logger.name ;
size_t namelen = strlen(name) ;
char *socket = sa + res->live.fdholderdir ;
size_t socketlen = strlen(socket) ;
s6_fdholder_t a = S6_FDHOLDER_ZERO ;
tain deadline = tain_infinite_relative, limit = tain_infinite_relative ;
unsigned int fd ;
char fdname[SS_FDHOLDER_PIPENAME_LEN + 2 + namelen + 1] ;
char sock[socketlen + 3] ;
auto_strings(sock, socket, "/s") ;
tain_now_set_stopwatch_g() ;
tain_add_g(&deadline, &deadline) ;
tain_add_g(&limit, &limit) ;
if (!s6_fdholder_start_g(&a, sock, &deadline))
log_dieusys(LOG_EXIT_SYS, "connect to socket: ", sock) ;
if (FLAGS_ISSET(flag, STATE_FLAGS_TRUE)) {
auto_strings(fdname, SS_FDHOLDER_PIPENAME, "r-", name) ;
log_trace("store identifier: ", fdname) ;
if (!s6_fdholder_store_g(&a, fd, fdname, &limit, &deadline))
log_dieusys(LOG_EXIT_SYS, "store fd: ", fdname) ;
fdname[strlen(SS_FDHOLDER_PIPENAME)] = 'w' ;
log_trace("store identifier: ", fdname) ;
if (!s6_fdholder_store_g(&a, fd, fdname, &limit, &deadline))
log_dieusys(LOG_EXIT_SYS, "store fd: ", fdname) ;
} else if (FLAGS_ISSET(flag, STATE_FLAGS_FALSE)) {
auto_strings(fdname, SS_FDHOLDER_PIPENAME, "r-", name) ;
log_trace("delete identifier: ", fdname) ;
if (!s6_fdholder_delete_g(&a, fdname, &deadline))
log_dieusys(LOG_EXIT_SYS, "delete fd: ", fdname) ;
fdname[strlen(SS_FDHOLDER_PIPENAME)] = 'w' ;
log_trace("delete identifier: ", fdname) ;
if (!s6_fdholder_delete_g(&a, fdname, &deadline))
log_dieusys(LOG_EXIT_SYS, "delete fd: ", fdname) ;
}
if (s6_fdholder_list_g(&a, &list, &deadline) < 0)
log_dieusys(LOG_EXIT_SYS, "list identifier") ;
s6_fdholder_end(&a) ;
size_t pos = 0, tlen = list.len ;
char t[tlen + 1] ;
sastr_to_char(t, &list) ;
list.len = 0 ;
for (; pos < tlen ; pos += strlen(t + pos) + 1) {
if (str_start_with(t + pos, SS_FDHOLDER_PIPENAME "r-")) {
/** only keep the reader, the writer is automatically created
* by the 66-fdholder-filler. see format of it */
if (!auto_stra(&list, t + pos, "\n"))
log_die_nomem("stralloc") ;
}
}
char file[socketlen + 17] ;
auto_strings(file, socket, "/data/autofilled") ;
if (!openwritenclose_unsafe(file, list.s, list.len))
log_dieusys(LOG_EXIT_SYS, "write file: ", file) ;
stralloc_free(&list) ;
}
}
/*
* sanitize_init.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <66/svc.h>
#include <string.h>
#include <stdlib.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <oblibs/sastr.h>
#include <skalibs/types.h>
#include <skalibs/tai.h>
#include <skalibs/djbunix.h>
#include <skalibs/unix-transactional.h>//atomic_symlink
#include <s6/supervise.h>
#include <s6/ftrigr.h>
#include <s6/ftrigw.h>
#include <66/utils.h>
#include <66/resolve.h>
#include <66/constants.h>
#include <66/ssexec.h>
#include <66/state.h>
#include <66/enum.h>
#include <66/sanitize.h>
void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_service_t *ares, unsigned int areslen, uint32_t flags)
{
log_flow() ;
ftrigr_t fifo = FTRIGR_ZERO ;
uint32_t earlier = FLAGS_ISSET(flags, STATE_FLAGS_ISEARLIER) ;
gid_t gid = getgid() ;
int is_supervised = 0, is_init ;
unsigned int pos = 0, nsv = 0 ;
unsigned int real[alen] ;
/* nothing to do */
if (!alen)
return ;
for (; pos < alen ; pos++) {
char *name = g->data.s + genalloc_s(graph_hash_t,&g->hash)[alist[pos]].vertex ;
int aresid = service_resolve_array_search(ares, areslen, name) ;
if (aresid < 0)
log_dieu(LOG_EXIT_SYS,"find ares id -- please make a bug reports") ;
char *sa = ares[aresid].sa.s ;
char *scandir = sa + ares[aresid].live.scandir ;
size_t scandirlen = strlen(scandir) ;
is_init = access(sa + ares[aresid].live.statedir, F_OK) ;
if (is_init < 0 || FLAGS_ISSET(flags, STATE_FLAGS_TOINIT))
sanitize_livestate(&ares[aresid], STATE_FLAGS_UNKNOWN) ;
/**
* Bundle, module type are not a daemons. We don't need
* to supervise it.
* Special case for Oneshot, we only deal with
* the scandir symlink.
* */
if (ares[aresid].type == TYPE_BUNDLE || ares[aresid].type == TYPE_MODULE )
continue ;
is_supervised = access(scandir, F_OK) ;
if (!earlier && !is_supervised) {
log_warn(name," already initialized -- ignore it") ;
continue ;
}
if (is_supervised == -1) {
sanitize_scandir(&ares[aresid], STATE_FLAGS_TOINIT) ;
if (ares[aresid].type == TYPE_ONESHOT)
continue ;
}
/* down file */
char downfile[scandirlen + 6] ;
auto_strings(downfile, scandir, "/down") ;
int fd = open_trunc(downfile) ;
if (fd < 0)
log_dieusys(LOG_EXIT_SYS, "create file: ", downfile) ;
fd_close(fd) ;
if (!earlier && is_supervised) {
if (!FLAGS_ISSET(flags, STATE_FLAGS_TORELOAD))
sanitize_fdholder(&ares[aresid], STATE_FLAGS_TRUE) ;
log_trace("create fifo: ", sa + ares[aresid].live.eventdir) ;
if (!ftrigw_fifodir_make(sa + ares[aresid].live.eventdir, gid, 0))
log_dieusys(LOG_EXIT_SYS, "create fifo: ", sa + ares[aresid].live.eventdir) ;
}
real[nsv++] = (unsigned int)aresid ;
}
/**
* scandir is already running, we need to synchronize with it
* */
if (!earlier && nsv) {
uint16_t ids[nsv] ;
unsigned int nids = 0 ;
tain deadline ;
tain_now_set_stopwatch_g() ;
tain_addsec(&deadline, &STAMP, 2) ;
if (!ftrigr_startf_g(&fifo, &deadline))
log_dieusys(LOG_EXIT_SYS, "ftrigr") ;
for (pos = 0 ; pos < nsv ; pos++) {
if (ares[real[pos]].type == TYPE_CLASSIC) {
char *sa = ares[real[pos]].sa.s ;
char *eventdir = sa + ares[real[pos]].live.eventdir ;
log_trace("subcribe to fifo: ", eventdir) ;
/** unsubscribe automatically, options is 0 */
ids[nids] = ftrigr_subscribe_g(&fifo, eventdir, "s", 0, &deadline) ;
if (!ids[nids++])
log_dieusys(LOG_EXIT_SYS, "subcribe to fifo: ", eventdir) ;
}
}
if (nids) {
sanitize_scandir(&ares[0], STATE_FLAGS_TORELOAD) ;
log_trace("waiting for events on fifo...") ;
if (ftrigr_wait_and_g(&fifo, ids, nids, &deadline) < 0)
log_dieusys(LOG_EXIT_SYS, "wait for events") ;
{
/** for now, i don't know exactly why
* but if the fdholder daemon isn't reloaded
* the up process hangs at a service logger start.
* Sending a -ru to fdholder solve the issue.*/
char tfmt[UINT32_FMT] ;
tfmt[uint_fmt(tfmt, 3000)] = 0 ;
pid_t pid ;
int wstat ;
char *socket = ares[0].sa.s + ares[0].live.fdholderdir ;
char const *newargv[8] ;
unsigned int m = 0 ;
newargv[m++] = "s6-svc" ;
newargv[m++] = "-ru" ;
newargv[m++] = "-T" ;
newargv[m++] = tfmt ;
newargv[m++] = "--" ;
newargv[m++] = socket ;
newargv[m++] = 0 ;
log_trace("sending -ru signal to: ", socket) ;
pid = child_spawn0(newargv[0], newargv, (char const *const *) environ) ;
if (waitpid_nointr(pid, &wstat, 0) < 0)
log_dieusys(LOG_EXIT_SYS, "wait for reload of the fdholder daemon") ;
if (wstat)
log_dieu(LOG_EXIT_SYS, "reload fdholder service; ", socket) ;
}
}
}
if (earlier)
sanitize_scandir(&ares[0], STATE_FLAGS_ISEARLIER) ;
/**
* We pass through here even for Bundle, Module and Oneshot.
* We need to write the state file anyway. Thus can always
* be consider as initialized.
* */
for (pos = 0 ; pos < alen ; pos++) {
char *name = g->data.s + genalloc_s(graph_hash_t,&g->hash)[alist[pos]].vertex ;
int aresid = service_resolve_array_search(ares, areslen, name) ;
if (aresid < 0)
log_dieu(LOG_EXIT_SYS,"find ares id -- please make a bug reports") ;
char *sa = ares[aresid].sa.s ;
if (!ftrigw_clean(sa + ares[aresid].live.eventdir))
log_warnu("clean event directory: ", sa + ares[aresid].live.eventdir) ;
if (!state_messenger(sa + ares[aresid].path.home, name, STATE_FLAGS_TOINIT, STATE_FLAGS_FALSE))
log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
log_info("Initialized successfully: ", sa + ares[pos].name) ;
}
ftrigr_end(&fifo) ;
}
/*
* sanitize_livestate.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <oblibs/directory.h>
#include <skalibs/unix-transactional.h>
#include <skalibs/posixplz.h>
#include <66/constants.h>
#include <66/sanitize.h>
#include <66/service.h>
#include <66/utils.h>
#include <66/state.h>
/** creation of the /run/66/state/<uid> directory */
static void sanitize_livestate_directory(resolve_service_t *res)
{
log_flow() ;
int r ;
gid_t gidowner ;
size_t livelen = strlen(res->sa.s + res->live.livedir) ;
size_t ownerlen = strlen(res->sa.s + res->ownerstr) ;
char ste[livelen + SS_STATE_LEN + 1 + ownerlen + 1] ;
auto_strings(ste, res->sa.s + res->live.livedir, SS_STATE + 1, "/", res->sa.s + res->ownerstr) ;
r = scan_mode(ste, S_IFDIR) ;
if (r < 0)
log_diesys(LOG_EXIT_SYS, "conflicting format for: ", ste) ;
if (!r) {
r = dir_create_parent(ste, 0700) ;
if (!r)
log_dieusys(LOG_EXIT_SYS, "create directory: ", ste) ;
if (!yourgid(&gidowner, res->owner))
log_dieusys(LOG_EXIT_SYS, "get gid of: ", res->sa.s + res->ownerstr) ;
if (chown(ste, res->owner, gidowner) < 0)
log_dieusys(LOG_EXIT_SYS, "chown: ", ste) ;
}
}
/** creation of the /run/66/state/<uid>/<service> symlink */
static void sanitize_livestate_service_symlink(resolve_service_t *res)
{
char *name = res->sa.s + res->name ;
size_t namelen = strlen(name) ;
size_t livelen = strlen(res->sa.s + res->live.livedir) ;
size_t ownerlen = strlen(res->sa.s + res->ownerstr) ;
size_t treelen = strlen(res->sa.s + res->path.tree) ;
char sym[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + namelen + 1] ;
char dst[treelen + SS_SVDIRS_LEN + SS_SVC_LEN + 1 + namelen + 1] ;
auto_strings(sym, res->sa.s + res->live.livedir, SS_STATE + 1, "/", res->sa.s + res->ownerstr, "/", name) ;
auto_strings(dst, res->sa.s + res->path.tree, SS_SVDIRS, SS_SVC, "/", name) ;
if (!atomic_symlink(dst, sym, "scandir"))
log_dieu(LOG_EXIT_SYS, "symlink: ", sym, " to: ", dst) ;
}
void sanitize_livestate(resolve_service_t *res, uint32_t flag)
{
log_flow() ;
int r ;
char *name = res->sa.s + res->name ;
size_t namelen = strlen(name) ;
size_t livelen = strlen(res->sa.s + res->live.livedir) ;
size_t ownerlen = strlen(res->sa.s + res->owner) ;
char ste[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + namelen + 1] ;
auto_strings(ste, res->sa.s + res->live.livedir, SS_STATE + 1, "/", res->sa.s + res->ownerstr, "/", name) ;
r = access(ste, F_OK) ;
if (r == -1) {
sanitize_livestate_directory(res) ;
sanitize_livestate_service_symlink(res) ;
} else {
if (FLAGS_ISSET(flag, STATE_FLAGS_TOUNSUPERVISE)) {
unlink_void(ste) ;
if (!state_messenger(res->sa.s + res->path.home, name, STATE_FLAGS_TORELOAD, STATE_FLAGS_FALSE))
log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
}
}
if (!state_messenger(res->sa.s + res->path.home, name, STATE_FLAGS_TOINIT, STATE_FLAGS_FALSE))
log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
}
/*
* sanitize_scandir.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/stat.h> // umask
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/directory.h>
#include <oblibs/types.h>
#include <skalibs/unix-transactional.h>
#include <skalibs/posixplz.h>
#include <66/service.h>
#include <66/sanitize.h>
#include <66/constants.h>
#include <66/enum.h>
#include <66/state.h>
#include <66/svc.h>
static void scandir_scandir_to_livestate(resolve_service_t *res)
{
char *name = res->sa.s + res->name ;
size_t namelen = strlen(name) ;
size_t livelen = strlen(res->sa.s + res->live.livedir) ;
size_t ownerlen = strlen(res->sa.s + res->ownerstr) ;
char sym[livelen + 1 + SS_SCANDIR_LEN + 1 + ownerlen + 1 + namelen + 1] ;
char dst[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + namelen + 1] ;
auto_strings(sym, res->sa.s + res->live.livedir, "/", SS_SCANDIR, "/", res->sa.s + res->ownerstr, "/", name) ;
auto_strings(dst, res->sa.s + res->live.livedir, SS_STATE + 1, "/", res->sa.s + res->ownerstr, "/", name) ;
if (!atomic_symlink(dst, sym, "scandir"))
log_dieu(LOG_EXIT_SYS, "symlink: ", sym, " to: ", dst) ;
}
static void scandir_service_to_scandir(resolve_service_t *res)
{
char *name = res->sa.s + res->name ;
size_t namelen = strlen(name) ;
size_t treelen = strlen(res->sa.s + res->path.tree) ;
size_t livelen = strlen(res->sa.s + res->live.livedir) ;
size_t ownerlen = strlen(res->sa.s + res->ownerstr) ;
char sym[treelen + SS_SVDIRS_LEN + SS_SVC_LEN + 1 + namelen + 1 + SS_SCANDIR_LEN + 1] ;
char dst[livelen + SS_SCANDIR_LEN + 1 + ownerlen + 1] ;
auto_strings(sym, res->sa.s + res->path.tree, SS_SVDIRS, SS_SVC, "/", name, "/", SS_SCANDIR) ;
auto_strings(dst, res->sa.s + res->live.livedir, SS_SCANDIR, "/", res->sa.s + res->ownerstr) ;
if (!atomic_symlink(dst, sym, "scandir"))
log_dieu(LOG_EXIT_SYS, "symlink: ", sym, " to: ", dst) ;
}
static void compute_supervision_dir(resolve_service_t *res)
{
mode_t hmod = umask(0) ;
char *event = res->sa.s + res->live.eventdir ;
char *supervise = res->sa.s + res->live.supervisedir ;
/* event dir */
int r = dir_create_parent(event, 0700) ;
if (!r)
log_dieusys(LOG_EXIT_SYS, "create directory: ", event) ;
if (chown(event, -1, getegid()) < 0)
log_dieusys(LOG_EXIT_SYS, "chown: ", event) ;
if (chmod(event, 03730) < 0)
log_dieusys(LOG_EXIT_SYS, "chmod: ", event) ;
/* supervise dir*/
r = dir_create_parent(supervise, 0700) ;
if (!r)
log_dieusys(LOG_EXIT_SYS, "create directory: ", event) ;
umask(hmod) ;
}
void sanitize_scandir(resolve_service_t *res, uint32_t flag)
{
log_flow() ;
int r ;
char *name = res->sa.s + res->name ;
size_t namelen = strlen(name) ;
size_t livelen = strlen(res->sa.s + res->live.livedir) ;
size_t scandirlen = strlen(res->sa.s + res->live.scandir) ;
char svcandir[scandirlen + 1] ;
auto_strings(svcandir, res->sa.s + res->live.scandir) ;
svcandir[scandirlen - namelen - 1] = 0 ;
r = access(res->sa.s + res->live.scandir, F_OK) ;
if (r == -1 && FLAGS_ISSET(flag, STATE_FLAGS_TOINIT)) {
if (res->type == TYPE_CLASSIC)
scandir_scandir_to_livestate(res) ;
scandir_service_to_scandir(res) ;
compute_supervision_dir(res) ;
if (FLAGS_ISSET(flag, STATE_FLAGS_ISEARLIER)) {
if (svc_scandir_send(svcandir, "h") <= 0)
log_dieu(LOG_EXIT_SYS, "reload scandir: ", svcandir) ;
}
if (!state_messenger(res->sa.s + res->path.home, name, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_TRUE))
log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
if (!state_messenger(res->sa.s + res->path.home, name, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE))
log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
} else {
if (FLAGS_ISSET(flag, STATE_FLAGS_TOUNSUPERVISE)) {
char s[livelen + SS_SCANDIR_LEN + 1 + strlen(res->sa.s + res->ownerstr) + 1 + namelen + 1] ;
auto_strings(s, res->sa.s + res->live.livedir, SS_SCANDIR, "/", res->sa.s + res->ownerstr, "/", name) ;
unlink_void(s) ;
if (!state_messenger(res->sa.s + res->path.home, name, STATE_FLAGS_ISSUPERVISED, STATE_FLAGS_FALSE))
log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
if (!state_messenger(res->sa.s + res->path.home, name, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE))
log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
if (svc_scandir_send(svcandir, "an") <= 0)
log_dieu(LOG_EXIT_SYS, "reload scandir: ", svcandir) ;
}
if (FLAGS_ISSET(flag, STATE_FLAGS_TORELOAD)) {
if (svc_scandir_send(svcandir, "a") <= 0)
log_dieu(LOG_EXIT_SYS, "reload scandir: ", svcandir) ;
if (!state_messenger(res->sa.s + res->path.home, name, STATE_FLAGS_TORELOAD, STATE_FLAGS_FALSE))
log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
if (!state_messenger(res->sa.s + res->path.home, name, STATE_FLAGS_TOUNSUPERVISE, STATE_FLAGS_FALSE))
log_dieusys(LOG_EXIT_SYS, "send message to state of: ", name) ;
}
}
}
/*
* sanitize_source.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <stdint.h>
#include <string.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <66/constants.h>
#include <66/sanitize.h>
#include <66/service.h>
#include <66/state.h>
void sanitize_source(char const *name, ssexec_t *info, uint32_t flag)
{
int r ;
char atree[SS_MAX_TREENAME + 1] ;
r = service_is_g(atree, name, STATE_FLAGS_ISPARSED) ;
if (r == -1)
log_dieusys(LOG_EXIT_SYS, "get information of service: ", name, " -- please a bug report") ;
if (!r) {
int argc = 3 ;
int m = 0 ;
char const *newargv[argc] ;
newargv[m++] = "66-parse" ;
newargv[m++] = name ;
newargv[m++] = 0 ;
if (ssexec_parse(argc, newargv, info))
log_dieu(LOG_EXIT_SYS, "parse service: ", name) ;
} else if FLAGS_ISSET(flag, STATE_FLAGS_TORESTART) {
int argc = 4 ;
int m = 0 ;
char const *newargv[argc] ;
newargv[m++] = "66-parse" ;
newargv[m++] = "-f" ;
newargv[m++] = name ;
newargv[m++] = 0 ;
if (ssexec_parse(argc, newargv, info))
log_dieu(LOG_EXIT_SYS, "parse service: ", name) ;
}
}
/*
* sanitize_system.c
*
* Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <oblibs/directory.h>
#include <skalibs/stralloc.h>
#include <66/ssexec.h>
#include <66/constants.h>
#include <66/sanitize.h>
#include <66/utils.h>
#include <66/state.h>
#include <66/tree.h>
static char const *cleantree = 0 ;
static void cleanup(void)
{
log_flow() ;
if (cleantree) {
log_trace("removing: ",cleantree,"...") ;
if (!dir_rm_rf(cleantree))
log_dieusys(LOG_EXIT_SYS, "remove: ", cleantree) ;
}
}
static void auto_dir(char const *dst, mode_t mode)
{
log_flow() ;
log_trace("create directory: ",dst) ;
if (!dir_create_parent(dst,mode))
log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"create directory: ",dst) ;
}
static void auto_check(char *dst)
{
log_flow() ;
int r = scan_mode(dst,S_IFDIR) ;
if (r == -1)
log_diesys_nclean(LOG_EXIT_SYS, &cleanup, "conflicting format for: ", dst) ;
if (!r)
auto_dir(dst,0755) ;
}
static void inline auto_stralloc(stralloc *sa,char const *str)
{
log_flow() ;
if (!auto_stra(sa,str))
log_die_nomem("stralloc") ;
}
int sanitize_system(ssexec_t *info)
{
log_flow() ;
log_trace("sanitize system..." ) ;
/** set cleanup */
cleantree = info->tree.s ;
size_t baselen = info->base.len ;
uid_t log_uid ;
gid_t log_gid ;
char dst[baselen + SS_SYSTEM_LEN + SS_RESOLVE_LEN + 1 + SS_SERVICE_LEN + 1] ;
auto_strings(dst,info->base.s, SS_SYSTEM) ;
/** base is /var/lib/66 or $HOME/.66*/
/** this verification is made in case of
* first use of 66-*** tools */
auto_check(dst) ;
/** create extra directory for service part */
if (!info->owner) {
auto_check(SS_LOGGER_SYSDIR) ;
if (!youruid(&log_uid,SS_LOGGER_RUNNER) ||
!yourgid(&log_gid,log_uid))
log_dieusys(LOG_EXIT_SYS,"get uid and gid of: ",SS_LOGGER_RUNNER) ;
if (chown(SS_LOGGER_SYSDIR,log_uid,log_gid) == -1)
log_dieusys(LOG_EXIT_SYS,"chown: ",SS_LOGGER_RUNNER) ;
auto_check(SS_SERVICE_SYSDIR) ;
auto_check(SS_SERVICE_ADMDIR) ;
auto_check(SS_SERVICE_ADMCONFDIR) ;
auto_check(SS_MODULE_SYSDIR) ;
auto_check(SS_MODULE_ADMDIR) ;
auto_check(SS_SCRIPT_SYSDIR) ;
auto_check(SS_SEED_ADMDIR) ;
auto_check(SS_SEED_SYSDIR) ;
} else {
size_t extralen ;
stralloc extra = STRALLOC_ZERO ;
if (!set_ownerhome(&extra,info->owner))
log_dieusys(LOG_EXIT_SYS,"set home directory") ;
extralen = extra.len ;
if (!auto_stra(&extra, SS_USER_DIR, SS_SYSTEM))
log_die_nomem("stralloc") ;
auto_check(extra.s) ;
extra.len = extralen ;
auto_stralloc(&extra,SS_LOGGER_USERDIR) ;
auto_check(extra.s) ;
extra.len = extralen ;
auto_stralloc(&extra,SS_SERVICE_USERDIR) ;
auto_check(extra.s) ;
extra.len = extralen ;
auto_stralloc(&extra,SS_SERVICE_USERCONFDIR) ;
auto_check(extra.s) ;
extra.len = extralen ;
auto_stralloc(&extra,SS_MODULE_USERDIR) ;
auto_check(extra.s) ;
extra.len = extralen ;
auto_stralloc(&extra,SS_SCRIPT_USERDIR) ;
auto_check(extra.s) ;
extra.len = extralen ;
auto_stralloc(&extra,SS_SEED_USERDIR) ;
auto_check(extra.s) ;
stralloc_free(&extra) ;
}
auto_strings(dst, info->base.s, SS_SYSTEM, SS_RESOLVE, "/", SS_SERVICE) ;
auto_check(dst) ;
auto_strings(dst + baselen + SS_SYSTEM_LEN + SS_RESOLVE_LEN, SS_MASTER) ;
if (!scan_mode(dst, S_IFREG))
if (!tree_resolve_master_create(info->base.s, info->owner))
log_dieu(LOG_EXIT_SYS, "write Master resolve file of trees") ;
auto_strings(dst + baselen, SS_TREE_CURRENT) ;
auto_check(dst) ;
return 1 ;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment