+static void auth_unix_gid(FILE *f)
+{
+ /* Request are
+ * uid
+ * reply is
+ * uid expiry count list of group ids
+ */
+ uid_t uid;
+ struct passwd *pw;
+ static gid_t *groups = NULL;
+ static int groups_len = 0;
+ gid_t *more_groups;
+ int ngroups;
+ int rv, i;
+ char *cp;
+
+ if (groups_len == 0) {
+ groups = malloc(sizeof(gid_t) * INITIAL_MANAGED_GROUPS);
+ if (!groups)
+ return;
+
+ groups_len = INITIAL_MANAGED_GROUPS;
+ }
+
+ ngroups = groups_len;
+
+ if (readline(fileno(f), &lbuf, &lbuflen) != 1)
+ return;
+
+ cp = lbuf;
+ if (qword_get_uint(&cp, &uid) != 0)
+ return;
+
+ pw = getpwuid(uid);
+ if (!pw)
+ rv = -1;
+ else {
+ rv = getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
+ if (rv == -1 && ngroups >= groups_len) {
+ more_groups = realloc(groups, sizeof(gid_t)*ngroups);
+ if (!more_groups)
+ rv = -1;
+ else {
+ groups = more_groups;
+ groups_len = ngroups;
+ rv = getgrouplist(pw->pw_name, pw->pw_gid,
+ groups, &ngroups);
+ }
+ }
+ }
+ qword_printuint(f, uid);
+ qword_printuint(f, time(0) + DEFAULT_TTL);
+ if (rv >= 0) {
+ qword_printuint(f, ngroups);
+ for (i=0; i<ngroups; i++)
+ qword_printuint(f, groups[i]);
+ } else
+ qword_printuint(f, 0);
+ qword_eol(f);
+}
+
+#if USE_BLKID
+static const char *get_uuid_blkdev(char *path)
+{
+ /* We set *safe if we know that we need the
+ * fsid from statfs too.
+ */
+ static blkid_cache cache = NULL;
+ struct stat stb;
+ char *devname;
+ blkid_tag_iterate iter;
+ blkid_dev dev;
+ const char *type;
+ const char *val, *uuid = NULL;
+
+ if (cache == NULL)
+ blkid_get_cache(&cache, NULL);
+
+ if (stat(path, &stb) != 0)
+ return NULL;
+ devname = blkid_devno_to_devname(stb.st_dev);
+ if (!devname)
+ return NULL;
+ dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL);
+ free(devname);
+ if (!dev)
+ return NULL;
+ iter = blkid_tag_iterate_begin(dev);
+ if (!iter)
+ return NULL;
+ while (blkid_tag_next(iter, &type, &val) == 0) {
+ if (strcmp(type, "UUID") == 0)
+ uuid = val;
+ if (strcmp(type, "TYPE") == 0 &&
+ strcmp(val, "btrfs") == 0) {
+ uuid = NULL;
+ break;
+ }
+ }
+ blkid_tag_iterate_end(iter);
+ return uuid;
+}
+#else
+#define get_uuid_blkdev(path) (NULL)
+#endif
+
+static int get_uuid(const char *val, int uuidlen, char *u)