summaryrefslogtreecommitdiffstats
path: root/lib/libc/gen/getgrent.c
diff options
context:
space:
mode:
authorwosch <wosch@FreeBSD.org>1996-12-25 21:51:24 +0000
committerwosch <wosch@FreeBSD.org>1996-12-25 21:51:24 +0000
commit8925ccaa67f7bd6bc72e8d9c4b4b8c56803f3127 (patch)
tree0e190e126bb5cc2a88d9d9b2ab41305076bcb5f1 /lib/libc/gen/getgrent.c
parent78f7aad1145b4e3fec496a19efd91ee71e0f376e (diff)
downloadFreeBSD-src-8925ccaa67f7bd6bc72e8d9c4b4b8c56803f3127.zip
FreeBSD-src-8925ccaa67f7bd6bc72e8d9c4b4b8c56803f3127.tar.gz
Use dynamic allocated buffers instead static buffers. No member or
line length limit anymore - now 500 members or 5000 members are possible. For security group lines longer than 256K will be count as an error. 256K should be enough for 65536 users. Support comments (lines that begin with a #) if compiled with option -DGROUP_IGNORE_COMMENTS. Fortunately it seems that all system utilities which use getgrent() functions are dynamically linked executables. So you need only rebuild libc.so.3.0 if you want this change. Note: if you have an old X server which depend on libc.so.2.* you should rebuild libc.so.2.* too. Not a 2.2 candidate.
Diffstat (limited to 'lib/libc/gen/getgrent.c')
-rw-r--r--lib/libc/gen/getgrent.c110
1 files changed, 91 insertions, 19 deletions
diff --git a/lib/libc/gen/getgrent.c b/lib/libc/gen/getgrent.c
index b4829fe..e2cefb9 100644
--- a/lib/libc/gen/getgrent.c
+++ b/lib/libc/gen/getgrent.c
@@ -55,10 +55,22 @@ static int _getypgroup(struct group *, const char *, char *);
static int _nextypgroup(struct group *);
#endif
-#define MAXGRP 200
-static char *members[MAXGRP];
-#define MAXLINELENGTH 1024
-static char line[MAXLINELENGTH];
+/* initial size for malloc and increase steps for realloc */
+#define MAXGRP 64
+#define MAXLINELENGTH 256
+
+static char **members; /* list of group members */
+static int maxgrp; /* current length of **mebers */
+static char *line; /* temp buffer for group line */
+static int maxlinelength; /* current length of *line */
+
+/*
+ * Lines longer than MAXLINELENGTHLIMIT will be count as an error.
+ * <= 0 disable check for maximum line length
+ * 256K is enough for 64,000 uids
+ */
+#define MAXLINELENGTHLIMIT (256 * 1024)
+
struct group *
getgrent()
@@ -176,6 +188,21 @@ start_gr()
rewind(_gr_fp);
}
#endif
+
+ if (maxlinelength == 0) {
+ if ((line = (char *)malloc(sizeof(char) *
+ MAXLINELENGTH)) == NULL)
+ return(0);
+ maxlinelength += MAXLINELENGTH;
+ }
+
+ if (maxgrp == 0) {
+ if ((members = (char **)malloc(sizeof(char **) *
+ MAXGRP)) == NULL)
+ return(0);
+ maxgrp += MAXGRP;
+ }
+
return 1;
}
@@ -217,24 +244,55 @@ grscan(search, gid, name)
{
register char *cp, **m;
char *bp;
+
+
#ifdef YP
int _ypfound;
-#endif;
+#endif
for (;;) {
#ifdef YP
_ypfound = 0;
#endif
- if (!fgets(line, sizeof(line), _gr_fp))
+ if (fgets(line, maxlinelength, _gr_fp) == NULL)
return(0);
- bp = line;
- /* skip lines that are too big */
+
if (!index(line, '\n')) {
- int ch;
+ do {
+ if (feof(_gr_fp))
+ return(0);
+
+ /* don't allocate infinite memory */
+ if (MAXLINELENGTHLIMIT > 0 &&
+ maxlinelength >= MAXLINELENGTHLIMIT)
+ return(0);
- while ((ch = getc(_gr_fp)) != '\n' && ch != EOF)
- ;
- continue;
+ if ((line = (char *)realloc(line,
+ sizeof(char) *
+ (maxlinelength + MAXLINELENGTH))) == NULL)
+ return(0);
+
+ if (fgets(line + maxlinelength - 1,
+ MAXLINELENGTH + 1, _gr_fp) == NULL)
+ return(0);
+
+ maxlinelength += MAXLINELENGTH;
+ } while (!index(line + maxlinelength -
+ MAXLINELENGTH - 1, '\n'));
}
+
+#ifdef GROUP_IGNORE_COMMENTS
+ /*
+ * Ignore comments: ^[ \t]*#
+ */
+ for (cp = line; *cp != '\0'; cp++)
+ if (*cp != ' ' && *cp != '\t')
+ break;
+ if (*cp == '#')
+ continue;
+#endif
+
+ bp = line;
+
if ((_gr_group.gr_name = strsep(&bp, ":\n")) == NULL)
break;
#ifdef YP
@@ -320,9 +378,16 @@ grscan(search, gid, name)
bp = cp;
cp = NULL;
#endif
- for (m = _gr_group.gr_mem = members;; bp++) {
- if (m == &members[MAXGRP - 1])
- break;
+ for (m = members; ; bp++) {
+ if (m == (members + maxgrp - 1)) {
+ if ((members = (char **)
+ realloc(members,
+ sizeof(char **) *
+ (maxgrp + MAXGRP))) == NULL)
+ return(0);
+ m = members + maxgrp - 1;
+ maxgrp += MAXGRP;
+ }
if (*bp == ',') {
if (cp) {
*bp = '\0';
@@ -333,11 +398,13 @@ grscan(search, gid, name)
if (cp) {
*bp = '\0';
*m++ = cp;
- }
+ }
break;
} else if (cp == NULL)
cp = bp;
+
}
+ _gr_group.gr_mem = members;
*m = NULL;
return(1);
}
@@ -370,9 +437,13 @@ _gr_breakout_yp(struct group *gr, char *result)
if ((s = result) == NULL) return 0;
cp = 0;
- for (m = _gr_group.gr_mem = members; /**/; s++) {
- if (m == &members[MAXGRP - 1]) {
- break;
+ for (m = members; ; s++) {
+ if (m == members + maxgrp - 1) {
+ if ((members = (char **)realloc(members,
+ sizeof(char **) * (maxgrp + MAXGRP))) == NULL)
+ return(0);
+ m = members + maxgrp - 1;
+ maxgrp += MAXGRP;
}
if (*s == ',') {
if (cp) {
@@ -390,6 +461,7 @@ _gr_breakout_yp(struct group *gr, char *result)
cp = s;
}
}
+ _gr_group.gr_mem = members;
*m = NULL;
return 1;
OpenPOWER on IntegriCloud