Recreate repo
This commit is contained in:
commit
56b75106f6
12 changed files with 1195 additions and 0 deletions
134
can.c
Normal file
134
can.c
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/* SPDX-License-Identifier: GPL-3.0-only */
|
||||
/* SPDX-FileCopyrightText: 2026 afiw <afiw@linuxposting.xyz> */
|
||||
|
||||
/*
|
||||
* can - query filesystem permissions
|
||||
* Copyright (C) 2026 afiw <afiw@linuxposting.xyz>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, exclusively version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "action.h"
|
||||
#include "group.h"
|
||||
#include "user.h"
|
||||
|
||||
enum lookup_mode: char {
|
||||
LOOKUP_MODE_GID = 'G',
|
||||
LOOKUP_MODE_GROUP = 'g',
|
||||
LOOKUP_MODE_UID = 'U',
|
||||
LOOKUP_MODE_USER = 'u' };
|
||||
|
||||
[[noreturn]] static void exit_with_usage(int ec) {
|
||||
fprintf(ec == EXIT_SUCCESS ? stdout : stderr,
|
||||
"usage: %s [-GghqU] [--gid] [--group] [--help] [--quiet] [--uid] user action path\n",
|
||||
getprogname());
|
||||
exit(ec); }
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
struct option const options[] = {
|
||||
{ "gid", no_argument, nullptr, 'G' },
|
||||
{ "group", no_argument, nullptr, 'g' },
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "quiet", no_argument, nullptr, 'q' },
|
||||
{ "uid", no_argument, nullptr, 'U' } };
|
||||
int flag;
|
||||
enum lookup_mode lookup_mode = LOOKUP_MODE_USER;
|
||||
char const* lookup;
|
||||
enum action action;
|
||||
char const* path;
|
||||
struct passwd* passwd;
|
||||
struct group* group;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
char const* errstr; /* for strtonum() */
|
||||
bool quiet = false;
|
||||
bool result;
|
||||
#ifdef HAVE_PLEDGE
|
||||
if (pledge("stdio rpath getpw", nullptr) == -1) {
|
||||
err(EXIT_FAILURE, "pledge"); }
|
||||
#endif
|
||||
opterr = 0;
|
||||
while ((flag = getopt_long(argc, argv, "GghqU", options, nullptr)) != -1) {
|
||||
switch (flag) {
|
||||
case '?':
|
||||
warnx("unrecognized option: %c", optopt);
|
||||
exit_with_usage(EXIT_FAILURE);
|
||||
case 'G':
|
||||
case 'g':
|
||||
case 'U':
|
||||
lookup_mode = flag;
|
||||
break;
|
||||
case 'h':
|
||||
exit_with_usage(EXIT_SUCCESS);
|
||||
case 'q':
|
||||
quiet = true;
|
||||
break;
|
||||
default:
|
||||
errx(EXIT_FAILURE, "getopt returned %c", flag); } }
|
||||
if (argc != optind + 3) {
|
||||
exit_with_usage(EXIT_FAILURE); }
|
||||
lookup = argv[optind];
|
||||
if ((action = action_of_cstring(argv[optind + 1])) == -1) {
|
||||
warn("%s", argv[optind + 1]);
|
||||
exit_with_usage(EXIT_FAILURE); }
|
||||
path = argv[optind + 2];
|
||||
switch (lookup_mode) {
|
||||
case LOOKUP_MODE_GID:
|
||||
gid = (gid_t)strtonum(lookup, 0, (gid_t)-1, &errstr);
|
||||
if (errstr != nullptr) {
|
||||
errx(EXIT_FAILURE, "%s: %s", lookup, errstr); }
|
||||
errno = 0;
|
||||
if ((group = getgrgid(gid)) == nullptr) {
|
||||
if (errno == 0) {
|
||||
errx(EXIT_FAILURE, "%d: No such group", gid); }
|
||||
err(EXIT_FAILURE, "%d", gid); }
|
||||
result = can_group(group, action, path);
|
||||
break;
|
||||
case LOOKUP_MODE_GROUP:
|
||||
errno = 0;
|
||||
if ((group = getgrnam(lookup)) == nullptr) {
|
||||
if (errno == 0) {
|
||||
errx(EXIT_FAILURE, "%s: No such group", lookup); }
|
||||
err(EXIT_FAILURE, "%s", lookup); }
|
||||
result = can_group(group, action, path);
|
||||
break;
|
||||
case LOOKUP_MODE_UID:
|
||||
uid = (uid_t)strtonum(lookup, 0, (uid_t)-1, &errstr);
|
||||
if (errstr != nullptr) {
|
||||
errx(EXIT_FAILURE, "%s: %s", lookup, errstr); }
|
||||
errno = 0;
|
||||
if ((passwd = getpwuid(uid)) == nullptr) {
|
||||
if (errno == 0) {
|
||||
errx(EXIT_FAILURE, "%d: No such user", uid); }
|
||||
err(EXIT_FAILURE, "%d", uid); }
|
||||
result = can_user(passwd, action, path);
|
||||
break;
|
||||
case LOOKUP_MODE_USER:
|
||||
errno = 0;
|
||||
if ((passwd = getpwnam(lookup)) == nullptr) {
|
||||
if (errno == 0) {
|
||||
errx(EXIT_FAILURE, "%s: No such user", lookup); }
|
||||
err(EXIT_FAILURE, "%s", lookup); }
|
||||
result = can_user(passwd, action, path);
|
||||
break; }
|
||||
if (!quiet) {
|
||||
printf(result ? "yes\n" : "no\n"); }
|
||||
return result ? EXIT_SUCCESS : EXIT_FAILURE; }
|
||||
Loading…
Add table
Add a link
Reference in a new issue