Merged with chkgrp and renamed to chkusr.

This commit is contained in:
Johannes Findeisen 2025-06-27 00:57:42 +02:00
commit 8644ccbdc5
12 changed files with 779 additions and 22 deletions

9
.gitignore vendored
View file

@ -1,5 +1,12 @@
*.o
*.so
chkgrp
chkgrp-min
chkgrp-native
chkgrp-native-min
chkgrp-native-min-extended
chkgrp-ng
chkpwd chkpwd
chkpwd.o
chkpwd.1.gz chkpwd.1.gz
test test
test.c test.c

View file

@ -1,18 +1,44 @@
all: 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
$(CC) -Wall -o ./chkgrp-native-min-extended ./chkgrp-native-min-extended.c
$(CC) -Wall -o ./chkgrp-ng ./chkgrp-ng.c
$(CC) -Wall -o ./chkpwd ./chkpwd.c -lpam $(CC) -Wall -o ./chkpwd ./chkpwd.c -lpam
gzip -fk ./chkpwd.1 gzip -fk ./chkpwd.1
clean: clean:
rm -f ./chkgrp
rm -f ./chkgrp-min
rm -f ./chkgrp-native
rm -f ./chkgrp-native-min
rm -f ./chkgrp-native-min-extended
rm -f ./chkgrp-ng
rm -f ./chkpwd rm -f ./chkpwd
rm -f ./chkpwd.1.gz rm -f ./chkpwd.1.gz
rm -f ./test rm -f ./test
install: 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/
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 ./chkpwd /usr/bin/ install -g 0 -o 0 -m 0655 ./chkpwd /usr/bin/
install -g 0 -o 0 -m 0644 ./chkpwd.h /usr/include/ install -g 0 -o 0 -m 0644 ./chkpwd.h /usr/include/
install -g 0 -o 0 -m 0644 ./chkpwd.1.gz /usr/share/man/man1/ install -g 0 -o 0 -m 0644 ./chkpwd.1.gz /usr/share/man/man1/
install -g 0 -o 0 -m 0655 ./lua/chkgrp-native-min-extended.lua /usr/bin/
uninstall: 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
rm -f /usr/bin/chkgrp-native-min-extended
rm -f /usr/bin/chkgrp-native-min-extended.lua
rm -f /usr/bin/chkgrp-ng
rm -f /usr/bin/chkpwd rm -f /usr/bin/chkpwd
rm -f /usr/include/chkpwd.h rm -f /usr/include/chkpwd.h
rm -f /usr/share/man/man1/chkpwd.1.gz rm -f /usr/share/man/man1/chkpwd.1.gz

View file

