]> err.no Git - util-linux/commitdiff
newgrp: add support for /etc/gshadow
authorKarel Zak <kzak@redhat.com>
Wed, 21 Mar 2007 22:07:25 +0000 (23:07 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 21 Mar 2007 22:07:25 +0000 (23:07 +0100)
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>
include/pathnames.h
login-utils/newgrp.c

index d9e05b3215adcc379db4de31e6a647d37332d878..ec2c236baddc515fa194ec41c2762a426c90a0eb 100644 (file)
@@ -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"
index 13475f3e149aee7db59bfd1acecbc866f312d08b..189a38262f4713da928a671e4a1eca091277e695 100644 (file)
 # 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 */
 }