From 9fd2e3573ec65ff11f1e54bf8558b4e5b24a58c6 Mon Sep 17 00:00:00 2001 From: hanez Date: Wed, 18 Jun 2025 21:31:20 +0200 Subject: [PATCH] Initial commit 2.0 --- .gitignore | 5 +++ LICENSE | 2 +- Makefile | 24 ++++++++++++++ README.md | 6 ++++ chkgrp-min.c | 48 ++++++++++++++++++++++++++++ chkgrp-native-min.c | 60 ++++++++++++++++++++++++++++++++++ chkgrp-native.c | 78 +++++++++++++++++++++++++++++++++++++++++++++ chkgrp.c | 77 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 chkgrp-min.c create mode 100644 chkgrp-native-min.c create mode 100644 chkgrp-native.c create mode 100644 chkgrp.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..538d43e --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +chkgrp +chkgrp-min +chkgrp-native +chkgrp-native-min + diff --git a/LICENSE b/LICENSE index 247aa29..d2c57e8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2024 Johannes Findeisen +Copyright 2025 Johannes Findeisen Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8de95ca --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +all: + $(CC) -Wall -o ./chkgrp ./chkgrp.c + $(CC) -Wall -o ./chkgrp-min ./chkgrp-min.c + $(CC) -Wall -o ./chkgrp-native ./chkgrp-native.c + $(CC) -Wall -o ./chkgrp-native-min ./chkgrp-native-min.c + +clean: + rm -f ./chkgrp + rm -f ./chkgrp-min + rm -f ./chkgrp-native + rm -f ./chkgrp-native-min + +install: + install -g 0 -o 0 -m 0655 ./chkgrp /usr/bin/ + install -g 0 -o 0 -m 0655 ./chkgrp-min /usr/bin/ + install -g 0 -o 0 -m 0655 ./chkgrp-native /usr/bin/ + install -g 0 -o 0 -m 0655 ./chkgrp-native-min /usr/bin/ + +uninstall: + rm -f /usr/bin/chkgrp + rm -f /usr/bin/chkgrp-min + rm -f /usr/bin/chkgrp-native + rm -f /usr/bin/chkgrp-native-min + diff --git a/README.md b/README.md index e69de29..54b6892 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,6 @@ +# chkgrp + +chkgrp is a set of programs to verify if a user is a member of a group on a UNIX based system. This code is so simple that it describes itself very good. + +Mor information will follow... + diff --git a/chkgrp-min.c b/chkgrp-min.c new file mode 100644 index 0000000..2fe002a --- /dev/null +++ b/chkgrp-min.c @@ -0,0 +1,48 @@ +/** + * chkgrp-min 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 +#include +#include + +#define MAX_NAME 256 + +int main(int argc, char *argv[]) +{ + if (argc != 3) + return 2; + + if (strlen(argv[1]) > MAX_NAME || strlen(argv[2]) > MAX_NAME) + return 2; + + struct passwd *pw = getpwnam(argv[1]); + if (!pw) + return 2; + + struct group *gr = getgrnam(argv[2]); + if (!gr) + return 2; + + if (pw->pw_gid == gr->gr_gid) { + puts("Yes"); + return 0; + } + + for (char **m = gr->gr_mem; *m; ++m) { + if (!strcmp(*m, argv[1])) { + puts("Yes"); + return 0; + } + } + + puts("No"); + return 1; +} + diff --git a/chkgrp-native-min.c b/chkgrp-native-min.c new file mode 100644 index 0000000..c067695 --- /dev/null +++ b/chkgrp-native-min.c @@ -0,0 +1,60 @@ +/** + * chkgrp-min-native 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 + +int main(int argc, char *argv[]) +{ + if (argc != 3) + return 2; + + const char *username = argv[1]; + const char *groupname = argv[2]; + + if (strlen(username) > MAX_NAME || strlen(groupname) > MAX_NAME) + return 2; + + FILE *fp = fopen("/etc/group", "r"); + if (!fp) + return 2; + + char line[MAX_LINE]; + while (fgets(line, sizeof(line), fp)) { + char *grp = strtok(line, ":"); + if (!grp || strcmp(grp, groupname) != 0) + continue; + + strtok(NULL, ":"); // skip password + strtok(NULL, ":"); // skip GID + + char *members = strtok(NULL, ":\n"); + if (!members) break; + + char *m = strtok(members, ","); + while (m) { + if (!strcmp(m, username)) { + puts("Yes"); + fclose(fp); + return 0; + } + m = strtok(NULL, ","); + } + + break; // group matched, no user found + } + + fclose(fp); + puts("No"); + return 1; +} + diff --git a/chkgrp-native.c b/chkgrp-native.c new file mode 100644 index 0000000..bec5808 --- /dev/null +++ b/chkgrp-native.c @@ -0,0 +1,78 @@ +/** + * chkgrp-native 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 + +int main(int argc, char *argv[]) +{ + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 2; + } + + const char *username = argv[1]; + const char *groupname = argv[2]; + + if (strlen(username) > MAX_NAME || strlen(groupname) > MAX_NAME) { + fprintf(stderr, "Error: Name too long (max %d characters).\n", MAX_NAME); + return 2; + } + + FILE *fp = fopen("/etc/group", "r"); + if (!fp) { + perror("Error opening /etc/group"); + return 2; + } + + char line[MAX_LINE]; + int found = 0; + + while (fgets(line, sizeof(line), fp)) { + char *grp_name = strtok(line, ":"); + if (!grp_name) continue; + + strtok(NULL, ":"); // skip password + strtok(NULL, ":"); // skip GID + + char *members = strtok(NULL, ":\n"); + if (!members) continue; + + if (strcmp(grp_name, groupname) != 0) + continue; + + // Group found, now check for user in member list + found = 1; + char *member = strtok(members, ","); + while (member) { + if (strcmp(member, username) == 0) { + fclose(fp); + puts("Yes"); + return 0; + } + member = strtok(NULL, ","); + } + + break; // no need to continue scanning + } + + fclose(fp); + + if (!found) { + fprintf(stderr, "Group '%s' not found.\n", groupname); + return 2; + } + + puts("No"); + return 1; +} + diff --git a/chkgrp.c b/chkgrp.c new file mode 100644 index 0000000..0c668c1 --- /dev/null +++ b/chkgrp.c @@ -0,0 +1,77 @@ +/** + * chkgrp 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 +#include +#include +#include +#include +#include + +#ifndef LOGIN_NAME_MAX +#define LOGIN_NAME_MAX 256 +#endif + +int main(int argc, char *argv[]) +{ + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 2; + } + + const char *username = argv[1]; + const char *groupname = argv[2]; + + // Runtime check for max name length + long max_name_len = sysconf(_SC_LOGIN_NAME_MAX); + if (max_name_len <= 0 || max_name_len > 1024) { + max_name_len = LOGIN_NAME_MAX; + } + + if (strlen(username) > (size_t)max_name_len) { + fprintf(stderr, "Error: Username too long (max %ld characters).\n", + max_name_len); + return 2; + } + + if (strlen(groupname) > (size_t)max_name_len) { + fprintf(stderr, "Error: Group name too long (max %ld characters).\n", + max_name_len); + return 2; + } + + struct passwd *pw = getpwnam(username); + if (!pw) { + fprintf(stderr, "Error: User '%s' not found.\n", username); + return 2; + } + + struct group *gr = getgrnam(groupname); + if (!gr) { + fprintf(stderr, "Error: Group '%s' not found.\n", groupname); + return 2; + } + + if (pw->pw_gid == gr->gr_gid) { + puts("Yes"); + return 0; + } + + for (char **members = gr->gr_mem; *members != NULL; members++) { + if (strcmp(*members, username) == 0) { + puts("Yes"); + return 0; + } + } + + puts("No"); + return 1; +} +