diff --git a/src/lib66/sanitize/deps-lib/deps b/src/lib66/sanitize/deps-lib/deps new file mode 100644 index 0000000000000000000000000000000000000000..f22650fe2622646d51a56d5f5c3018b27bf62fe0 --- /dev/null +++ b/src/lib66/sanitize/deps-lib/deps @@ -0,0 +1,9 @@ +sanitize_fdholder.o +sanitize_init.o +sanitize_livestate.o +sanitize_scandir.o +sanitize_source.o +sanitize_system.o +-loblibs +-lskarnet + diff --git a/src/lib66/sanitize/sanitize_fdholder.c b/src/lib66/sanitize/sanitize_fdholder.c new file mode 100644 index 0000000000000000000000000000000000000000..98069f28bb0450c89e0bd2bce7260a8eb35ec045 --- /dev/null +++ b/src/lib66/sanitize/sanitize_fdholder.c @@ -0,0 +1,131 @@ +/* + * 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) ; + } +} diff --git a/src/lib66/sanitize/sanitize_init.c b/src/lib66/sanitize/sanitize_init.c new file mode 100644 index 0000000000000000000000000000000000000000..1d83724f40fa9daa03fc169f6b33dc4b3345fb04 --- /dev/null +++ b/src/lib66/sanitize/sanitize_init.c @@ -0,0 +1,220 @@ +/* + * 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) ; + +} diff --git a/src/lib66/sanitize/sanitize_livestate.c b/src/lib66/sanitize/sanitize_livestate.c new file mode 100644 index 0000000000000000000000000000000000000000..f47999cf2f02dea09dcf8b225a18c0d76e98c3c7 --- /dev/null +++ b/src/lib66/sanitize/sanitize_livestate.c @@ -0,0 +1,121 @@ +/* + * 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) ; + +} diff --git a/src/lib66/sanitize/sanitize_scandir.c b/src/lib66/sanitize/sanitize_scandir.c new file mode 100644 index 0000000000000000000000000000000000000000..46dfa8c696f1ce4a85148f6f2898609b036f32f8 --- /dev/null +++ b/src/lib66/sanitize/sanitize_scandir.c @@ -0,0 +1,165 @@ +/* + * 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) ; + } + } +} diff --git a/src/lib66/sanitize/sanitize_source.c b/src/lib66/sanitize/sanitize_source.c new file mode 100644 index 0000000000000000000000000000000000000000..043b5176b9a9177e53b3cc2f97d334dd3d4ca59b --- /dev/null +++ b/src/lib66/sanitize/sanitize_source.c @@ -0,0 +1,66 @@ +/* + * 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) ; + + } + +} + diff --git a/src/lib66/sanitize/sanitize_system.c b/src/lib66/sanitize/sanitize_system.c new file mode 100644 index 0000000000000000000000000000000000000000..b9d9fa6e6706f7bc09b05a0a6c93c161f4a00bef --- /dev/null +++ b/src/lib66/sanitize/sanitize_system.c @@ -0,0 +1,169 @@ +/* + * 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 ; +}