Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2023-01-13 22:59:07 +0300
committerCorinna Vinschen <corinna@vinschen.de>2023-01-13 22:59:29 +0300
commitc8ddd03cb015cf7f9137c42a6cbd0639c6c93a23 (patch)
treed6f7618d87e7337cb995991038e492beae9c0dc0
parent6072dcfc346f6d5409bb8324dec1d7e8e08c22ef (diff)
Cygwin: add very simple newgrp(1) tool
This tool allows to change the primary group for a child process. The new primary group MUST be part of the supplementary group list of newgrp's user token. The command started as child process is specified on the command line. If it's missing, start the user's default shell with the new primary group. TODO: Implement '-' option. Add command description to documentation. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--winsup/utils/Makefile.am1
-rw-r--r--winsup/utils/newgrp.c101
2 files changed, 102 insertions, 0 deletions
diff --git a/winsup/utils/Makefile.am b/winsup/utils/Makefile.am
index 6be5b12c2..75da1163b 100644
--- a/winsup/utils/Makefile.am
+++ b/winsup/utils/Makefile.am
@@ -31,6 +31,7 @@ bin_PROGRAMS = \
mkgroup \
mkpasswd \
mount \
+ newgrp \
passwd \
pldd \
profiler \
diff --git a/winsup/utils/newgrp.c b/winsup/utils/newgrp.c
new file mode 100644
index 000000000..012c3188f
--- /dev/null
+++ b/winsup/utils/newgrp.c
@@ -0,0 +1,101 @@
+/* newgrp.c
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+#include <grp.h>
+#include <pwd.h>
+
+int
+main (int argc, const char **argv)
+{
+ struct group *gr;
+ gid_t gid;
+ const char *cmd;
+ const char **cmd_av;
+ const char *fake_av[2];
+
+ /* TODO: Implement '-' option */
+ /* TODO: Add command description to documentation */
+
+ if (argc < 2 || argv[1][0] == '-')
+ {
+ fprintf (stderr,
+ "Usage: %1$s group [command [args...]]\n"
+ "\n"
+ "%1$s changes the current primary group for a command.\n"
+ "The primary group must be member of the supplementary group\n"
+ "list of the user.\n"
+ "The command and its arguments are specified on the command\n"
+ "line. Default is the user's standard shell.\n",
+ program_invocation_short_name);
+ return 1;
+ }
+ if (isdigit ((int) argv[1][0]))
+ {
+ char *e = NULL;
+
+ gid = strtol (argv[1], &e, 10);
+ if (e && *e != '\0')
+ {
+ fprintf (stderr, "%s: invalid gid `%s'\n",
+ program_invocation_short_name, argv[1]);
+ return 2;
+ }
+ gr = getgrgid (gid);
+ if (!gr)
+ {
+ fprintf (stderr, "%s: unknown group gid `%u'\n",
+ program_invocation_short_name, gid);
+ return 2;
+ }
+ }
+ else
+ {
+ gr = getgrnam (argv[1]);
+ if (!gr)
+ {
+ fprintf (stderr, "%s: unknown group name `%s'\n",
+ program_invocation_short_name, argv[1]);
+ return 2;
+ }
+ gid = gr->gr_gid;
+ }
+ if (setgid (gid) != 0)
+ {
+ fprintf (stderr, "%s: can't switch primary group to `%s'\n",
+ program_invocation_short_name, argv[1]);
+ return 2;
+ }
+ argc -= 2;
+ argv += 2;
+ if (argc < 1)
+ {
+ struct passwd *pw = getpwuid (getuid ());
+ if (!pw)
+ cmd = "/usr/bin/bash";
+ else
+ cmd = pw->pw_shell;
+ fake_av[0] = cmd;
+ fake_av[1] = NULL;
+ cmd_av = fake_av;
+ }
+ else
+ {
+ cmd = argv[0];
+ cmd_av = argv;
+ }
+ execvp (cmd, (char **) cmd_av);
+ fprintf (stderr, "%s: failed to start `%s': %s\n",
+ program_invocation_short_name, cmd, strerror (errno));
+ return 3;
+}