1 /* setgrp.c - by Michael Haardt. Set the gid if possible
2 * Added a bit more error recovery/reporting - poe
3 * Vesa Roukonen added code for asking password */
5 /* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
6 * - added Native Language Support
10 * This command is deprecated. The utility is in maintenance mode,
11 * meaning we keep them in source tree for backward compatibility
12 * only. Do not waste time making this command better, unless the
13 * fix is about security or other very critical issue.
15 * See Documentation/deprecated.txt for more information.
32 #include "closestream.h"
34 #include "pathnames.h"
36 /* try to read password from gshadow */
37 static char *get_gshadow_pwd(char *groupname
)
43 if (groupname
== NULL
|| *groupname
== '\0')
46 f
= fopen(_PATH_GSHADOW
, "r");
50 while (fgets(buf
, sizeof buf
, f
)) {
51 char *cp
= strchr(buf
, ':');
53 /* any junk in gshadow? */
56 if (strcmp(buf
, groupname
) == 0) {
57 if (cp
- buf
>= BUFSIZ
)
58 /* only group name on line */
61 if ((cp
= strchr(pwd
, ':')) && pwd
== cp
+ 1)
70 return pwd
? strdup(pwd
) : NULL
;
73 static int allow_setgid(struct passwd
*pe
, struct group
*ge
)
80 /* root may do anything */
82 if (ge
->gr_gid
== pe
->pw_gid
)
83 /* You can switch back to your default group */
87 while (*look
&& (notfound
= strcmp(*look
++, pe
->pw_name
))) ;
90 /* member of group => OK */
93 /* Ask for password. Often there is no password in /etc/group, so
94 * contrary to login et al. we let an empty password mean the same
95 * as in /etc/passwd */
97 /* check /etc/gshadow */
98 if (!(pwd
= get_gshadow_pwd(ge
->gr_name
)))
101 if (pwd
&& *pwd
&& (xpwd
= getpass(_("Password: ")))) {
102 char *cbuf
= crypt(xpwd
, pwd
);
105 warn(_("crypt() failed"));
106 else if (strcmp(pwd
, cbuf
) == 0)
110 /* default to denial */
114 static void __attribute__ ((__noreturn__
)) usage(FILE * out
)
116 fprintf(out
, USAGE_HEADER
);
117 fprintf(out
, _(" %s <group>\n"), program_invocation_short_name
);
118 fprintf(out
, USAGE_OPTIONS
);
119 fprintf(out
, USAGE_HELP
);
120 fprintf(out
, USAGE_VERSION
);
121 fprintf(out
, USAGE_MAN_TAIL("newgrp(1)"));
122 exit(out
== stderr
? EXIT_FAILURE
: EXIT_SUCCESS
);
125 int main(int argc
, char *argv
[])
127 struct passwd
*pw_entry
;
128 struct group
*gr_entry
;
131 static const struct option longopts
[] = {
132 {"version", no_argument
, NULL
, 'V'},
133 {"help", no_argument
, NULL
, 'h'},
137 setlocale(LC_ALL
, "");
138 bindtextdomain(PACKAGE
, LOCALEDIR
);
140 atexit(close_stdout
);
142 while ((ch
= getopt_long(argc
, argv
, "Vh", longopts
, NULL
)) != -1)
145 printf(UTIL_LINUX_VERSION
);
153 if (!(pw_entry
= getpwuid(getuid())))
154 err(EXIT_FAILURE
, _("who are you?"));
156 shell
= (pw_entry
->pw_shell
&& *pw_entry
->pw_shell
?
157 pw_entry
->pw_shell
: _PATH_BSHELL
);
160 if (setgid(pw_entry
->pw_gid
) < 0)
161 err(EXIT_FAILURE
, _("setgid failed"));
164 if (!(gr_entry
= getgrnam(argv
[1]))) {
166 err(EXIT_FAILURE
, _("no such group"));
169 errx(EXIT_FAILURE
, _("no such group"));
171 if (allow_setgid(pw_entry
, gr_entry
)) {
172 if (setgid(gr_entry
->gr_gid
) < 0)
173 err(EXIT_FAILURE
, _("setgid failed"));
175 errx(EXIT_FAILURE
, _("permission denied"));
179 if (setuid(getuid()) < 0)
180 err(EXIT_FAILURE
, _("setuid failed"));
184 execl(shell
, shell
, (char *)0);
185 warn(_("exec %s failed"), shell
);