From 38f60772da4e4a1c11d010232498ac162f826872 Mon Sep 17 00:00:00 2001 From: hanez Date: Thu, 19 Jun 2025 01:15:24 +0200 Subject: [PATCH] Added NG... ;) --- .gitignore | 2 +- Makefile | 4 ++ chkgrp-ng.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 chkgrp-ng.c diff --git a/.gitignore b/.gitignore index f03ba1c..5f9f08e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ chkgrp-min chkgrp-native chkgrp-native-min chkgrp-native-min-extended - +chkgrp-ng diff --git a/Makefile b/Makefile index 162f0f5..29ecc73 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ all: $(CC) -Wall -o ./chkgrp-native ./chkgrp-native.c $(CC) -Wall -o ./chkgrp-native-min ./chkgrp-native-min.c $(CC) -Wall -o ./chkgrp-native-min-extended ./chkgrp-native-min-extended.c + $(CC) -Wall -o ./chkgrp-ng ./chkgrp-ng.c clean: rm -f ./chkgrp @@ -11,6 +12,7 @@ clean: rm -f ./chkgrp-native rm -f ./chkgrp-native-min rm -f ./chkgrp-native-min-extended + rm -f ./chkgrp-ng install: install -g 0 -o 0 -m 0655 ./chkgrp /usr/bin/ @@ -18,6 +20,7 @@ install: install -g 0 -o 0 -m 0655 ./chkgrp-native /usr/bin/ install -g 0 -o 0 -m 0655 ./chkgrp-native-min /usr/bin/ install -g 0 -o 0 -m 0655 ./chkgrp-native-min-extended /usr/bin/ + install -g 0 -o 0 -m 0655 ./chkgrp-ng /usr/bin/ install -g 0 -o 0 -m 0655 ./lua/chkgrp-native-min-extended.lua /usr/bin/ uninstall: @@ -27,4 +30,5 @@ uninstall: rm -f /usr/bin/chkgrp-native-min rm -f /usr/bin/chkgrp-native-min-extended rm -f /usr/bin/chkgrp-native-min-extended.lua + rm -f /usr/bin/chkgrp-ng diff --git a/chkgrp-ng.c b/chkgrp-ng.c new file mode 100644 index 0000000..8faa900 --- /dev/null +++ b/chkgrp-ng.c @@ -0,0 +1,153 @@ +/** + * chkgrp-ng is a program that checks if a user is a member of a group. + * + * Author: Johannes Findeisen - 2025 + * Homepage: https://git.xw3.org/hanez/chkgrp + * License: Apache-2.0 (see LICENSE) + */ + +#include +#include +#include + +#define MAX_LINE 1024 +#define MAX_NAME 256 + +void print_help(const char *prog) +{ + printf("Usage: %s [OPTIONS] \n", prog); + printf("Options:\n"); + printf(" --passwd PATH Use custom /etc/passwd file\n"); + printf(" --group PATH Use custom /etc/group file\n"); + printf(" -q Quiet mode (no output)\n"); + printf(" -h Show this help message\n"); +} + +const char *get_arg(int *i, int argc, char *argv[], const char *opt) +{ + if (*i + 1 >= argc) { + fprintf(stderr, "Missing argument after %s\n", opt); + exit(2); + } + return argv[++(*i)]; +} + +int get_user_gid(const char *user, const char *passwd_path) +{ + FILE *fp = fopen(passwd_path, "r"); + if (!fp) { + fprintf(stderr, "Error: Cannot open passwd file: %s\n", passwd_path); + return -1; + } + + char line[MAX_LINE]; + while (fgets(line, sizeof(line), fp)) { + char *name = strtok(line, ":"); + if (!name || strcmp(name, user) != 0) continue; + + strtok(NULL, ":"); // password + strtok(NULL, ":"); // UID + char *gid_str = strtok(NULL, ":"); + fclose(fp); + return gid_str ? atoi(gid_str) : -1; + } + + fclose(fp); + return -1; +} + +int check_group(const char *user, const char *group, int user_gid, + const char *group_path) +{ + FILE *fp = fopen(group_path, "r"); + if (!fp) { + fprintf(stderr, "Error: Cannot open group file: %s\n", group_path); + return -1; + } + + char line[MAX_LINE]; + while (fgets(line, sizeof(line), fp)) { + char *grp = strtok(line, ":"); + if (!grp || strcmp(grp, group) != 0) continue; + + strtok(NULL, ":"); // password + char *gid_str = strtok(NULL, ":"); + if (!gid_str) break; + + int group_gid = atoi(gid_str); + if (group_gid == user_gid) { + fclose(fp); + return 1; + } + + char *members = strtok(NULL, ":\n"); + if (!members) break; + + char *m = strtok(members, ","); + while (m) { + if (strcmp(m, user) == 0) { + fclose(fp); + return 1; + } + m = strtok(NULL, ","); + } + + fclose(fp); + return 0; + } + + fclose(fp); + return -1; +} + +int main(int argc, char *argv[]) +{ + const char *passwd_file = "/etc/passwd"; + const char *group_file = "/etc/group"; + int quiet = 0; + + int i = 1; + const char *username = NULL, *groupname = NULL; + + while (i < argc) { + if (!strcmp(argv[i], "--passwd")) { + passwd_file = get_arg(&i, argc, argv, "--passwd"); + } else if (!strcmp(argv[i], "--group")) { + group_file = get_arg(&i, argc, argv, "--group"); + } else if (!strcmp(argv[i], "-q")) { + quiet = 1; + } else if (!strcmp(argv[i], "-h")) { + print_help(argv[0]); + return 0; + } else if (!username) { + username = argv[i]; + } else if (!groupname) { + groupname = argv[i]; + } else { + fprintf(stderr, "Unexpected argument: %s\n", argv[i]); + return 2; + } + i++; + } + + if (!username || !groupname || + strlen(username) > MAX_NAME || strlen(groupname) > MAX_NAME) { + return 2; + } + + int user_gid = get_user_gid(username, passwd_file); + if (user_gid < 0) + return 2; + + int result = check_group(username, groupname, user_gid, group_file); + if (result == 1) { + if (!quiet) puts("Yes"); + return 0; + } else if (result == 0) { + if (!quiet) puts("No"); + return 1; + } + + return 2; +} +