@ -1,18 +1,30 @@
# chkpwd # MERGED PROJECT!!! I WILL UPDATE THIS README IN THE NEXT DAYS!!! THE FOLLOWING DOCUMENTATION WILL NOT WORK ACTUALLY!
# chkusr
chkusr is a set of programs to verify information about a user on a UNIX based systems.
## 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.
More information will follow... Actually there are multiple programs with some different behavior. I will write more about this, but for now I will not.
## chkpwd
chkpwd is a program that checks the validity of a users password on a UNIX/[PAM](https://en.wikipedia.org/wiki/Pluggable_Authentication_Module)-based system. chkpwd is a program that checks the validity of a users password on a UNIX/[PAM](https://en.wikipedia.org/wiki/Pluggable_Authentication_Module)-based system.
Currently chkpwd is only tested on Linux, but it should work on a [AIX](https://en.wikipedia.org/wiki/IBM_AIX), [DragonFly BSD](https://www.dragonflybsd.org/), [FreeBSD](https://www.freebsd.org/), [HP-UX](https://en.wikipedia.org/wiki/HP-UX), [Linux](https://kernel.org/), [macOS](https://en.wikipedia.org/wiki/MacOS), [NetBSD](https://netbsd.org/) and [Solaris](https://en.wikipedia.org/wiki/Oracle_Solaris) operating system too. Currently chkpwd is only tested on Linux, but it should work on a [AIX](https://en.wikipedia.org/wiki/IBM_AIX), [DragonFly BSD](https://www.dragonflybsd.org/), [FreeBSD](https://www.freebsd.org/), [HP-UX](https://en.wikipedia.org/wiki/HP-UX), [Linux](https://kernel.org/), [macOS](https://en.wikipedia.org/wiki/MacOS), [NetBSD](https://netbsd.org/) and [Solaris](https://en.wikipedia.org/wiki/Oracle_Solaris) operating system too.
## The idea ### The idea
I needed a program to verify passwords of users on Linux/UNIX systems using PAM that just returns 0 on success and 1 on error. I needed a program to verify passwords of users on Linux/UNIX systems using PAM that just returns 0 on success and 1 on error.
## Requirements ### Requirements
You need the PAM development package installed. On Alpine it is named linux-pam-dev, on Debian based systems it is libpam0g-dev. You need the PAM development package installed. On Alpine it is named linux-pam-dev, on Debian based systems it is libpam0g-dev.
## Building chkpwd ### Building chkpwd
``` ```
git clone https://git.xw3.org/hanez/chkpwd.git git clone https://git.xw3.org/hanez/chkpwd.git
@ -22,7 +34,7 @@ make
The code only supports verifying passwords for user id 1000 by default. Look at the file chkpwd.h for some compile time options! The code only supports verifying passwords for user id 1000 by default. Look at the file chkpwd.h for some compile time options!
### Custom build example #### Custom build example
Set MAX_UID and MIN_UID at compile time: Set MAX_UID and MIN_UID at compile time:
@ -30,7 +42,7 @@ Set MAX_UID and MIN_UID at compile time:
gcc -Wall -DMAX_UID=1000 -DMIN_UID=1000 -o chkpwd chkpwd.c -lpam -lpam_misc gcc -Wall -DMAX_UID=1000 -DMIN_UID=1000 -o chkpwd chkpwd.c -lpam -lpam_misc
``` ```
## Installation ### Installation
**WARNING:** Install this software with care. chkpwd could easily be used for bruteforcing passwords from local users! **WARNING:** Install this software with care. chkpwd could easily be used for bruteforcing passwords from local users!
@ -42,13 +54,13 @@ chkpwd is installed to /usr/bin/.
chkpwd.h is installed to /usr/include/ for use in other applications. chkpwd.h is installed to /usr/include/ for use in other applications.
## Uninstall ### Uninstall
``` ```
sudo make uninstall sudo make uninstall
``` ```
## Usage ### Usage
``` ```
chkpwd -h chkpwd -h
@ -68,44 +80,38 @@ You can also use chkpwd even without installing by just running the following co
./chkpwd ./chkpwd
``` ```
### Return codes #### Return codes
chkpwd returns 0 on success, 1 otherwise. chkpwd returns 0 on success, 1 otherwise.
### Examples #### Examples
#### Interactive mode asking for a username and a password ##### Interactive mode asking for a username and a password
``` ```
chkpwd chkpwd
``` ```
#### Interactive mode only asking for a password ##### Interactive mode only asking for a password
``` ```
chkpwd -u hanez chkpwd -u hanez
``` ```
#### None interactive mode with username and password provided as arguments to chkpwd ##### None interactive mode with username and password provided as arguments to chkpwd
``` ```
chkpwd -u hanez -p password chkpwd -u hanez -p password
``` ```
#### Request the result from the above commands ##### Request the result from the above commands
``` ```
echo $? echo $?
``` ```
## License #### Links
chkpwd is licensed under the Apache License, Version 2.0.
See LICENSE for details.
## Links
- [https://git.xw3.org/hanez/chkpwd](https://git.xw3.org/hanez/chkpwd) - [https://git.xw3.org/hanez/chkpwd](https://git.xw3.org/hanez/chkpwd)
- [https://www.man7.org/linux/man-pages/man8/unix_chkpwd.8.html](https://www.man7.org/linux/man-pages/man8/unix_chkpwd.8.html) - [https://www.man7.org/linux/man-pages/man8/unix_chkpwd.8.html](https://www.man7.org/linux/man-pages/man8/unix_chkpwd.8.html)
@ -115,3 +121,9 @@ See LICENSE for details.
- [https://github.com/ViKingIX/pam_test](https://github.com/ViKingIX/pam_test) - [https://github.com/ViKingIX/pam_test](https://github.com/ViKingIX/pam_test)
- [https://github.com/Dareka826/chk_pw](https://github.com/Dareka826/chk_pw) - [https://github.com/Dareka826/chk_pw](https://github.com/Dareka826/chk_pw)
## License
chkpwd is licensed under the Apache License, Version 2.0.
See LICENSE for details.

48
chkgrp-min.c Normal file
View file

@ -0,0 +1,48 @@
/**
* chkgrp-min 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>
#include <pwd.h>
#include <grp.h>
#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;
}

View file

@ -0,0 +1,102 @@
/**
* chkgrp-min-native-extended 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>
#include <ctype.h>
#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;
// Step 1: Find user in /etc/passwd to get their primary GID
FILE *passwd = fopen("/etc/passwd", "r");
if (!passwd)
return 2;
char line[MAX_LINE];
int user_gid = -1;
while (fgets(line, sizeof(line), passwd)) {
char *u = strtok(line, ":");
if (!u || strcmp(u, username) != 0)
continue;
strtok(NULL, ":"); // skip password
strtok(NULL, ":"); // skip UID
char *gid_str = strtok(NULL, ":");
if (!gid_str)
break;
user_gid = atoi(gid_str);
break;
}
fclose(passwd);
if (user_gid < 0)
return 2;
// Step 2: Find group in /etc/group and check membership or GID match
FILE *group = fopen("/etc/group", "r");
if (!group)
return 2;
int found = 0;
while (fgets(line, sizeof(line), group)) {
char *grp = strtok(line, ":");
if (!grp || strcmp(grp, groupname) != 0)
continue;
strtok(NULL, ":"); // skip password
char *gid_str = strtok(NULL, ":");
if (!gid_str)
break;
int group_gid = atoi(gid_str);
if (group_gid == user_gid) {
puts("Yes");
fclose(group);
return 0;
}
char *members = strtok(NULL, ":\n");
if (!members)
break;
char *m = strtok(members, ",");
while (m) {
if (!strcmp(m, username)) {
puts("Yes");
fclose(group);
return 0;
}
m = strtok(NULL, ",");
}
found = 1;
break;
}
fclose(group);
if (!found)
return 2;
puts("No");
return 1;
}

60
chkgrp-native-min.c Normal file
View file

@ -0,0 +1,60 @@
/**
* chkgrp-min-native 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
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;
}

78
chkgrp-native.c Normal file
View file

@ -0,0 +1,78 @@
/**
* chkgrp-native 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
int main(int argc, char *argv[])
{
if (argc != 3) {
fprintf(stderr, "Usage: %s <username> <groupname>\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;
}

153
chkgrp-ng.c Normal file
View 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;
}

77
chkgrp.c Normal file
View file

@ -0,0 +1,77 @@
/**
* chkgrp 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>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#ifndef LOGIN_NAME_MAX
#define LOGIN_NAME_MAX 256
#endif
int main(int argc, char *argv[])
{
if (argc != 3) {
fprintf(stderr, "Usage: %s <username> <groupname>\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;
}

79
lua/checkgroup.lua Normal file
View file

@ -0,0 +1,79 @@
-- This file is part of chkgrp that 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)
local checkgroup = {}
local MAX_NAME = 256
local function read_passwd_gid(username)
local f = io.open("/etc/passwd", "r")
if not f then return nil end
for line in f:lines() do
local fields = {}
for field in string.gmatch(line, "([^:]+)") do
table.insert(fields, field)
end
if fields[1] == username then
f:close()
return tonumber(fields[4])
end
end
f:close()
return nil
end
local function check_group_membership(username, groupname, user_gid)
local f = io.open("/etc/group", "r")
if not f then return nil end
for line in f:lines() do
local fields = {}
for field in string.gmatch(line, "([^:]+)") do
table.insert(fields, field)
end
if fields[1] == groupname then
local group_gid = tonumber(fields[3])
if group_gid == user_gid then
f:close()
return true
end
for member in string.gmatch(fields[4] or "", "[^,]+") do
if member == username then
f:close()
return true
end
end
f:close()
return false
end
end
f:close()
return nil
end
function checkgroup.is_user_in_group(username, groupname)
if not username or not groupname then
return nil
end
if #username > MAX_NAME or #groupname > MAX_NAME then
return nil
end
local gid = read_passwd_gid(username)
if not gid then return nil end
return check_group_membership(username, groupname, gid)
end
return checkgroup

View file

@ -0,0 +1,89 @@
#!/usr/bin/env lua
-- This file is part of chkgrp that 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)
local MAX_NAME = 256
local function read_passwd_gid(username)
local f = io.open("/etc/passwd", "r")
if not f then return nil end
for line in f:lines() do
local fields = {}
for field in string.gmatch(line, "([^:]+)") do
table.insert(fields, field)
end
if fields[1] == username then
f:close()
return tonumber(fields[4]) -- GID is 4th field
end
end
f:close()
return nil
end
local function check_group_membership(username, groupname, user_gid)
local f = io.open("/etc/group", "r")
if not f then return nil end
for line in f:lines() do
local fields = {}
for field in string.gmatch(line, "([^:]+)") do
table.insert(fields, field)
end
if fields[1] == groupname then
local group_gid = tonumber(fields[3])
if group_gid == user_gid then
f:close()
return true
end
for member in string.gmatch(fields[4] or "", "[^,]+") do
if member == username then
f:close()
return true
end
end
f:close()
return false
end
end
f:close()
return nil
end
local username = arg[1]
local groupname = arg[2]
if not username or not groupname then
os.exit(2)
end
if #username > MAX_NAME or #groupname > MAX_NAME then
os.exit(2)
end
local user_gid = read_passwd_gid(username)
if not user_gid then
os.exit(2)
end
local result = check_group_membership(username, groupname, user_gid)
if result == nil then
os.exit(2)
elseif result == true then
print("Yes")
os.exit(0)
else
print("No")
os.exit(1)
end

26
lua/test.lua Executable file
View file

@ -0,0 +1,26 @@
#!/usr/bin/env lua
-- This file is part of chkgrp that 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)
local checkgroup = require("checkgroup")
local user = arg[1]
local group = arg[2]
local result = checkgroup.is_user_in_group(user, group)
if result == true then
print("Yes")
os.exit(0)
elseif result == false then
print("No")
os.exit(1)
else
os.exit(2)
end