|
rpm-build |
0a0c83 |
/*
|
|
rpm-build |
0a0c83 |
File: acl_from_text.c
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
Copyright (C) 1999, 2000, 2001
|
|
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 <string.h>
|
|
rpm-build |
0a0c83 |
#include <pwd.h>
|
|
rpm-build |
0a0c83 |
#include <grp.h>
|
|
rpm-build |
0a0c83 |
#include "libacl.h"
|
|
rpm-build |
0a0c83 |
#include "misc.h"
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
#define SKIP_WS(x) do { \
|
|
rpm-build |
0a0c83 |
while (*(x)==' ' || *(x)=='\t' || *(x)=='\n' || *(x)=='\r') \
|
|
rpm-build |
0a0c83 |
(x)++; \
|
|
rpm-build |
0a0c83 |
if (*(x)=='#') { \
|
|
rpm-build |
0a0c83 |
while (*(x)!='\n' && *(x)!='\0') \
|
|
rpm-build |
0a0c83 |
(x)++; \
|
|
rpm-build |
0a0c83 |
} \
|
|
rpm-build |
0a0c83 |
} while (0)
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static int parse_acl_entry(const char **text_p, acl_t *acl_p);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/* 23.4.13 */
|
|
rpm-build |
0a0c83 |
acl_t
|
|
rpm-build |
0a0c83 |
acl_from_text(const char *buf_p)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
acl_t acl;
|
|
rpm-build |
0a0c83 |
acl = acl_init(0);
|
|
rpm-build |
0a0c83 |
if (!acl)
|
|
rpm-build |
0a0c83 |
return NULL;
|
|
rpm-build |
0a0c83 |
if (!buf_p) {
|
|
rpm-build |
0a0c83 |
errno = EINVAL;
|
|
rpm-build |
0a0c83 |
return NULL;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
while (*buf_p != '\0') {
|
|
rpm-build |
0a0c83 |
if (parse_acl_entry(&buf_p, &acl) != 0)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
SKIP_WS(buf_p);
|
|
rpm-build |
0a0c83 |
if (*buf_p == ',') {
|
|
rpm-build |
0a0c83 |
buf_p++;
|
|
rpm-build |
0a0c83 |
SKIP_WS(buf_p);
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (*buf_p != '\0') {
|
|
rpm-build |
0a0c83 |
errno = EINVAL;
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
return acl;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
fail:
|
|
rpm-build |
0a0c83 |
acl_free(acl);
|
|
rpm-build |
0a0c83 |
return NULL;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static int
|
|
rpm-build |
0a0c83 |
skip_tag_name(const char **text_p, 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++;
|
|
rpm-build |
0a0c83 |
*text_p = text;
|
|
rpm-build |
0a0c83 |
return 1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static char *
|
|
rpm-build |
0a0c83 |
get_token(const char **text_p)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
char *token = NULL;
|
|
rpm-build |
0a0c83 |
const char *ep;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
ep = *text_p;
|
|
rpm-build |
0a0c83 |
SKIP_WS(ep);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
while (*ep!='\0' && *ep!='\r' && *ep!='\n' && *ep!=':' && *ep!=',')
|
|
rpm-build |
0a0c83 |
ep++;
|
|
rpm-build |
0a0c83 |
if (ep == *text_p)
|
|
rpm-build |
0a0c83 |
goto after_token;
|
|
rpm-build |
0a0c83 |
token = (char*)malloc(ep - *text_p + 1);
|
|
rpm-build |
0a0c83 |
if (token == 0)
|
|
rpm-build |
0a0c83 |
goto after_token;
|
|
rpm-build |
0a0c83 |
memcpy(token, *text_p, (ep - *text_p));
|
|
rpm-build |
0a0c83 |
token[ep - *text_p] = '\0';
|
|
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(const char *token, 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(const char *token, uid_t *uid_p)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
struct passwd *passwd;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (get_id(token, uid_p) == 0)
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
errno = 0;
|
|
rpm-build |
0a0c83 |
passwd = getpwnam(token);
|
|
rpm-build |
0a0c83 |
if (passwd) {
|
|
rpm-build |
0a0c83 |
*uid_p = passwd->pw_uid;
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (errno == 0)
|
|
rpm-build |
0a0c83 |
errno = EINVAL;
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
static int
|
|
rpm-build |
0a0c83 |
get_gid(const char *token, gid_t *gid_p)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
struct group *group;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
if (get_id(token, (uid_t *)gid_p) == 0)
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
errno = 0;
|
|
rpm-build |
0a0c83 |
group = getgrnam(token);
|
|
rpm-build |
0a0c83 |
if (group) {
|
|
rpm-build |
0a0c83 |
*gid_p = group->gr_gid;
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
if (errno == 0)
|
|
rpm-build |
0a0c83 |
errno = EINVAL;
|
|
rpm-build |
0a0c83 |
return -1;
|
|
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 |
static int
|
|
rpm-build |
0a0c83 |
parse_acl_entry(const char **text_p, acl_t *acl_p)
|
|
rpm-build |
0a0c83 |
{
|
|
rpm-build |
0a0c83 |
acl_entry_obj entry_obj;
|
|
rpm-build |
0a0c83 |
acl_entry_t entry_d;
|
|
rpm-build |
0a0c83 |
char *str;
|
|
rpm-build |
0a0c83 |
const char *backup;
|
|
rpm-build |
0a0c83 |
int error, perm_chars;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
new_obj_p_here(acl_entry, &entry_obj);
|
|
rpm-build |
0a0c83 |
init_acl_entry_obj(entry_obj);
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
/* parse acl entry type */
|
|
rpm-build |
0a0c83 |
SKIP_WS(*text_p);
|
|
rpm-build |
0a0c83 |
switch (**text_p) {
|
|
rpm-build |
0a0c83 |
case 'u': /* user */
|
|
rpm-build |
0a0c83 |
if (!skip_tag_name(text_p, "user"))
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
backup = *text_p;
|
|
rpm-build |
0a0c83 |
str = get_token(text_p);
|
|
rpm-build |
0a0c83 |
if (str) {
|
|
rpm-build |
0a0c83 |
entry_obj.etag = ACL_USER;
|
|
rpm-build |
0a0c83 |
error = get_uid(__acl_unquote(str),
|
|
rpm-build |
0a0c83 |
&entry_obj.eid.qid);
|
|
rpm-build |
0a0c83 |
free(str);
|
|
rpm-build |
0a0c83 |
if (error) {
|
|
rpm-build |
0a0c83 |
*text_p = backup;
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
entry_obj.etag = 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 fail;
|
|
rpm-build |
0a0c83 |
backup = *text_p;
|
|
rpm-build |
0a0c83 |
str = get_token(text_p);
|
|
rpm-build |
0a0c83 |
if (str) {
|
|
rpm-build |
0a0c83 |
entry_obj.etag = ACL_GROUP;
|
|
rpm-build |
0a0c83 |
error = get_gid(__acl_unquote(str),
|
|
rpm-build |
0a0c83 |
&entry_obj.eid.qid);
|
|
rpm-build |
0a0c83 |
free(str);
|
|
rpm-build |
0a0c83 |
if (error) {
|
|
rpm-build |
0a0c83 |
*text_p = backup;
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
} else {
|
|
rpm-build |
0a0c83 |
entry_obj.etag = ACL_GROUP_OBJ;
|
|
rpm-build |
0a0c83 |
}
|
|
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 fail;
|
|
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 |
entry_obj.etag = ACL_MASK;
|
|
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 fail;
|
|
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 |
entry_obj.etag = ACL_OTHER;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
default:
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
for (perm_chars=0; perm_chars<3; perm_chars++, (*text_p)++) {
|
|
rpm-build |
0a0c83 |
switch(**text_p) {
|
|
rpm-build |
0a0c83 |
case 'r':
|
|
rpm-build |
0a0c83 |
if (entry_obj.eperm.sperm & ACL_READ)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
entry_obj.eperm.sperm |= ACL_READ;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'w':
|
|
rpm-build |
0a0c83 |
if (entry_obj.eperm.sperm & ACL_WRITE)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
entry_obj.eperm.sperm |= ACL_WRITE;
|
|
rpm-build |
0a0c83 |
break;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
case 'x':
|
|
rpm-build |
0a0c83 |
if (entry_obj.eperm.sperm & ACL_EXECUTE)
|
|
rpm-build |
0a0c83 |
goto fail;
|
|
rpm-build |
0a0c83 |
entry_obj.eperm.sperm |= ACL_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 |
goto create_entry;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
create_entry:
|
|
rpm-build |
0a0c83 |
if (acl_create_entry(acl_p, &entry_d) != 0)
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
#pragma GCC diagnostic push
|
|
rpm-build |
0a0c83 |
#pragma GCC diagnostic ignored "-Waddress"
|
|
rpm-build |
0a0c83 |
if (acl_copy_entry(entry_d, int2ext(&entry_obj)) != 0)
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
#pragma GCC diagnostic pop
|
|
rpm-build |
0a0c83 |
return 0;
|
|
rpm-build |
0a0c83 |
|
|
rpm-build |
0a0c83 |
fail:
|
|
rpm-build |
0a0c83 |
errno = EINVAL;
|
|
rpm-build |
0a0c83 |
return -1;
|
|
rpm-build |
0a0c83 |
}
|
|
rpm-build |
0a0c83 |
|