[Pkg-shadow-devel] Re: [Pkg-shadow-commits] r298 - trunk/debian/patches

Nicolas François nicolas.francois@centraliens.net
Sun, 26 Jun 2005 23:05:29 +0200


--zhXaljGHf11kAtnf
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hello,

On Sun, Jun 26, 2005 at 08:51:04PM +0300, Alexander Gattin wrote:
> OK. When we discussed the issue on IRC, I desided the
> way pwck works was "propagating passwd to shadow", i.e.
> master-to-shadow mirroring.
> 
> This is policy aspect, I mean this takes one source of
> data (passwd) as primary and considers other as
> derived.
> 
> Technically this has some problems. In case of
> passwd/shadow former has 7 fields while latter has 9.
> 
> So technically it's impossible to get all the data for
> shadow from passwd, when there's an entry in latter
> which is missing from the former. At least, while some
> missing fields may have reasonable defaults, e.g.
> sp_min, sp_max, sp_warn, sp_inact, others are hardly
> re-creatable (sp_pwdp, sp_lstchg, sp_expire).
> 
> I think the clash of pwck's policy against technical
> problems is the cause why pwck does nothing when
> "/etc/passwd contains an entry which is not in
> /etc/shadow". I.e. technical problems prevent pwck
> from passwd->shadow mirroring while _both_ ;) policy
> and technical problems prevent it from mirroring in
> reverse direction.

The more I dug into this, the more I was re-implementing pwconv/grpconv.
So my final implementation is quite a cut&past from {pw,grp}conv.

So maybe it is better to just issue a warning:
"This user/group does not have a shadowed entry. You should use
pwconv/grpconv to convert it to shadow."

Note: this warning will be issued only if the shadowed file exist (and
{pw,grp}ck is compiled with SHADOWPWD/SHADOWGRP.

I attach a update for 426_grpck_group-gshadow_members_consistency.
Tell me if you prefer a warning-only solution.

Also, Tomaz, as I will submit it to you later (after an update/reindent),
it would be nice to have your opinion.

Kind Regards,
-- 
Nekral

--zhXaljGHf11kAtnf
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=426_grpck_group-gshadow_members_consistency

Goal: Warn when the members of a group differ in /etc/groups and /etc/gshadow.
Fixes: #75181

Status wrt upstream: It should be forwarded to upstream.

Note: With this patch, the user will be asked to add an entry to the shadowed
      files (/etc/shadow for pwck or /etc/gshadow for grpck) when this entry is
      present in non-shadowed file and not present in the shadowed file.

Index: shadow-4.0.3/src/grpck.c
===================================================================
--- shadow-4.0.3.orig/src/grpck.c	2005-06-24 00:02:49.000000000 +0200
+++ shadow-4.0.3/src/grpck.c	2005-06-26 22:05:06.668559000 +0200
@@ -144,7 +144,7 @@
 {
 	int arg;
 	int errors = 0;
-	int deleted = 0;
+	int changed = 0;
 	int i;
 	int prune = 0;
 	struct commonio_entry *gre, *tgre;
@@ -337,7 +337,7 @@
 		      delete_gr:
 			SYSLOG ((LOG_INFO, "delete group line `%s'",
 				 gre->line));
-			deleted++;
+			changed++;
 
 			__gr_del_entry (gre);
 			continue;
@@ -432,11 +432,76 @@
 
 			SYSLOG ((LOG_INFO, "delete member `%s' group `%s'",
 				 grp->gr_mem[i], grp->gr_name));
-			deleted++;
+			changed++;
 			delete_member (grp->gr_mem, grp->gr_mem[i]);
 			gre->changed = 1;
 			__gr_set_changed ();
 		}
+
+#ifdef	SHADOWGRP
+		/*
+		 * Make sure this entry exists in the /etc/gshadow file.
+		 */
+
+		if (is_shadow)
+		{
+			sgr = (struct sgrp *)sgr_locate (grp->gr_name);
+			if (sgr == NULL) {
+				printf (_("no matching group file entry in %s\n"), sgr_file);
+				printf (_("add group `%s' in %s? "),
+				        grp->gr_name, sgr_file);
+				errors++;
+				if (yes_or_no ())
+				{
+					struct sgrp sg;
+					static char *empty = NULL;
+					sg.sg_name   = grp->gr_name;
+					sg.sg_passwd = grp->gr_passwd;
+					sg.sg_adm    = ∅
+					sg.sg_mem    = grp->gr_mem;
+					SYSLOG ((LOG_INFO, "add group `%s' to `%s'",
+					        grp->gr_name, sgr_file));
+					changed++;
+
+					if (!sgr_update(&sg))
+					{
+						fprintf (stderr,
+						         _("%s: can't update shadow entry for %s\n"),
+						         Prog, sg.sg_name);
+						exit (E_CANT_UPDATE);
+					}
+					/* remove password from /etc/group */
+					grp->gr_passwd = SHADOW_PASSWD_STRING; /* XXX warning: const */
+					if (!gr_update (grp)) {
+						fprintf (stderr,
+						         _("%s: can't update entry for group %s\n"),
+						         Prog, grp->gr_name);
+						exit (E_CANT_UPDATE);
+					}
+				}
+			} else {
+				/**
+				 * Verify that the all members defined in /etc/group are also
+				 * present in /etc/gshadow.
+				 */
+				char **pgrp_mem,**psgr_mem;
+				for (pgrp_mem=grp->gr_mem; *pgrp_mem; pgrp_mem++)
+				{
+					for (psgr_mem=sgr->sg_mem; *psgr_mem; psgr_mem++)
+					{
+						if (strcmp(*pgrp_mem, *psgr_mem) == 0)
+							break;
+					}
+					if (*psgr_mem == NULL)
+					{
+						printf ("'%s' is a member of the '%s' group in %s but not in %s\n",
+						        *pgrp_mem, sgr->sg_name, grp_file, sgr_file);
+					}
+				}
+			}
+		}
+#endif
+
 	}
 
 #ifdef	SHADOWGRP
