Encoder for ACL long text form

This commit is contained in:
Thomas Schmitt 2008-12-25 14:01:36 +00:00
parent 2c2a394a61
commit 37f4eaa9bb
3 changed files with 320 additions and 20 deletions

View File

@ -17,12 +17,29 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pwd.h>
#include <grp.h>
/* <<< */
#define Aaip_encode_debuG 1
#include "aaip_0_2.h"
#define Aaip_EXEC 1
#define Aaip_WRITE 2
#define Aaip_READ 4
#define Aaip_TRANSLATE 0
#define Aaip_ACL_USER_OBJ 1
#define Aaip_ACL_USER 2
#define Aaip_ACL_GROUP_OBJ 3
#define Aaip_ACL_GROUP 4
#define Aaip_ACL_MASK 5
#define Aaip_ACL_OTHER 6
#define Aaip_SWITCH_MARK 8
#define Aaip_ACL_USER_N 10
#define Aaip_ACL_GROUP_N 12
#define Aaip_FUTURE_VERSION 15
/* --------------------------------- Encoder ---------------------------- */
@ -174,7 +191,210 @@ static int aaip_encode_pair(char *name, size_t attr_length, char *attr,
}
/* >>> Encoder for ACLs */;
/* ----------- Encoder for ACLs ----------- */
static ssize_t aaip_encode_acl_text(char *acl_text,
size_t result_size, unsigned char *result, int flag);
/* Convert an ACL text as of acl_to_text(3) into the value of an Arbitrary
Attribute. According to AAIP 0.2 this value is to be stored together with
an empty name.
@param acl_text The ACL in long text form
@param result_len Number of bytes in the resulting value
@param result *result will point to the start of the result string.
This is malloc() memory which needs to be freed when
no longer needed
@param flag Bitfield for control purposes
bit0= count only
bit1= use numeric qualifiers rather than names
@return >0 means ok
0 means error
*/
int aaip_encode_acl(char *acl_text,
size_t *result_len, unsigned char **result, int flag)
{
ssize_t bytes;
*result= NULL;
*result_len= 0;
bytes= aaip_encode_acl_text(acl_text, (size_t) 0, NULL, 1 | (flag & 2));
if(bytes < 0)
return(0);
if(flag & 1) {
*result_len= bytes;
return(1);
}
*result= calloc(bytes + 1, 1);
if(*result == NULL)
return(-1);
(*result)[bytes]= 0;
*result_len= bytes;
bytes= aaip_encode_acl_text(acl_text, *result_len, *result, (flag & 2));
if(bytes != *result_len) {
*result_len= 0;
return(0);
}
return(1);
}
static double aaip_numeric_id(char *name, int flag)
{
double num;
char *cpt;
for(cpt= name; *cpt != 0; cpt++)
if(*cpt < '0' || *cpt >'9')
break;
if(*cpt != 0)
return(-1);
sscanf(name, "%lf", &num);
return(num);
}
/*
@param result_len Number of bytes in the resulting value
@param result *result will point to the start of the result string.
This is malloc() memory which needs to be freed when
no longer needed
@param flag Bitfield for control purposes
bit0= count only, do not really produce bytes
bit1= use numeric qualifiers
@return >=0 number of bytes produced resp. counted
<0 means error
*/
static ssize_t aaip_encode_acl_text(char *acl_text,
size_t result_size, unsigned char *result, int flag)
{
char *rpt, *npt, *cpt;
int qualifier= 0, perms, type, i, qualifier_len, num_recs;
uid_t uid, huid;
gid_t gid, hgid;
ssize_t count= 0;
struct passwd *pwd;
struct group *grp;
char name[1024];
double num;
for(rpt= acl_text; *rpt != 0; rpt= npt) {
npt= strchr(rpt, '\n');
if(npt == 0)
npt= rpt + strlen(rpt);
else
npt++;
if(*rpt == '#')
continue;
cpt= strchr(rpt, ':');
if(cpt == NULL)
continue;
cpt= strchr(cpt + 1, ':');
if(cpt == NULL)
continue;
qualifier= 0;
if(strncmp(rpt, "user:", 5) == 0) {
if(cpt - rpt == 5)
type= Aaip_ACL_USER_OBJ;
else {
if(cpt - (rpt + 5) >= sizeof(name))
continue;
strncpy(name, rpt + 5, cpt - (rpt + 5));
name[cpt - (rpt + 5)]= 0;
if(flag & 2) {
type= Aaip_ACL_USER_N;
pwd= getpwnam(name);
if(pwd == NULL) {
num= aaip_numeric_id(name, 0);
if(num <= 0)
goto user_by_name;
uid= huid= num;
} else
uid= huid= pwd->pw_uid;
/* Convert uid into Qualifier Record */
for(i= 0; huid != 0; i++)
huid= huid >> 8;
qualifier_len= i;
for(i= 0; i < qualifier_len ; i++)
name[i]= uid >> (8 * (qualifier_len - i - 1));
} else {
user_by_name:;
type= Aaip_ACL_USER;
qualifier_len= strlen(name);
}
qualifier= 1;
}
} else if(strncmp(rpt, "group:", 6) == 0) {
if(cpt - rpt == 6)
type= Aaip_ACL_GROUP_OBJ;
else {
if(cpt - (rpt + 6) >= sizeof(name))
continue;
strncpy(name, rpt + 6, cpt - (rpt + 6));
if(flag & 2) {
type= Aaip_ACL_GROUP_N;
grp= getgrnam(name);
if(grp == NULL) {
num= aaip_numeric_id(name, 0);
if(num <= 0)
goto group_by_name;
gid= hgid= num;
} else
gid= hgid= grp->gr_gid;
/* Convert gid into Qualifier Record */
for(i= 0; hgid != 0; i++)
hgid= hgid >> 8;
qualifier_len= i;
for(i= 0; i < qualifier_len ; i++)
name[i]= gid >> (8 * (qualifier_len - i - 1));
} else {
group_by_name:;
type= Aaip_ACL_GROUP;
qualifier_len= strlen(name);
}
qualifier= 1;
}
} else if(strncmp(rpt, "other:", 6) == 0) {
type= Aaip_ACL_OTHER;
} else if(strncmp(rpt, "mask:", 5) == 0) {
type= Aaip_ACL_MASK;
} else
continue;
perms= 0;
if(cpt[1] == 'r')
perms|= Aaip_READ;
if(cpt[2] == 'w')
perms|= Aaip_WRITE;
if(cpt[3] == 'x')
perms|= Aaip_EXEC;
if(!(flag & 1))
result[count]= perms | ((!!qualifier) << 3) | (type << 4);
count++;
if(qualifier) {
num_recs= (qualifier_len / 127) + !!(qualifier_len % 127);
if(!(flag & 1)) {
for(i= 0; i < num_recs; i++) {
if(i < num_recs - 1)
result[count++]= 255;
else {
result[count++]= (qualifier_len % 127);
if(result[count - 1] == 0)
result[count - 1]= 127;
}
memcpy(result + count, name + i * 127, result[count - 1] & 127);
count+= result[count - 1] & 127;
}
} else
count+= qualifier_len + num_recs;
}
}
return(count);
}
/* --------------------------------- Decoder ---------------------------- */

