Added NG... ;)
This commit is contained in:
parent
09537c955f
commit
38f60772da
3 changed files with 158 additions and 1 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -3,4 +3,4 @@ chkgrp-min
|
|||
chkgrp-native
|
||||
chkgrp-native-min
|
||||
chkgrp-native-min-extended
|
||||
|
||||
chkgrp-ng
|
||||
|
|
|
|||
4
Makefile
4
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
|
||||
|
||||
|
|
|
|||
153
chkgrp-ng.c
Normal file
153
chkgrp-ng.c
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
/**
|
||||
* chkgrp-ng is a program that checks if a user is a member of a group.
|
||||
*
|
||||
* Author: Johannes Findeisen <you@hanez.org> - 2025
|
||||
* Homepage: https://git.xw3.org/hanez/chkgrp
|
||||
* License: Apache-2.0 (see LICENSE)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_LINE 1024
|
||||
#define MAX_NAME 256
|
||||
|
||||
void print_help(const char *prog)
|
||||
{
|
||||
printf("Usage: %s [OPTIONS] <username> <groupname>\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;
|
||||
}
|
||||
|
||||
Reference in a new issue