From: Karel Zak Date: Wed, 21 Mar 2007 22:07:25 +0000 (+0100) Subject: newgrp: add support for /etc/gshadow X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=66a9411eb0dec245b0dd781837442586521b5550;p=util-linux 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 --- diff --git a/include/pathnames.h b/include/pathnames.h index d9e05b32..ec2c236b 100644 --- a/include/pathnames.h +++ b/include/pathnames.h @@ -134,6 +134,9 @@ Libc5 and glibc 2.0-2.1 have /var/spool/mail, but glibc 2.1.1 has /var/mail. /* used in login-utils/setpwnam.h and login-utils/islocal.c */ #define _PATH_PASSWD "/etc/passwd" +/* used in login-utils/newgrp */ +#define _PATH_GSHADOW "/etc/gshadow" + /* used in login-utils/setpwnam.h */ #define _PATH_PTMP "/etc/ptmp" #define _PATH_PTMPTMP "/etc/ptmptmp" diff --git a/login-utils/newgrp.c b/login-utils/newgrp.c index 13475f3e..189a3826 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 */ }