@@ -483,7 +548,7 @@
 		      delete_sg:
 			SYSLOG ((LOG_INFO, "delete shadow line `%s'",
 				 sge->line));
-			deleted++;
+			changed++;
 
 			__sgr_del_entry (sge);
 			continue;
@@ -541,12 +606,32 @@
 		 * Make sure this entry exists in the /etc/group file.
 		 */
 
-		if (!gr_locate (sgr->sg_name)) {
-			puts (_("no matching group file entry\n"));
+		grp = (struct group *)gr_locate (sgr->sg_name);
+		if (grp == NULL) {
+			printf (_("no matching group file entry in %s\n"), grp_file);
 			printf (_("delete line `%s'? "), sge->line);
 			errors++;
 			if (yes_or_no ())
 				goto delete_sg;
+		} else {
+			/**
+			 * Verify that the all members defined in /etc/gshadow are also
+			 * present in /etc/group.
+			 */
+			char **pgrp_mem,**psgr_mem;
+			for (psgr_mem=sgr->sg_mem; *psgr_mem; psgr_mem++)
+			{
+				for (pgrp_mem=grp->gr_mem; *pgrp_mem; pgrp_mem++)
+				{
+					if (strcmp(*pgrp_mem, *psgr_mem) == 0)
+						break;
+				}
+				if (*pgrp_mem == NULL)
+				{
+					printf ("'%s' is a member of the '%s' group in %s but not in %s\n",
+					        *psgr_mem, sgr->sg_name, sgr_file, grp_file);
+				}
+			}
 		}
 
 		/*
@@ -574,7 +659,7 @@
 			SYSLOG ((LOG_INFO,
 				 "delete admin `%s' from shadow group `%s'",
 				 sgr->sg_adm[i], sgr->sg_name));
-			deleted++;
+			changed++;
 			delete_member (sgr->sg_adm, sgr->sg_adm[i]);
 			sge->changed = 1;
 			__sgr_set_changed ();
@@ -603,7 +688,7 @@
 			SYSLOG ((LOG_INFO,
 				 "delete member `%s' from shadow group `%s'",
 				 sgr->sg_mem[i], sgr->sg_name));
-			deleted++;
+			changed++;
 			delete_member (sgr->sg_mem, sgr->sg_mem[i]);
 			sge->changed = 1;
 			__sgr_set_changed ();
@@ -614,11 +699,11 @@
 #endif				/* SHADOWGRP */
 
 	/*
-	 * All done. If there were no deletions we can just abandon any
+	 * All done. If there were no change we can just abandon any
 	 * changes to the files.
 	 */
 
-	if (deleted) {
+	if (changed) {
 	      write_and_bye:
 		if (!gr_close ()) {
 			fprintf (stderr, _("%s: cannot update file %s\n"),
@@ -650,12 +735,12 @@
 
 	if (errors)
 #ifdef NDBM
-		printf (deleted ?
+		printf (changed ?
 			_
 			("%s: the files have been updated; run mkpasswd\n")
 			: _("%s: no changes\n"), Prog);
 #else
-		printf (deleted ?
+		printf (changed ?
 			_("%s: the files have been updated\n") :
 			_("%s: no changes\n"), Prog);
 #endif
Index: shadow-4.0.3/src/pwck.c
===================================================================
--- shadow-4.0.3.orig/src/pwck.c	2002-01-10 14:01:28.000000000 +0100
+++ shadow-4.0.3/src/pwck.c	2005-06-26 21:51:43.068559000 +0200
@@ -45,6 +45,7 @@
 
 #ifdef SHADOWPWD
 #include "shadowio.h"
+#include "getdef.h"
 extern void __spw_del_entry (const struct commonio_entry *);
 extern struct commonio_entry *__spw_get_head (void);
 #endif
@@ -421,6 +422,51 @@
 				pwd->pw_name, pwd->pw_shell);
 			errors++;
 		}
+#ifdef SHADOWPWD
+		/*
+		 * Make sure this entry exists in the /etc/gshadow file.
+		 */
+
+		if (is_shadow)
+		{
+			spw = (struct spwd *) spw_locate(pwd->pw_name);
+			if (spw == NULL) {
+				printf (_("no matching password file entry in %s\n"),
+				        spw_file);
+				printf (_("add user `%s' in %s? "),
+				        pwd->pw_name, spw_file);
+				errors++;
+				if (yes_or_no())
+				{
+					struct spwd sp;
+					sp.sp_namp = pwd->pw_name;
+					sp.sp_pwdp = pwd->pw_passwd;
+					sp.sp_min = getdef_num ("PASS_MIN_DAYS", -1);
+					sp.sp_max = getdef_num ("PASS_MAX_DAYS", -1);
+					sp.sp_warn = getdef_num ("PASS_WARN_AGE", -1);
+					sp.sp_inact = -1;
+					sp.sp_expire = -1;
+					sp.sp_flag = -1;
+					sp.sp_lstchg = time ((time_t *) 0) / (24L * 3600L);
+					if (!spw_update (&sp))
+					{
+						fprintf (stderr,
+						         _("%s: can't update shadow entry for %s\n"),
+						         Prog, sp.sp_namp);
+						exit (E_CANTUPDATE);
+					}
+					/* remove password from /etc/passwd */
+					pwd->pw_passwd = SHADOW_PASSWD_STRING;/* XXX warning: const */
+					if (!pw_update (pwd)) {
+						fprintf (stderr,
+						         _("%s: can't update passwd entry for %s\n"),
+						         Prog, pwd->pw_name);
+						exit (E_CANTUPDATE);
+					}
+				}
+			}
+		}
+#endif
 	}
 
 #ifdef	SHADOWPWD
@@ -539,7 +585,8 @@
 			 * /etc/passwd entry and ask them to delete it.
 			 */
 
-			puts (_("no matching password file entry\n"));
+			printf (_("no matching password file entry in %s\n"),
+			        pwd_file);
 			printf (_("delete line `%s'? "), spe->line);
 			errors++;
 

--zhXaljGHf11kAtnf--