libteeacl: Add function to resolve name to gid_t

It's very common to specify groups by name so a helper function may be
useful.

Signed-off-by: Eero Aaltonen <eero.aaltonen@vaisala.com>
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/libteeacl/include/teeacl.h b/libteeacl/include/teeacl.h
index e4d567a..f4db914 100644
--- a/libteeacl/include/teeacl.h
+++ b/libteeacl/include/teeacl.h
@@ -39,6 +39,23 @@
 #define TEEACL_L_UUID 48
 
 /**
+ * teeacl_gid_from_name - Try to resolve gid_t for a given `group_name`.
+ *
+ * If a matching group is found, zero is returned and `gid_out` will be set to
+ * the found value.
+ * If no group is found, -ENOENT is returned.
+ * If memory allocation fails, -ENOMEM is returned.
+ * For other failures, errno is returned.
+ *
+ * @param gid_out Ptr to gid result. Will be set to group id if a matching
+ * group is found.
+ * @param group_name Name of group to resolve.
+ * @return 0 if a matching group is found, see detailed description for other
+ * cases.
+ */
+int teeacl_gid_from_name(gid_t *gid_out, const char *group_name);
+
+/**
  * teeacl_group_acl_uuid() - Encode a group login ACL string to the
  * provided uuid_buf
  *
diff --git a/libteeacl/src/group.c b/libteeacl/src/group.c
index 24a5bbd..10965dd 100644
--- a/libteeacl/src/group.c
+++ b/libteeacl/src/group.c
@@ -5,9 +5,48 @@
 
 #include <teeacl.h>
 
+#include <errno.h>
+#include <grp.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+
+static long teeacl_getgr_r_size_max(void)
+{
+	long s = sysconf(_SC_GETGR_R_SIZE_MAX);
+
+	if (s == -1)
+		return 1024;
+	return s;
+};
+
+int teeacl_gid_from_name(gid_t *gid_out, const char *group_name)
+{
+	struct group grp = { 0 };
+	char *buffer = NULL;
+	struct group *result = NULL;
+	size_t b_size = 0;
+	int rv = 0;
+
+	b_size = teeacl_getgr_r_size_max();
+	buffer = calloc(1, b_size);
+	if (!buffer)
+		return -ENOMEM;
+
+	rv = getgrnam_r(group_name, &grp, buffer, b_size, &result);
+
+	free(buffer);
+	if (!result) {
+		if (rv == 0)
+			return -ENOENT;
+		else
+			return rv;
+	} else {
+		*gid_out = grp.gr_gid;
+		return 0;
+	}
+}
 
 enum rv_groupmember teeacl_current_user_is_member_of(gid_t group)
 {