Encoder for ACL long text form
This commit is contained in:
parent
e97848de8d
commit
a8695bf86e
@ -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 ---------------------------- */
|
||||
|
@ -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 ---------------------------- */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user