Improved processing of group membership

N2009_11_14_FIXES
jpandre 2008-03-13 18:36:06 +00:00
parent cc9d5c0b57
commit 5258a873f1
1 changed files with 58 additions and 37 deletions

View File

@ -1808,19 +1808,18 @@ static BOOL staticgroupmember(struct SECURITY_CONTEXT *scx, uid_t uid, gid_t gid
static BOOL groupmember(struct SECURITY_CONTEXT *scx, uid_t uid, gid_t gid)
{
static char key[] = "\nGroups:";
char buf[BUFSZ+1];
char filename[64];
enum { INKEY, INSEP, INNUM, INEND } state;
int fd;
BOOL found;
BOOL done;
char c;
int matched;
BOOL ismember;
int wanted;
int pos;
int got;
char *start;
char *p;
gid_t grp;
pid_t tid;
char buf[BUFSZ+1];
if (scx->vol->flags & (1 << SECURITY_STATICGRPS))
ismember = staticgroupmember(scx, uid, gid);
@ -1830,39 +1829,61 @@ static BOOL groupmember(struct SECURITY_CONTEXT *scx, uid_t uid, gid_t gid)
sprintf(filename,"/proc/%u/task/%u/status",tid,tid);
fd = open(filename,O_RDONLY);
if (fd >= 0) {
/* we expect a line such as "Groups: 601 603 605 607" */
wanted = BUFSZ;
pos = 0;
found = FALSE;
done = FALSE;
got = read(fd, buf, BUFSZ);
buf[got] = 0;
state = INKEY;
matched = 0;
p = buf;
grp = 0;
/*
* A simple automaton to process lines like
* Groups: 14 500 513
*/
do {
got = read(fd, &buf[pos], wanted);
buf[pos + got] = 0;
start = strstr(buf,"\nGroups:");
found = start && (strchr(++start,'\n'));
if (!found && (got == wanted)) {
wanted = pos = BUFSZ/2;
memcpy(buf, &buf[BUFSZ/2], BUFSZ/2);
} else
done = TRUE;
} while (!done);
close(fd);
/* Groups record found, check the gids */
if (found) {
p = &start[7];
done = FALSE;
do {
grp = 0;
while ((*p == ' ') || (*p == '\t')) p++;
if ((*p >= '0') && (*p <= '9')) {
while ((*p >= '0') && (*p <= '9'))
grp = grp*10 + (*p++) - '0';
ismember = (grp == gid);
c = *p++;
if (!c) {
/* refill buffer */
got = read(fd, buf, BUFSZ);
buf[got] = 0;
p = buf;
c = *p++; /* 0 at end of file */
}
switch (state) {
case INKEY :
if (key[matched] == c) {
if (!key[++matched])
state = INSEP;
} else
done = TRUE;
} while (!done && !ismember);
} else
ntfs_log_error("No group record found in %s\n",filename);
if (key[0] == c)
matched = 1;
else
matched = 0;
break;
case INSEP :
if ((c >= '0') && (c <= '9')) {
grp = c - '0';
state = INNUM;
} else
if ((c != ' ') && (c != '\t'))
state = INEND;
break;
case INNUM :
if ((c >= '0') && (c <= '9'))
grp = grp*10 + c - '0';
else {
ismember = (grp == gid);
if ((c != ' ') && (c != '\t'))
state = INEND;
else
state = INSEP;
}
default :
break;
}
} while (!ismember && c && (state != INEND));
close(fd);
if (!c)
ntfs_log_error("No group record found in %s\n",filename);
} else
ntfs_log_error("Could not open %s\n",filename);
}