Import the upstream lens for the shadow file, just with a different
identifier and not matching /etc/shadow by default. Instead, apply a
transformation to have it match /etc/shadow only if the version of
augeas is at least 1.2.1 [1].
[1] While the last upstream version is 1.2.0, all the development seems
to happen in master, so whatever the next version is going to be
numbered (e.g. 1.2.1 or 1.3.0), the check will be fine anyway.
---
appliance/Makefile.am | 3 +-
appliance/guestfs_shadow.aug | 72 ++++++++++++++++++++++++++++++++++++++++++++
daemon/augeas.c | 21 ++++++++++++-
3 files changed, 94 insertions(+), 2 deletions(-)
create mode 100644 appliance/guestfs_shadow.aug
diff --git a/appliance/Makefile.am b/appliance/Makefile.am
index bb0c0e8..b8377af 100644
--- a/appliance/Makefile.am
+++ b/appliance/Makefile.am
@@ -75,13 +75,14 @@ packagelist: packagelist.in Makefile
cmp -s $@ $@-t || mv $@-t $@
rm -f $@-t
-supermin.d/daemon.tar.gz: ../daemon/guestfsd guestfsd.suppressions guestfs_lvm_conf.aug
+supermin.d/daemon.tar.gz: ../daemon/guestfsd guestfsd.suppressions guestfs_lvm_conf.aug
guestfs_shadow.aug
rm -f $@ $@-t
rm -rf tmp-d
mkdir -p tmp-d$(DAEMON_SUPERMIN_DIR) tmp-d/etc tmp-d/usr/share/guestfs
ln ../daemon/guestfsd tmp-d$(DAEMON_SUPERMIN_DIR)/guestfsd
ln $(srcdir)/guestfsd.suppressions tmp-d/etc/guestfsd.suppressions
ln $(srcdir)/guestfs_lvm_conf.aug tmp-d/usr/share/guestfs/guestfs_lvm_conf.aug
+ ln $(srcdir)/guestfs_shadow.aug tmp-d/usr/share/guestfs/guestfs_shadow.aug
( cd tmp-d && tar zcf - * ) > $@-t
rm -r tmp-d
mv $@-t $@
diff --git a/appliance/guestfs_shadow.aug b/appliance/guestfs_shadow.aug
new file mode 100644
index 0000000..2fbf455
--- /dev/null
+++ b/appliance/guestfs_shadow.aug
@@ -0,0 +1,72 @@
+(*
+ Module: Shadow
+ Parses /etc/shadow
+
+ Author: Lorenzo M. Catucci <catucci(a)ccd.uniroma2.it>
+
+ Original Author: Free Ekanayaka <free(a)64studio.com>
+
+ About: Reference
+
+ - man 5 shadow
+ - man 3 getspnam
+
+ About: License
+ This file is licensed under the LGPL v2+, like the rest of Augeas.
+
+ About:
+
+ Each line in the shadow files represents the additional shadow-defined attributes
+ for the corresponding user, as defined in the passwd file.
+
+*)
+
+module Guestfs_Shadow =
+
+ autoload xfm
+
+(************************************************************************
+ * USEFUL PRIMITIVES
+ *************************************************************************)
+
+let eol = Util.eol
+let comment = Util.comment
+let empty = Util.empty
+let dels = Util.del_str
+
+let colon = Sep.colon
+
+let word = Rx.word
+let integer = Rx.integer
+
+let sto_to_col = Passwd.sto_to_col
+let sto_to_eol = Passwd.sto_to_eol
+
+(************************************************************************
+ * Group: ENTRIES
+ *************************************************************************)
+
+(* View: entry *)
+let entry = [ key word
+ . colon
+ . [ label "password" . sto_to_col? . colon ]
+ . [ label "lastchange_date" . store integer? . colon ]
+ . [ label "minage_days" . store integer? . colon ]
+ . [ label "maxage_days" . store integer? . colon ]
+ . [ label "warn_days" . store integer? . colon ]
+ . [ label "inactive_days" . store integer? . colon ]
+ . [ label "expire_date" . store integer? . colon ]
+ . [ label "flag" . store integer? ]
+ . eol ]
+
+(************************************************************************
+ * LENS
+ *************************************************************************)
+
+let lns = (comment|empty|entry) *
+
+let filter
+ = incl "/shadow"
+ . Util.stdexcl
+
+let xfm = transform lns filter
diff --git a/daemon/augeas.c b/daemon/augeas.c
index 8dc6a7c..988deed 100644
--- a/daemon/augeas.c
+++ b/daemon/augeas.c
@@ -189,7 +189,7 @@ do_aug_init (const char *root, int flags)
}
/* Pass AUG_NO_ERR_CLOSE so we can display detailed errors. */
- aug = aug_init (buf, NULL, flags | AUG_NO_ERR_CLOSE);
+ aug = aug_init (buf, "/usr/share/guestfs/", flags | AUG_NO_ERR_CLOSE);
if (!aug) {
reply_with_error ("augeas initialization failed");
@@ -203,6 +203,25 @@ do_aug_init (const char *root, int flags)
return -1;
}
+ if (!augeas_is_version (1, 2, 1)) {
+ int r = aug_transform (aug, "guestfs_shadow", "/etc/shadow",
+ 0 /* = included */);
+ if (r == -1) {
+ AUGEAS_ERROR ("aug_transform");
+ aug_close (aug);
+ aug = NULL;
+ return -1;
+ }
+
+ /* If aug_load was implicitly called, reload the handle. */
+ if ((flags & AUG_NO_LOAD) == 0) {
+ if (aug_load (aug) == -1) {
+ AUGEAS_ERROR ("aug_load");
+ return -1;
+ }
+ }
+ }
+
return 0;
}
--
1.9.3