View File

@ -37,7 +37,22 @@ unsigned int aaip_encode(char aa_name[2],
size_t *result_len, unsigned char **result, int flag);
/* >>> Encoder for ACLs */;
/* Convert an ACL text as of acl_to_text(3) into the value of an Arbitrary
Attribute. According to AAIP 0.2 this value is to be stored together with
an empty name.
@param acl_text The ACL in long text form
@param result_len Number of bytes in the resulting value
@param result *result will point to the start of the result string.
This is malloc() memory which needs to be freed when
no longer needed
@param flag Bitfield for control purposes
bit0= count only
bit1= use numeric qualifiers rather than names
@return >0 means ok
0 means error
*/
int aaip_encode_acl(char *acl_text,
size_t *result_len, unsigned char **result, int flag);
/* --------------------------------- Decoder ---------------------------- */

View File

@ -8,7 +8,7 @@
test/aaip_0_2_test.c - Main program for test binary
Compile: cc -g -Wall -o test/aaip test/aaip_0_2.c test/aaip_0_2_test.c
Compile: cc -g -Wall -o test/aaip test/aaip_0_2.c test/aaip_0_2_test.c -lacl
Usage: ./aaip name value
Long parameters ./aaip -name"x100" -value"x100"
@ -23,12 +23,89 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/acl.h>
#include "aaip_0_2.h"
#define Aaip_test_name_sizE 1024
#define Aaip_test_value_sizE 1024
static int print_result(unsigned char *result, size_t result_len, int flag)
{
int i;
printf(
" - - - - - - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - - 8 - - 9\n");
printf("\n");
printf("%4u : ", 0);
for(i= 0; i < result_len; i++) {
if(result[i] >= 32 && result[i] <= 126)
printf("'%c' ", result[i]);
else
printf("%3u ", (unsigned int) ((unsigned char *) result)[i]);
if((i % 10) == 9)
printf("\n%4u : ", (unsigned int) (i + 1));
}
printf("\n\n");
printf(
" - - - - - - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - - 8 - - 9\n");
printf("\n");
return(1);
}
static int test_acl(char *path, int flag)
{
int ret;
acl_t acl= NULL;
char *acl_text= NULL;
unsigned char *result= NULL;
size_t result_len;
acl= acl_get_file(path, ACL_TYPE_ACCESS);
if(acl == NULL) {
fprintf(stderr, "acl_get_file failed: %d %s\n",
errno, errno != 0 ? strerror(errno) : "");
ret= 0; goto ex;
}
acl_text= acl_to_text(acl, NULL);
if(acl_text == NULL) {
fprintf(stderr, "acl_to_text failed: %d %s\n",
errno, errno != 0 ? strerror(errno) : "");
ret= 0; goto ex;
}
printf("--- ACL:\n%s--- end of ACL\n\n", acl_text);
ret= aaip_encode_acl(acl_text, &result_len, &result, 0);
if(ret <= 0) {
fprintf(stderr, "aaip_encode_acl(text) failed: ret= %d\n", ret);
ret= 0; goto ex;
}
print_result(result, result_len, 0);
free(result); result= NULL;
ret= aaip_encode_acl(acl_text, &result_len, &result, 2);
if(ret <= 0) {
fprintf(stderr, "aaip_encode_acl(num) failed: ret= %d\n", ret);
ret= 0; goto ex;
}
print_result(result, result_len, 0);
/* >>> */;
ret= 1;
ex:;
if(acl_text != NULL)
acl_free(acl_text);
if(acl != NULL)
acl_free(acl);
if(result != NULL)
free(result);
return(ret);
}
int main(int argc, char **argv)
{
int ret, l, mult= 0, k;
@ -48,6 +125,10 @@ int main(int argc, char **argv)
unsigned char *rpt;
unsigned int skipped, was_skipped= 0;
test_acl("/u/test/acl", 0);
if(argc < 3 || (argc % 2) == 0) {
fprintf(stderr, "usage: %s [-]name[xNNN] [-]value[xNNN] ...\n", argv[0]);
exit(1);
@ -91,23 +172,7 @@ int main(int argc, char **argv)
fprintf(stderr, "%s : aaip_encode failed with ret= %d\n", argv[0], ret);
exit(2);
}
printf(
" - - - - - - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - - 8 - - 9\n");
printf("\n");
printf("%4u : ", 0);
for(i= 0; i < result_len; i++) {
if(result[i] >= 32 && result[i] <= 126)
printf("'%c' ", result[i]);
else
printf("%3u ", (unsigned int) ((unsigned char *) result)[i]);
if((i % 10) == 9)
printf("\n%4u : ", (unsigned int) (i + 1));
}
printf("\n\n");
printf(
" - - - - - - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - - 6 - - 7 - - 8 - - 9\n");
printf("\n");
print_result(result, result_len, 0);
aaip_init(aaip, "AA", 0);
rpt= result;