summaryrefslogtreecommitdiffstats
path: root/login-utils/newgrp.c
diff options
context:
space:
mode:
authorKarel Zak2007-03-21 23:07:25 +0100
committerKarel Zak2007-03-21 23:07:25 +0100
commit66a9411eb0dec245b0dd781837442586521b5550 (patch)
tree24031b06219e575d5740d7f1eb30370a40d8d098 /login-utils/newgrp.c
parentnewgrp: check result from getgrnam() more carefully (diff)
downloadkernel-qcow2-util-linux-66a9411eb0dec245b0dd781837442586521b5550.tar.gz
kernel-qcow2-util-linux-66a9411eb0dec245b0dd781837442586521b5550.tar.xz
kernel-qcow2-util-linux-66a9411eb0dec245b0dd781837442586521b5550.zip
newgrp: add support for /etc/gshadow
The original newgrp command doesn't expect group pasword in /etc/gshadow although almost all distributions use this file (and the gpasswd command). The newgrp from util-linux is deprecated and better is use shadow-utils only. Unfortunately, shadow-utils are broken too (see RH version where is bugfix). In this case it's better fix util-linux version at least... Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'login-utils/newgrp.c')
-rw-r--r--login-utils/newgrp.c50
1 files changed, 43 insertions, 7 deletions
diff --git a/login-utils/newgrp.c b/login-utils/newgrp.c
index 13475f3e1..189a38262 100644
--- a/login-utils/newgrp.c
+++ b/login-utils/newgrp.c
@@ -26,12 +26,46 @@
# define FALSE 0
#endif
+/* try to read password from gshadow */
+static char *
+get_gshadow_pwd(char *groupname)
+{
+ char buf[BUFSIZ];
+ char *pwd = NULL;
+ FILE *f = fopen(_PATH_GSHADOW, "r");
+
+ if (groupname == NULL || *groupname == '\0' || f == NULL)
+ return NULL;
+
+ while(fgets(buf, sizeof buf, f))
+ {
+ char *cp = strchr (buf, ':');
+ if (!cp)
+ continue; /* any junk in gshadow? */
+ *cp = '\0';
+ if (strcmp(buf, groupname) == 0)
+ {
+ if (cp-buf >= BUFSIZ)
+ break; /* only group name on line */
+ pwd = cp+1;
+ if ((cp = strchr(pwd, ':')) && pwd == cp+1 )
+ pwd = NULL; /* empty password */
+ else if (cp)
+ *cp = '\0';
+ break;
+ }
+ }
+ fclose(f);
+ return pwd ? strdup(pwd) : NULL;
+}
+
static int
allow_setgid(struct passwd *pe, struct group *ge)
{
char **look;
int notfound = 1;
-
+ char *pwd, *xpwd;
+
if (getuid() == 0) return TRUE; /* root may do anything */
if (ge->gr_gid == pe->pw_gid) return TRUE; /* You can switch back to your default group */
@@ -44,12 +78,14 @@ allow_setgid(struct passwd *pe, struct group *ge)
contrary to login et al. we let an empty password mean the same
as * in /etc/passwd */
- if(ge->gr_passwd && ge->gr_passwd[0] != 0) {
- if(strcmp(ge->gr_passwd,
- crypt(getpass(_("Password: ")), ge->gr_passwd)) == 0) {
- return TRUE; /* password accepted */
- }
- }
+ /* check /etc/gshadow */
+ if (!(pwd = get_gshadow_pwd(ge->gr_name)))
+ pwd = ge->gr_passwd;
+
+ if(pwd && *pwd && (xpwd = getpass(_("Password: ")))) {
+ if(strcmp(pwd, crypt(xpwd, pwd)) == 0)
+ return TRUE; /* password accepted */
+ }
return FALSE; /* default to denial */
}