You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
6.3 KiB
218 lines
6.3 KiB
diff -r e502c48f9ba9 lib/auth_unix.c |
|
--- a/lib/auth_unix.c Thu Oct 25 08:10:12 2007 +0200 |
|
+++ b/lib/auth_unix.c Fri Nov 30 11:33:23 2007 +0100 |
|
@@ -48,12 +48,133 @@ |
|
#include <stdlib.h> |
|
#include <pwd.h> |
|
#include <grp.h> |
|
+#include <stdio.h> |
|
#include <ctype.h> |
|
#include <string.h> |
|
|
|
#include "auth.h" |
|
#include "libcyr_cfg.h" |
|
#include "xmalloc.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]; |
|
@@ -142,6 +263,25 @@ static char allowedchars[256] = { |
|
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 |
|
@@ -177,7 +317,7 @@ size_t len; |
|
*/ |
|
|
|
if (!strncmp(retbuf, "group:", 6)) { |
|
- grp = getgrnam(retbuf+6); |
|
+ grp = fgetgrnam(retbuf+6); |
|
if (!grp) return 0; |
|
strcpy(retbuf+6, grp->gr_name); |
|
return retbuf; |
|
@@ -228,6 +368,7 @@ static struct auth_state *mynewstate(con |
|
int ret, ngroups = 0; |
|
#else |
|
char **mem; |
|
+ FILE *groupfile; |
|
#endif |
|
|
|
identifier = mycanonifyid(identifier, 0); |
|
@@ -286,20 +427,23 @@ err: |
|
if (groupids) free(groupids); |
|
|
|
#else /* !HAVE_GETGROUPLIST */ |
|
- setgrent(); |
|
- while ((grp = getgrent())) { |
|
- 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(); |
|
+ 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); |
|
+ } |
|
+ } |
|
+ fclose(groupfile); |
|
+ } |
|
#endif /* HAVE_GETGROUPLIST */ |
|
|
|
return newstate;
|
|
|