File KOLAB_cyrus-imapd-2.3.18_Groups2.patch of Package cyrus-imapd.3194
diff -r 37030bf2b2bb lib/auth_unix.c
--- a/lib/auth_unix.c Fri Dec 04 10:25:24 2009 +0100
+++ b/lib/auth_unix.c Fri Dec 04 10:32:19 2009 +0100
@@ -46,6 +46,7 @@
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
+#include <stdio.h>
#include <ctype.h>
#include <string.h>
@@ -54,6 +55,126 @@
#include "xmalloc.h"
#include "util.h"
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+/*
+ * __getgrent.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+static struct group *__getgrent(int grp_fd, char *line_buff, char **members)
+{
+ short line_index;
+ short buff_size;
+ static struct group group;
+ register char *ptr;
+ char *field_begin;
+ short member_num;
+ char *endptr;
+ int line_len;
+
+ /* We use the restart label to handle malformatted lines */
+ restart:
+ line_index = 0;
+ buff_size = 256;
+
+ line_buff = realloc(line_buff, buff_size);
+ while (1) {
+ if ((line_len = read(grp_fd, line_buff + line_index,
+ buff_size - line_index)) <= 0) {
+ return NULL;
+ }
+ field_begin = strchr(line_buff, '\n');
+ if (field_begin != NULL) {
+ lseek(grp_fd,
+ (long) (1 + field_begin -
+ (line_len + line_index + line_buff)), SEEK_CUR);
+ *field_begin = '\0';
+ if (*line_buff == '#' || *line_buff == ' '
+ || *line_buff == '\n' || *line_buff == '\t')
+ goto restart;
+ break;
+ } else {
+ /* Allocate some more space */
+ line_index = buff_size;
+ buff_size += 256;
+ line_buff = realloc(line_buff, buff_size);
+ }
+ }
+
+ /* Now parse the line */
+ group.gr_name = line_buff;
+ ptr = strchr(line_buff, ':');
+ if (ptr == NULL)
+ goto restart;
+ *ptr++ = '\0';
+
+ group.gr_passwd = ptr;
+ ptr = strchr(ptr, ':');
+ if (ptr == NULL)
+ goto restart;
+ *ptr++ = '\0';
+
+ field_begin = ptr;
+ ptr = strchr(ptr, ':');
+ if (ptr == NULL)
+ goto restart;
+ *ptr++ = '\0';
+
+ group.gr_gid = (gid_t) strtoul(field_begin, &endptr, 10);
+ if (*endptr != '\0')
+ goto restart;
+
+ member_num = 0;
+ field_begin = ptr;
+
+ if (members != NULL)
+ free(members);
+ members = (char **) malloc((member_num + 1) * sizeof(char *));
+ for ( ; field_begin && *field_begin != '\0'; field_begin = ptr) {
+ if ((ptr = strchr(field_begin, ',')) != NULL)
+ *ptr++ = '\0';
+ members[member_num++] = field_begin;
+ members = (char **) realloc(members,
+ (member_num + 1) * sizeof(char *));
+ }
+ members[member_num] = NULL;
+
+ group.gr_mem = members;
+ return &group;
+}
+
+static char *line_buff = NULL;
+static char **members = NULL;
+
+struct group *fgetgrent(FILE *file)
+{
+ if (file == NULL) {
+ errno = EINTR;
+ return NULL;
+ }
+ return __getgrent(fileno(file), line_buff, members);
+}
+#endif /* __FreeBSD__ */
+
struct auth_state {
char userid[81];
char **group;
@@ -141,6 +262,25 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
+static struct group* fgetgrnam(const char* name)
+{
+ struct group *grp;
+ FILE *groupfile;
+
+ groupfile = fopen("/etc/imapd.group", "r");
+ if (!groupfile) groupfile = fopen("/etc/group", "r");
+ if (groupfile) {
+ while ((grp = fgetgrent(groupfile))) {
+ if (strcmp(grp->gr_name, name) == 0) {
+ fclose(groupfile);
+ return grp;
+ }
+ }
+ }
+ if (groupfile) fclose(groupfile);
+ return NULL;
+}
+
/*
* Convert 'identifier' into canonical form.
* Returns a pointer to a static buffer containing the canonical form
@@ -176,7 +316,7 @@
*/
if (!strncmp(retbuf, "group:", 6)) {
- grp = getgrnam(retbuf+6);
+ grp = fgetgrnam(retbuf+6);
if (!grp) return NULL;
if (strlen(grp->gr_name) >= sizeof(retbuf)-6)
return NULL;
@@ -224,11 +364,12 @@
struct auth_state *newstate;
struct passwd *pwd;
struct group *grp;
-#if defined(HAVE_GETGROUPLIST) && defined(__GLIBC__)
+#if 0 && defined(HAVE_GETGROUPLIST) && defined(__GLIBC__)
gid_t gid, *groupids = NULL;
int ret, ngroups = 10;
#else
char **mem;
+ FILE *groupfile;
#endif
identifier = mycanonifyid(identifier, 0);
@@ -246,7 +387,7 @@
pwd = getpwnam(identifier);
-#if defined(HAVE_GETGROUPLIST) && defined(__GLIBC__)
+#if 0 && defined(HAVE_GETGROUPLIST) && defined(__GLIBC__)
gid = pwd ? pwd->pw_gid : (gid_t) -1;
/* get the group ids */
@@ -284,20 +425,23 @@
if (groupids) free(groupids);
#else /* !HAVE_GETGROUPLIST */
- setgrent();
- while ((grp = getgrent())) {
- for (mem = grp->gr_mem; *mem; mem++) {
- if (!strcmp(*mem, identifier)) break;
- }
+ groupfile = fopen("/etc/imapd.group", "r");
+ if (!groupfile) groupfile = fopen("/etc/group", "r");
+ if (groupfile) {
+ while ((grp = fgetgrent(groupfile))) {
+ for (mem = grp->gr_mem; *mem; mem++) {
+ if (!strcmp(*mem, identifier)) break;
+ }
- if (*mem || (pwd && pwd->pw_gid == grp->gr_gid)) {
- newstate->ngroups++;
- newstate->group = (char **)xrealloc((char *)newstate->group,
- newstate->ngroups * sizeof(char *));
- newstate->group[newstate->ngroups-1] = xstrdup(grp->gr_name);
- }
- }
- endgrent();
+ if (*mem || (pwd && pwd->pw_gid == grp->gr_gid)) {
+ newstate->ngroups++;
+ newstate->group = (char **)xrealloc((char *)newstate->group,
+ newstate->ngroups * sizeof(char *));
+ newstate->group[newstate->ngroups-1] = xstrdup(grp->gr_name);
+ }
+ }
+ fclose(groupfile);
+ }
#endif /* HAVE_GETGROUPLIST */
return newstate;