|
rpm-build |
0a0c83 |
/*
|
|
rpm-build |
0a0c83 |
File: parse.c
|
|
rpm-build |
0a0c83 |
(Linux Access Control List Management)
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
Copyright (C) 1999, 2000
|
|
rpm-build |
0a0c83 |
Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
This program is free software; you can redistribute it and/or
|
|
rpm-build |
0a0c83 |
modify it under the terms of the GNU Lesser General Public
|
|
rpm-build |
0a0c83 |
License as published by the Free Software Foundation; either
|
|
rpm-build |
0a0c83 |
version 2.1 of the License, or (at your option) any later version.
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
This program is distributed in the hope that it will be useful,
|
|
rpm-build |
0a0c83 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
0a0c83 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
rpm-build |
0a0c83 |
Lesser General Public License for more details.
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
You should have received a copy of the GNU Lesser General Public
|
|
rpm-build |
0a0c83 |
License along with this library; if not, write to the Free Software
|
|
rpm-build |
0a0c83 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
rpm-build |
0a0c83 |
*/
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#include "config.h"
|
|
rpm-build |
0a0c83 |
#include <stdio.h>
|
|
rpm-build |
0a0c83 |
#include <stdlib.h>
|
|
rpm-build |
0a0c83 |
#include <string.h>
|
|
rpm-build |
0a0c83 |
#include <errno.h>
|
|
rpm-build |
0a0c83 |
#include <limits.h>
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#include <sys/types.h>
|
|
rpm-build |
0a0c83 |
#include <sys/stat.h>
|
|
rpm-build |
0a0c83 |
#include <pwd.h>
|
|
rpm-build |
0a0c83 |
#include <grp.h>
|
|
rpm-build |
0a0c83 |
#include "sys/acl.h"
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#include "sequence.h"
|
|
rpm-build |
0a0c83 |
#include "parse.h"
|
|
rpm-build |
0a0c83 |
#include "misc.h"
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#define SKIP_WS(x) ({ \
|
|
rpm-build |
0a0c83 |
while (*(x)==' ' || *(x)=='\t' || *(x)=='\n' || *(x)=='\r') \
|
|
rpm-build |
0a0c83 |
(x)++; \
|
|
rpm-build |
0a0c83 |
})
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static int
|
|
rpm-build |
0a0c83 |
skip_tag_name(
|
|
rpm-build |
0a0c83 |
const char **text_p,
|
|
rpm-build |
0a0c83 |
const char *token)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
size_t len = strlen(token);
|
|
rpm-build |
0a0c83 |
const char *text = *text_p;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
SKIP_WS(text);
|
|
rpm-build |
0a0c83 |
if (strncmp(text, token, len) == 0) {
|
|
rpm-build |
0a0c83 |
text += len;
|
|
rpm-build |
0a0c83 |
goto delimiter;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (*text == *token) {
|
|
rpm-build |
0a0c83 |
text++;
|
|
rpm-build |
0a0c83 |
goto delimiter;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
delimiter:
|
|
rpm-build |
0a0c83 |
SKIP_WS(text);
|
|
rpm-build |
0a0c83 |
if (*text == ':') {
|
|
rpm-build |
0a0c83 |
*text_p = text+1;
|
|
rpm-build |
0a0c83 |
return 1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (*text == ',' || *text == '\0') {
|
|
rpm-build |
0a0c83 |
*text_p = text;
|
|
rpm-build |
0a0c83 |
return 1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static char *
|
|
rpm-build |
0a0c83 |
get_token(
|
|
rpm-build |
0a0c83 |
const char **text_p)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
char *token = NULL, *t;
|
|
rpm-build |
0a0c83 |
const char *bp, *ep;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
bp = *text_p;
|
|
rpm-build |
0a0c83 |
SKIP_WS(bp);
|
|
rpm-build |
0a0c83 |
ep = bp;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
while (*ep!='\0' && *ep!='\r' && *ep!='\n' && *ep!=':' && *ep!=',')
|
|
rpm-build |
0a0c83 |
ep++;
|
|
rpm-build |
0a0c83 |
if (ep == bp)
|
|
rpm-build |
0a0c83 |
goto after_token;
|
|
rpm-build |
0a0c83 |
token = (char*)malloc(ep - bp + 1);
|
|
rpm-build |
0a0c83 |
if (token == NULL)
|
|
rpm-build |
0a0c83 |
goto after_token;
|
|
rpm-build |
0a0c83 |
memcpy(token, bp, ep - bp);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/* Trim trailing whitespace */
|
|
rpm-build |
0a0c83 |
t = token + (ep - bp - 1);
|
|
rpm-build |
0a0c83 |
while (t >= token &&
|
|
rpm-build |
0a0c83 |
(*t==' ' || *t=='\t' || *t=='\n' || *t=='\r'))
|
|
rpm-build |
0a0c83 |
t--;
|
|
rpm-build |
0a0c83 |
*(t+1) = '\0';
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
after_token:
|
|
rpm-build |
0a0c83 |
if (*ep == ':')
|
|
rpm-build |
0a0c83 |
ep++;
|
|
rpm-build |
0a0c83 |
*text_p = ep;
|
|
rpm-build |
0a0c83 |
return token;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static int
|
|
rpm-build |
0a0c83 |
get_id(
|
|
rpm-build |
0a0c83 |
const char *token,
|
|
rpm-build |
0a0c83 |
id_t *id_p)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
char *ep;
|
|
rpm-build |
0a0c83 |
long l;
|
|
rpm-build |
0a0c83 |
l = strtol(token, &ep, 0);
|
|
rpm-build |
0a0c83 |
if (*ep != '\0')
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
if (l < 0) {
|
|
rpm-build |
0a0c83 |
/*
|
|
rpm-build |
0a0c83 |
Negative values are interpreted as 16-bit numbers,
|
|
rpm-build |
0a0c83 |
so that id -2 maps to 65534 (nobody/nogroup), etc.
|
|
rpm-build |
0a0c83 |
*/
|
|
rpm-build |
0a0c83 |
l &= 0xFFFF;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
*id_p = l;
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static int
|
|
rpm-build |
0a0c83 |
get_uid(
|
|
rpm-build |
0a0c83 |
const char *token,
|
|
rpm-build |
0a0c83 |
uid_t *uid_p)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
struct passwd *passwd;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (get_id(token, (id_t *)uid_p) == 0)
|
|
rpm-build |
0a0c83 |
goto accept;
|
|
rpm-build |
0a0c83 |
passwd = getpwnam(token);
|
|
rpm-build |
0a0c83 |
if (passwd) {
|
|
rpm-build |
0a0c83 |
*uid_p = passwd->pw_uid;
|
|
rpm-build |
0a0c83 |
goto accept;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
accept:
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static int
|
|
rpm-build |
0a0c83 |
get_gid(
|
|
rpm-build |
0a0c83 |
const char *token,
|
|
rpm-build |
0a0c83 |
gid_t *gid_p)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
struct group *group;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (get_id(token, (id_t *)gid_p) == 0)
|
|
rpm-build |
0a0c83 |
goto accept;
|
|
rpm-build |
0a0c83 |
group = getgrnam(token);
|
|
rpm-build |
0a0c83 |
if (group) {
|
|
rpm-build |
0a0c83 |
*gid_p = group->gr_gid;
|
|
rpm-build |
0a0c83 |
goto accept;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
accept:
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/*
|
|
rpm-build |
0a0c83 |
Parses the next acl entry in text_p.
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
Returns:
|
|
rpm-build |
0a0c83 |
-1 on error, 0 on success.
|
|
rpm-build |
0a0c83 |
*/
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
cmd_t
|
|
rpm-build |
0a0c83 |
parse_acl_cmd(
|
|
rpm-build |
0a0c83 |
const char **text_p,
|
|
rpm-build |
0a0c83 |
int seq_cmd,
|
|
rpm-build |
0a0c83 |
int parse_mode)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
cmd_t cmd = cmd_init();
|
|
rpm-build |
0a0c83 |
char *str;
|
|
rpm-build |
0a0c83 |
const char *backup;
|
|
rpm-build |
0a0c83 |
int error, perm_chars;
|
|
rpm-build |
0a0c83 |
if (!cmd)
|
|
rpm-build |
0a0c83 |
return NULL;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
cmd->c_cmd = seq_cmd;
|
|
rpm-build |
0a0c83 |
if (parse_mode & SEQ_PROMOTE_ACL)
|
|
rpm-build |
0a0c83 |
cmd->c_type = ACL_TYPE_DEFAULT;
|
|
rpm-build |
0a0c83 |
else
|
|
rpm-build |
0a0c83 |
cmd->c_type = ACL_TYPE_ACCESS;
|
|
rpm-build |
0a0c83 |
cmd->c_id = ACL_UNDEFINED_ID;
|
|
rpm-build |
0a0c83 |
cmd->c_perm = 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (parse_mode & SEQ_PARSE_DEFAULT) {
|
|
rpm-build |
0a0c83 |
/* check for default acl entry */
|
|
rpm-build |
0a0c83 |
backup = *text_p;
|
|
rpm-build |
0a0c83 |
if (skip_tag_name(text_p, "default")) {
|
|
rpm-build |
0a0c83 |
if (parse_mode & SEQ_PROMOTE_ACL) {
|
|
rpm-build |
0a0c83 |
/* if promoting from acl to default acl and
|
|
rpm-build |
0a0c83 |
a default acl entry is found, fail. */
|
|
rpm-build |
0a0c83 |
*text_p = backup;
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
cmd->c_type = ACL_TYPE_DEFAULT;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/* parse acl entry type */
|
|
rpm-build |
0a0c83 |
switch (**text_p) {
|
|
rpm-build |
0a0c83 |
case 'u': /* user */
|
|
rpm-build |
0a0c83 |
skip_tag_name(text_p, "user");
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
user_entry:
|
|
rpm-build |
0a0c83 |
backup = *text_p;
|
|
rpm-build |
0a0c83 |
str = get_token(text_p);
|
|
rpm-build |
0a0c83 |
if (str) {
|
|
rpm-build |
0a0c83 |
cmd->c_tag = ACL_USER;
|
|
rpm-build |
0a0c83 |
error = get_uid(__acl_unquote(str), &cmd->c_id);
|
|
rpm-build |
0a0c83 |
free(str);
|
|
rpm-build |
0a0c83 |
if (error) {
|
|
rpm-build |
0a0c83 |
*text_p = backup;
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
cmd->c_tag = ACL_USER_OBJ;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'g': /* group */
|
|
rpm-build |
0a0c83 |
if (!skip_tag_name(text_p, "group"))
|
|
rpm-build |
0a0c83 |
goto user_entry;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
backup = *text_p;
|
|
rpm-build |
0a0c83 |
str = get_token(text_p);
|
|
rpm-build |
0a0c83 |
if (str) {
|
|
rpm-build |
0a0c83 |
cmd->c_tag = ACL_GROUP;
|
|
rpm-build |
0a0c83 |
error = get_gid(__acl_unquote(str), &cmd->c_id);
|
|
rpm-build |
0a0c83 |
free(str);
|
|
rpm-build |
0a0c83 |
if (error) {
|
|
rpm-build |
0a0c83 |
*text_p = backup;
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
cmd->c_tag = ACL_GROUP_OBJ;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'o': /* other */
|
|
rpm-build |
0a0c83 |
if (!skip_tag_name(text_p, "other"))
|
|
rpm-build |
0a0c83 |
goto user_entry;
|
|
rpm-build |
0a0c83 |
/* skip empty entry qualifier field (this field may
|
|
rpm-build |
0a0c83 |
be missing for compatibility with Solaris.) */
|
|
rpm-build |
0a0c83 |
SKIP_WS(*text_p);
|
|
rpm-build |
0a0c83 |
if (**text_p == ':')
|
|
rpm-build |
0a0c83 |
(*text_p)++;
|
|
rpm-build |
0a0c83 |
cmd->c_tag = ACL_OTHER;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'm': /* mask */
|
|
rpm-build |
0a0c83 |
if (!skip_tag_name(text_p, "mask"))
|
|
rpm-build |
0a0c83 |
goto user_entry;
|
|
rpm-build |
0a0c83 |
/* skip empty entry qualifier field (this field may
|
|
rpm-build |
0a0c83 |
be missing for compatibility with Solaris.) */
|
|
rpm-build |
0a0c83 |
SKIP_WS(*text_p);
|
|
rpm-build |
0a0c83 |
if (**text_p == ':')
|
|
rpm-build |
0a0c83 |
(*text_p)++;
|
|
rpm-build |
0a0c83 |
cmd->c_tag = ACL_MASK;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
default: /* assume "user:" */
|
|
rpm-build |
0a0c83 |
goto user_entry;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
SKIP_WS(*text_p);
|
|
rpm-build |
0a0c83 |
if (**text_p == ',' || **text_p == '\0') {
|
|
rpm-build |
0a0c83 |
if (parse_mode & SEQ_PARSE_NO_PERM)
|
|
rpm-build |
0a0c83 |
return cmd;
|
|
rpm-build |
0a0c83 |
else
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (!(parse_mode & SEQ_PARSE_WITH_PERM))
|
|
rpm-build |
0a0c83 |
return cmd;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/* parse permissions */
|
|
rpm-build |
0a0c83 |
SKIP_WS(*text_p);
|
|
rpm-build |
0a0c83 |
if (**text_p >= '0' && **text_p <= '7') {
|
|
rpm-build |
0a0c83 |
cmd->c_perm = 0;
|
|
rpm-build |
0a0c83 |
while (**text_p == '0')
|
|
rpm-build |
0a0c83 |
(*text_p)++;
|
|
rpm-build |
0a0c83 |
if (**text_p >= '1' && **text_p <= '7') {
|
|
rpm-build |
0a0c83 |
cmd->c_perm = (*(*text_p)++ - '0');
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
return cmd;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
for (perm_chars=0;; perm_chars++, (*text_p)++) {
|
|
rpm-build |
0a0c83 |
switch(**text_p) {
|
|
rpm-build |
0a0c83 |
case 'r': /* read */
|
|
rpm-build |
0a0c83 |
if (cmd->c_perm & CMD_PERM_READ)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
cmd->c_perm |= CMD_PERM_READ;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'w': /* write */
|
|
rpm-build |
0a0c83 |
if (cmd->c_perm & CMD_PERM_WRITE)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
cmd->c_perm |= CMD_PERM_WRITE;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'x': /* execute */
|
|
rpm-build |
0a0c83 |
if (cmd->c_perm & CMD_PERM_EXECUTE)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
cmd->c_perm |= CMD_PERM_EXECUTE;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'X': /* execute only if directory or some
|
|
rpm-build |
0a0c83 |
entries already have execute permissions
|
|
rpm-build |
0a0c83 |
set */
|
|
rpm-build |
0a0c83 |
if (cmd->c_perm & CMD_PERM_COND_EXECUTE)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
cmd->c_perm |= CMD_PERM_COND_EXECUTE;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case '-':
|
|
rpm-build |
0a0c83 |
/* ignore */
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
default:
|
|
rpm-build |
0a0c83 |
if (perm_chars == 0)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
return cmd;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return cmd;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
fail:
|
|
rpm-build |
0a0c83 |
cmd_free(cmd);
|
|
rpm-build |
0a0c83 |
return NULL;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/*
|
|
rpm-build |
0a0c83 |
Parse a comma-separated list of acl entries.
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
which is set to the index of the first character that was not parsed,
|
|
rpm-build |
0a0c83 |
or -1 in case of success.
|
|
rpm-build |
0a0c83 |
*/
|
|
rpm-build |
0a0c83 |
int
|
|
rpm-build |
0a0c83 |
parse_acl_seq(
|
|
rpm-build |
0a0c83 |
seq_t seq,
|
|
rpm-build |
0a0c83 |
const char *text_p,
|
|
rpm-build |
0a0c83 |
int *which,
|
|
rpm-build |
0a0c83 |
int seq_cmd,
|
|
rpm-build |
0a0c83 |
int parse_mode)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
const char *initial_text_p = text_p;
|
|
rpm-build |
0a0c83 |
cmd_t cmd;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (which)
|
|
rpm-build |
0a0c83 |
*which = -1;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
while (*text_p != '\0') {
|
|
rpm-build |
0a0c83 |
cmd = parse_acl_cmd(&text_p, seq_cmd, parse_mode);
|
|
rpm-build |
0a0c83 |
if (cmd == NULL) {
|
|
rpm-build |
0a0c83 |
errno = EINVAL;
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (seq_append(seq, cmd) != 0) {
|
|
rpm-build |
0a0c83 |
cmd_free(cmd);
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
SKIP_WS(text_p);
|
|
rpm-build |
0a0c83 |
if (*text_p != ',')
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
text_p++;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (*text_p != '\0') {
|
|
rpm-build |
0a0c83 |
errno = EINVAL;
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
fail:
|
|
rpm-build |
0a0c83 |
if (which)
|
|
rpm-build |
0a0c83 |
*which = (text_p - initial_text_p);
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
int
|
|
rpm-build |
0a0c83 |
read_acl_comments(
|
|
rpm-build |
0a0c83 |
FILE *file,
|
|
rpm-build |
0a0c83 |
int *lineno,
|
|
rpm-build |
0a0c83 |
char **path_p,
|
|
rpm-build |
0a0c83 |
uid_t *uid_p,
|
|
rpm-build |
0a0c83 |
gid_t *gid_p,
|
|
rpm-build |
0a0c83 |
mode_t *flags)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
int c;
|
|
rpm-build |
0a0c83 |
/*
|
|
rpm-build |
0a0c83 |
Max PATH_MAX bytes even for UTF-8 path names and additional 9
|
|
rpm-build |
0a0c83 |
bytes for "# file: ". Not a good solution but for now it is the
|
|
rpm-build |
0a0c83 |
best I can do without too much impact on the code. [tw]
|
|
rpm-build |
0a0c83 |
*/
|
|
rpm-build |
0a0c83 |
char *line, *cp, *p;
|
|
rpm-build |
0a0c83 |
int comments_read = 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (path_p)
|
|
rpm-build |
0a0c83 |
*path_p = NULL;
|
|
rpm-build |
0a0c83 |
if (uid_p)
|
|
rpm-build |
0a0c83 |
*uid_p = ACL_UNDEFINED_ID;
|
|
rpm-build |
0a0c83 |
if (gid_p)
|
|
rpm-build |
0a0c83 |
*gid_p = ACL_UNDEFINED_ID;
|
|
rpm-build |
0a0c83 |
if (flags)
|
|
rpm-build |
0a0c83 |
*flags = 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
for(;;) {
|
|
rpm-build |
0a0c83 |
c = fgetc(file);
|
|
rpm-build |
0a0c83 |
if (c == EOF)
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
if (c==' ' || c=='\t' || c=='\r' || c=='\n') {
|
|
rpm-build |
0a0c83 |
if (c=='\n')
|
|
rpm-build |
0a0c83 |
(*lineno)++;
|
|
rpm-build |
0a0c83 |
continue;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (c != '#') {
|
|
rpm-build |
0a0c83 |
ungetc(c, file);
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (lineno)
|
|
rpm-build |
0a0c83 |
(*lineno)++;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
line = __acl_next_line(file);
|
|
rpm-build |
0a0c83 |
if (line == NULL)
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
comments_read = 1;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
p = strrchr(line, '\0');
|
|
rpm-build |
0a0c83 |
while (p > line &&
|
|
rpm-build |
0a0c83 |
(*(p-1)=='\r' || *(p-1)=='\n')) {
|
|
rpm-build |
0a0c83 |
p--;
|
|
rpm-build |
0a0c83 |
*p = '\0';
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
cp = line;
|
|
rpm-build |
0a0c83 |
SKIP_WS(cp);
|
|
rpm-build |
0a0c83 |
if (strncmp(cp, "file:", 5) == 0) {
|
|
rpm-build |
0a0c83 |
cp += 5;
|
|
rpm-build |
0a0c83 |
SKIP_WS(cp);
|
|
rpm-build |
0a0c83 |
cp = __acl_unquote(cp);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (path_p) {
|
|
rpm-build |
0a0c83 |
if (*path_p)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
*path_p = (char*)malloc(strlen(cp)+1);
|
|
rpm-build |
0a0c83 |
if (!*path_p)
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
strcpy(*path_p, cp);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
} else if (strncmp(cp, "owner:", 6) == 0) {
|
|
rpm-build |
0a0c83 |
cp += 6;
|
|
rpm-build |
0a0c83 |
SKIP_WS(cp);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (uid_p) {
|
|
rpm-build |
0a0c83 |
if (*uid_p != ACL_UNDEFINED_ID)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
if (get_uid(__acl_unquote(cp), uid_p) != 0)
|
|
rpm-build |
0a0c83 |
continue;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
} else if (strncmp(cp, "group:", 6) == 0) {
|
|
rpm-build |
0a0c83 |
cp += 6;
|
|
rpm-build |
0a0c83 |
SKIP_WS(cp);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (gid_p) {
|
|
rpm-build |
0a0c83 |
if (*gid_p != ACL_UNDEFINED_ID)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
if (get_gid(__acl_unquote(cp), gid_p) != 0)
|
|
rpm-build |
0a0c83 |
continue;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
} else if (strncmp(cp, "flags:", 6) == 0) {
|
|
rpm-build |
0a0c83 |
mode_t f = 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
cp += 6;
|
|
rpm-build |
0a0c83 |
SKIP_WS(cp);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (cp[0] == 's')
|
|
rpm-build |
0a0c83 |
f |= S_ISUID;
|
|
rpm-build |
0a0c83 |
else if (cp[0] != '-')
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
if (cp[1] == 's')
|
|
rpm-build |
0a0c83 |
f |= S_ISGID;
|
|
rpm-build |
0a0c83 |
else if (cp[1] != '-')
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
if (cp[2] == 't')
|
|
rpm-build |
0a0c83 |
f |= S_ISVTX;
|
|
rpm-build |
0a0c83 |
else if (cp[2] != '-')
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
if (cp[3] != '\0')
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (flags)
|
|
rpm-build |
0a0c83 |
*flags = f;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (ferror(file))
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
return comments_read;
|
|
rpm-build |
0a0c83 |
fail:
|
|
rpm-build |
0a0c83 |
if (path_p && *path_p) {
|
|
rpm-build |
0a0c83 |
free(*path_p);
|
|
rpm-build |
0a0c83 |
*path_p = NULL;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
return -EINVAL;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
int
|
|
rpm-build |
0a0c83 |
read_acl_seq(
|
|
rpm-build |
0a0c83 |
FILE *file,
|
|
rpm-build |
0a0c83 |
seq_t seq,
|
|
rpm-build |
0a0c83 |
int seq_cmd,
|
|
rpm-build |
0a0c83 |
int parse_mode,
|
|
rpm-build |
0a0c83 |
int *lineno,
|
|
rpm-build |
0a0c83 |
int *which)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
char *line;
|
|
rpm-build |
0a0c83 |
const char *cp;
|
|
rpm-build |
0a0c83 |
cmd_t cmd;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (which)
|
|
rpm-build |
0a0c83 |
*which = -1;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
while ((line = __acl_next_line(file))) {
|
|
rpm-build |
0a0c83 |
if (lineno)
|
|
rpm-build |
0a0c83 |
(*lineno)++;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
cp = line;
|
|
rpm-build |
0a0c83 |
SKIP_WS(cp);
|
|
rpm-build |
0a0c83 |
if (*cp == '\0') {
|
|
rpm-build |
0a0c83 |
if (!(parse_mode & SEQ_PARSE_MULTI))
|
|
rpm-build |
0a0c83 |
continue;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
} else if (*cp == '#') {
|
|
rpm-build |
0a0c83 |
continue;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
cmd = parse_acl_cmd(&cp, seq_cmd, parse_mode);
|
|
rpm-build |
0a0c83 |
if (cmd == NULL) {
|
|
rpm-build |
0a0c83 |
errno = EINVAL;
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (seq_append(seq, cmd) != 0) {
|
|
rpm-build |
0a0c83 |
cmd_free(cmd);
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
SKIP_WS(cp);
|
|
rpm-build |
0a0c83 |
if (*cp != '\0' && *cp != '#') {
|
|
rpm-build |
0a0c83 |
errno = EINVAL;
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (ferror(file))
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
fail:
|
|
rpm-build |
0a0c83 |
if (which)
|
|
rpm-build |
0a0c83 |
*which = (cp - line);
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|