00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <ctype.h>
00015 #include <sys/types.h>
00016 #include <unistd.h>
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #include <stdio.h>
00020 #include <pwd.h>
00021 #include <grp.h>
00022
00023
00024 #define Aaip_encode_debuG 1
00025
00026 #include "aaip_0_2.h"
00027
00028 #define Aaip_EXEC 1
00029 #define Aaip_WRITE 2
00030 #define Aaip_READ 4
00031
00032 #define Aaip_TRANSLATE 0
00033 #define Aaip_ACL_USER_OBJ 1
00034 #define Aaip_ACL_USER 2
00035 #define Aaip_ACL_GROUP_OBJ 3
00036 #define Aaip_ACL_GROUP 4
00037 #define Aaip_ACL_MASK 5
00038 #define Aaip_ACL_OTHER 6
00039 #define Aaip_SWITCH_MARK 8
00040 #define Aaip_ACL_USER_N 10
00041 #define Aaip_ACL_GROUP_N 12
00042 #define Aaip_FUTURE_VERSION 15
00043
00044
00045
00046
00047 static int aaip_encode_pair(char *name, size_t attr_length, char *attr,
00048 unsigned int *num_recs, size_t *comp_size,
00049 unsigned char *result, size_t result_fill,
00050 int flag);
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 unsigned int aaip_encode(char aa_name[2],
00069 unsigned int num_attrs, char **names,
00070 size_t *attr_lengths, char **attrs,
00071 size_t *result_len, unsigned char **result, int flag)
00072 {
00073 size_t mem_size= 0, comp_size;
00074 unsigned int number_of_fields, i, num_recs, total_recs= 0, ret;
00075
00076
00077 *result_len= 0;
00078 for(i= 0; i < num_attrs; i++) {
00079 ret= aaip_encode_pair(names[i], attr_lengths[i], attrs[i],
00080 &num_recs, &comp_size, NULL, (size_t) 0, 1);
00081 if(ret <= 0)
00082 return(ret);
00083 mem_size+= comp_size;
00084 total_recs= num_recs;
00085 }
00086 number_of_fields= mem_size / 250 + !!(mem_size % 250);
00087 mem_size+= number_of_fields * 5;
00088
00089 #ifdef Aaip_encode_debuG
00090 *result= (unsigned char *) calloc(1, mem_size + 1024000);
00091
00092 #else
00093 *result= (unsigned char *) calloc(1, mem_size);
00094 #endif
00095
00096
00097
00098 for(i= 0; i < num_attrs; i++) {
00099 ret= aaip_encode_pair(names[i], attr_lengths[i], attrs[i],
00100 &num_recs, &comp_size, *result, *result_len, 0);
00101 if(ret <= 0)
00102 return(ret);
00103 (*result_len)+= comp_size;
00104 }
00105
00106
00107 for(i= 0; i < number_of_fields; i++) {
00108 (*result)[i * 255 + 0]= aa_name[0];
00109 (*result)[i * 255 + 1]= aa_name[1];
00110 if(i < number_of_fields - 1 || (mem_size % 255) == 0)
00111 (*result)[i * 255 + 2]= 255;
00112 else
00113 (*result)[i * 255 + 2]= mem_size % 255;
00114 (*result)[i * 255 + 3]= 1;
00115 (*result)[i * 255 + 4]= (flag & 1) || (i < number_of_fields - 1);
00116 }
00117 (*result_len)+= number_of_fields * 5;
00118
00119 #ifdef Aaip_encode_debuG
00120 if(*result_len != mem_size) {
00121 fprintf(stderr, "aaip_encode(): MEMORY MISMATCH BY %d BYTES\n",
00122 (int) (mem_size - *result_len));
00123 }
00124 ret= 0;
00125 for(i= 0; i < *result_len; i+= ((unsigned char *) (*result))[i + 2])
00126 ret++;
00127 if(ret != number_of_fields) {
00128 fprintf(stderr, "aaip_encode(): WRONG NUMBER OF FIELDS %d <> %d\n",
00129 number_of_fields, ret);
00130 }
00131 #endif
00132
00133 return(number_of_fields);
00134 }
00135
00136
00137 static void aaip_encode_byte(unsigned char *result, size_t *result_fill,
00138 unsigned char value)
00139 {
00140 result[(*result_fill / 250) * 255 + 5 + (*result_fill % 250)]= value;
00141 (*result_fill)++;
00142 }
00143
00144
00145 static int aaip_encode_comp(unsigned char *result, size_t *result_fill,
00146 char *data, size_t l, int flag)
00147 {
00148 size_t todo;
00149 char *rpt, *comp_start;
00150
00151 if(l == 0) {
00152 aaip_encode_byte(result, result_fill, 0);
00153 aaip_encode_byte(result, result_fill, 0);
00154 return(1);
00155 }
00156 for(rpt= data; rpt - data < l;) {
00157 todo= l - (rpt - data);
00158 aaip_encode_byte(result, result_fill, (todo > 255));
00159 if(todo > 255)
00160 todo= 255;
00161 aaip_encode_byte(result, result_fill, todo);
00162 for(comp_start= rpt; rpt - comp_start < todo; rpt++)
00163 aaip_encode_byte(result, result_fill, *((unsigned char *) rpt));
00164 }
00165 return(1);
00166 }
00167
00168
00169
00170
00171
00172
00173 static int aaip_encode_pair(char *name, size_t attr_length, char *attr,
00174 unsigned int *num_recs, size_t *comp_size,
00175 unsigned char *result, size_t result_fill,
00176 int flag)
00177 {
00178 size_t l;
00179
00180 l= strlen(name);
00181 *num_recs= l / 255 + (!!(l % 255)) + (l == 0) +
00182 attr_length / 255 + (!!(attr_length % 255)) + (attr_length == 0);
00183 *comp_size= l + attr_length + 2 * *num_recs;
00184
00185 if(flag & 1)
00186 return(1);
00187
00188 aaip_encode_comp(result, &result_fill, name, l, 0);
00189 aaip_encode_comp(result, &result_fill, attr, attr_length, 0);
00190 return(1);
00191 }
00192
00193
00194
00195
00196 static ssize_t aaip_encode_acl_text(char *acl_text,
00197 size_t result_size, unsigned char *result, int flag);
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 int aaip_encode_acl(char *acl_text,
00216 size_t *result_len, unsigned char **result, int flag)
00217 {
00218 ssize_t bytes;
00219
00220 *result= NULL;
00221 *result_len= 0;
00222 bytes= aaip_encode_acl_text(acl_text, (size_t) 0, NULL, 1 | (flag & 6));
00223 if(bytes < 0)
00224 return(0);
00225 if(flag & 1) {
00226 *result_len= bytes;
00227 return(1);
00228 }
00229 *result= calloc(bytes + 1, 1);
00230 if(*result == NULL)
00231 return(-1);
00232 (*result)[bytes]= 0;
00233 *result_len= bytes;
00234 bytes= aaip_encode_acl_text(acl_text, *result_len, *result, (flag & 6));
00235 if(bytes != *result_len) {
00236 *result_len= 0;
00237 return(0);
00238 }
00239 return(1);
00240 }
00241
00242
00243 static double aaip_numeric_id(char *name, int flag)
00244 {
00245 double num;
00246 char *cpt;
00247
00248 for(cpt= name; *cpt != 0; cpt++)
00249 if(*cpt < '0' || *cpt >'9')
00250 break;
00251 if(*cpt != 0)
00252 return(-1);
00253 sscanf(name, "%lf", &num);
00254 return(num);
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 static ssize_t aaip_encode_acl_text(char *acl_text,
00269 size_t result_size, unsigned char *result, int flag)
00270 {
00271 char *rpt, *npt, *cpt;
00272 int qualifier= 0, perms, type, i, qualifier_len, num_recs;
00273 uid_t uid, huid;
00274 gid_t gid, hgid;
00275 ssize_t count= 0;
00276 struct passwd *pwd;
00277 struct group *grp;
00278 char name[1024];
00279 double num;
00280
00281 if(flag & 4) {
00282 ;
00283 if(!(flag & 1)) {
00284 if(count >= result_size)
00285 return(-1);
00286 result[count]= (Aaip_SWITCH_MARK << 4) | Aaip_EXEC;
00287 }
00288 count++;
00289 }
00290
00291 for(rpt= acl_text; *rpt != 0; rpt= npt) {
00292 npt= strchr(rpt, '\n');
00293 if(npt == 0)
00294 npt= rpt + strlen(rpt);
00295 else
00296 npt++;
00297 if(*rpt == '#')
00298 continue;
00299 cpt= strchr(rpt, ':');
00300 if(cpt == NULL)
00301 continue;
00302 cpt= strchr(cpt + 1, ':');
00303 if(cpt == NULL)
00304 continue;
00305 qualifier= 0;
00306 if(strncmp(rpt, "user:", 5) == 0) {
00307 if(cpt - rpt == 5)
00308 type= Aaip_ACL_USER_OBJ;
00309 else {
00310 if(cpt - (rpt + 5) >= sizeof(name))
00311 continue;
00312 strncpy(name, rpt + 5, cpt - (rpt + 5));
00313 name[cpt - (rpt + 5)]= 0;
00314 if(flag & 2) {
00315 type= Aaip_ACL_USER_N;
00316 pwd= getpwnam(name);
00317 if(pwd == NULL) {
00318 num= aaip_numeric_id(name, 0);
00319 if(num <= 0)
00320 goto user_by_name;
00321 uid= huid= num;
00322 } else
00323 uid= huid= pwd->pw_uid;
00324
00325 for(i= 0; huid != 0; i++)
00326 huid= huid >> 8;
00327 qualifier_len= i;
00328 for(i= 0; i < qualifier_len ; i++)
00329 name[i]= uid >> (8 * (qualifier_len - i - 1));
00330 } else {
00331 user_by_name:;
00332 type= Aaip_ACL_USER;
00333 qualifier_len= strlen(name);
00334 }
00335 qualifier= 1;
00336 }
00337 } else if(strncmp(rpt, "group:", 6) == 0) {
00338 if(cpt - rpt == 6)
00339 type= Aaip_ACL_GROUP_OBJ;
00340 else {
00341 if(cpt - (rpt + 6) >= sizeof(name))
00342 continue;
00343 strncpy(name, rpt + 6, cpt - (rpt + 6));
00344 if(flag & 2) {
00345 type= Aaip_ACL_GROUP_N;
00346 grp= getgrnam(name);
00347 if(grp == NULL) {
00348 num= aaip_numeric_id(name, 0);
00349 if(num <= 0)
00350 goto group_by_name;
00351 gid= hgid= num;
00352 } else
00353 gid= hgid= grp->gr_gid;
00354
00355 for(i= 0; hgid != 0; i++)
00356 hgid= hgid >> 8;
00357 qualifier_len= i;
00358 for(i= 0; i < qualifier_len ; i++)
00359 name[i]= gid >> (8 * (qualifier_len - i - 1));
00360
00361 } else {
00362 group_by_name:;
00363 type= Aaip_ACL_GROUP;
00364 qualifier_len= strlen(name);
00365 }
00366 qualifier= 1;
00367 }
00368 } else if(strncmp(rpt, "other:", 6) == 0) {
00369 type= Aaip_ACL_OTHER;
00370 } else if(strncmp(rpt, "mask:", 5) == 0) {
00371 type= Aaip_ACL_MASK;
00372 } else
00373 continue;
00374
00375 if(npt - cpt < 3)
00376 continue;
00377 perms= 0;
00378 if(cpt[1] == 'r')
00379 perms|= Aaip_READ;
00380 if(cpt[2] == 'w')
00381 perms|= Aaip_WRITE;
00382 if(cpt[3] == 'x')
00383 perms|= Aaip_EXEC;
00384
00385 if(!(flag & 1)) {
00386 if(count >= result_size)
00387 return(-1);
00388 result[count]= perms | ((!!qualifier) << 3) | (type << 4);
00389 }
00390 count++;
00391
00392 if(qualifier) {
00393 num_recs= (qualifier_len / 127) + !!(qualifier_len % 127);
00394 if(!(flag & 1)) {
00395 if(count + 1 > result_size)
00396 return(-1);
00397 for(i= 0; i < num_recs; i++) {
00398 if(i < num_recs - 1)
00399 result[count++]= 255;
00400 else {
00401 result[count++]= (qualifier_len % 127);
00402 if(result[count - 1] == 0)
00403 result[count - 1]= 127;
00404 }
00405 if(count + (result[count - 1] & 127) > result_size)
00406 return(-1);
00407 memcpy(result + count, name + i * 127, result[count - 1] & 127);
00408 count+= result[count - 1] & 127;
00409 }
00410 } else
00411 count+= qualifier_len + num_recs;
00412 }
00413 }
00414
00415 return(count);
00416 }
00417
00418
00419
00420
00421
00422
00423
00424 #define Aaip_buffer_sizE 4096
00425
00426
00427
00428
00429 #define Aaip_buffer_reservE (257 + 3 * 2)
00430
00431
00432 struct aaip_state {
00433
00434
00435 unsigned char aa_name[2];
00436 int aa_head_missing;
00437 int aa_missing;
00438 int aa_ends;
00439
00440
00441
00442 int recs_invalid;
00443 unsigned char recs[Aaip_buffer_sizE + Aaip_buffer_reservE];
00444 size_t recs_fill;
00445 unsigned char *recs_start;
00446 int rec_head_missing;
00447 int rec_missing;
00448 int rec_ends;
00449
00450
00451 unsigned int num_recs;
00452 size_t ready_bytes;
00453
00454
00455 unsigned int num_components;
00456 size_t end_of_components;
00457 int first_is_name;
00458
00459
00460 int pair_status;
00461 unsigned int pairs_skipped;
00462
00463 };
00464
00465
00466
00467
00468
00469 size_t aaip_sizeof_aaip_state(void)
00470 {
00471 return((size_t) sizeof(struct aaip_state));
00472 }
00473
00474
00475 int aaip_init(struct aaip_state *aaip, char aa_name[2], int flag)
00476 {
00477 aaip->aa_name[0]= aa_name[0];
00478 aaip->aa_name[1]= aa_name[1];
00479 aaip->aa_head_missing= 5;
00480 aaip->aa_missing= 0;
00481
00482 aaip->recs_invalid= 0;
00483 memset(aaip->recs, 0, Aaip_buffer_sizE + Aaip_buffer_reservE);
00484 aaip->recs_fill= 0;
00485 aaip->recs_start= aaip->recs;
00486 aaip->rec_head_missing= 2;
00487 aaip->rec_missing= 0;
00488 aaip->rec_ends= 0;
00489
00490 aaip->num_recs= 0;
00491 aaip->ready_bytes= 0;
00492
00493 aaip->num_components= 0;
00494 aaip->end_of_components= 0;
00495 aaip->first_is_name= 1;
00496
00497 aaip->pair_status= 2;
00498 aaip->pairs_skipped= 0;
00499
00500 return(1);
00501 }
00502
00503
00504
00505 #define Aaip_with_ring_buffeR yes
00506
00507 #ifdef Aaip_with_ring_buffeR
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 static int aaip_ring_adr(struct aaip_state *aaip, size_t idx, size_t todo,
00522 unsigned char **start_pt, size_t *at_start_pt,
00523 size_t *at_recs, int flag)
00524 {
00525 size_t ahead;
00526
00527 ahead= Aaip_buffer_sizE + Aaip_buffer_reservE
00528 - (aaip->recs_start - aaip->recs);
00529 if(idx < ahead)
00530 *start_pt= (aaip->recs_start + idx);
00531 else
00532 *start_pt= aaip->recs + (idx - ahead);
00533 ahead= Aaip_buffer_sizE + Aaip_buffer_reservE - (*start_pt - aaip->recs);
00534 if(todo >= ahead) {
00535 *at_start_pt= ahead;
00536 *at_recs= todo - ahead;
00537 return(2);
00538 }
00539 *at_start_pt= todo;
00540 *at_recs= 0;
00541 return(1);
00542 }
00543
00544
00545
00546
00547
00548
00549 static int aaip_push_to_recs(struct aaip_state *aaip, unsigned char *data,
00550 size_t todo, int flag)
00551 {
00552 unsigned char *start_pt;
00553 size_t at_start_pt, at_recs;
00554
00555 aaip_ring_adr(aaip, aaip->recs_fill, todo,
00556 &start_pt, &at_start_pt, &at_recs, 0);
00557 if(at_start_pt > 0)
00558 memcpy(start_pt, data, at_start_pt);
00559 if(at_recs > 0)
00560 memcpy(aaip->recs, data + at_start_pt, at_recs);
00561 aaip->recs_fill+= todo;
00562 if(flag & 1)
00563 aaip->ready_bytes+= todo;
00564 return(1);
00565 }
00566
00567
00568 static int aaip_read_from_recs(struct aaip_state *aaip, size_t idx,
00569 unsigned char *data, size_t num_data, int flag)
00570 {
00571 unsigned char *start_pt;
00572 size_t at_start_pt, at_recs;
00573
00574 aaip_ring_adr(aaip, idx, num_data,
00575 &start_pt, &at_start_pt, &at_recs, 0);
00576 if(at_start_pt > 0)
00577 memcpy(data, start_pt, at_start_pt);
00578 if(at_recs > 0)
00579 memcpy(data + at_start_pt, aaip->recs, at_recs);
00580 return(1);
00581 }
00582
00583
00584 static int aaip_set_buffer_byte(struct aaip_state *aaip, size_t idx,
00585 unsigned char data, int flag)
00586 {
00587 unsigned char *start_pt;
00588 size_t at_start_pt, at_recs;
00589
00590 aaip_ring_adr(aaip, idx, 1,
00591 &start_pt, &at_start_pt, &at_recs, 0);
00592 *start_pt= data;
00593 return(1);
00594 }
00595
00596
00597 static int aaip_get_buffer_byte(struct aaip_state *aaip, size_t idx, int flag)
00598 {
00599 unsigned char *start_pt;
00600 size_t at_start_pt, at_recs;
00601
00602 aaip_ring_adr(aaip, idx, 1,
00603 &start_pt, &at_start_pt, &at_recs, 0);
00604 return((int) *start_pt);
00605 }
00606
00607
00608 static int aaip_shift_recs(struct aaip_state *aaip, size_t todo, int flag)
00609 {
00610 int ret;
00611 unsigned char *start_pt;
00612 size_t at_start_pt, at_recs;
00613
00614 if(todo < aaip->recs_fill) {
00615 ret= aaip_ring_adr(aaip, 0, todo, &start_pt, &at_start_pt, &at_recs, 0);
00616 if(ret == 1)
00617 aaip->recs_start= start_pt + todo;
00618 else
00619 aaip->recs_start= aaip->recs + at_recs;
00620 } else {
00621 aaip->recs_start= aaip->recs;
00622 }
00623 aaip->recs_fill-= todo;
00624 if(aaip->end_of_components >= todo)
00625 aaip->end_of_components-= todo;
00626 else
00627 aaip->end_of_components= 0;
00628 return(1);
00629 }
00630
00631
00632 #else
00633
00634
00635
00636
00637
00638
00639 static int aaip_push_to_recs(struct aaip_state *aaip, unsigned char *data,
00640 size_t todo, int flag)
00641 {
00642 memcpy(aaip->recs + aaip->recs_fill, data, todo);
00643 aaip->recs_fill+= todo;
00644 if(flag & 1)
00645 aaip->ready_bytes+= todo;
00646 return(1);
00647 }
00648
00649
00650 static int aaip_read_from_recs(struct aaip_state *aaip, size_t idx,
00651 unsigned char *data, size_t num_data, int flag)
00652 {
00653 memcpy(data, aaip->recs + idx, num_data);
00654 return(1);
00655 }
00656
00657
00658 static int aaip_set_buffer_byte(struct aaip_state *aaip, size_t idx,
00659 unsigned char data, int flag)
00660 {
00661 aaip->recs[idx]= data;
00662 return(1);
00663 }
00664
00665
00666 static int aaip_get_buffer_byte(struct aaip_state *aaip, size_t idx, int flag)
00667 {
00668 return((int) aaip->recs[idx]);
00669 }
00670
00671
00672 static int aaip_shift_recs(struct aaip_state *aaip, size_t todo, int flag)
00673 {
00674 if(todo < aaip->recs_fill)
00675 memmove(aaip->recs, aaip->recs + todo, aaip->recs_fill - todo);
00676 aaip->recs_fill-= todo;
00677
00678 if(aaip->end_of_components >= todo)
00679 aaip->end_of_components-= todo;
00680 else
00681 aaip->end_of_components= 0;
00682 return(1);
00683 }
00684
00685
00686 #endif
00687
00688
00689 static int aaip_consume_rec_head(struct aaip_state *aaip,
00690 unsigned char **data, size_t *num_data, int flag)
00691 {
00692 size_t todo;
00693
00694 todo= *num_data;
00695 if(todo > aaip->aa_missing)
00696 todo= aaip->aa_missing;
00697 if(todo >= aaip->rec_head_missing)
00698 todo= aaip->rec_head_missing;
00699 if(!aaip->recs_invalid)
00700 aaip_push_to_recs(aaip, *data, todo, 0);
00701 aaip->rec_head_missing-= todo;
00702 if(aaip->rec_head_missing == 0) {
00703 aaip->rec_missing= aaip_get_buffer_byte(aaip, aaip->recs_fill - 1, 0);
00704 aaip->rec_ends= !(aaip_get_buffer_byte(aaip, aaip->recs_fill - 2, 0) & 1);
00705 }
00706 aaip->aa_missing-= todo;
00707 (*num_data)-= todo;
00708 (*data)+= todo;
00709 return(1);
00710 }
00711
00712
00713 static int aaip_consume_rec_data(struct aaip_state *aaip,
00714 unsigned char **data, size_t *num_data, int flag)
00715 {
00716 size_t todo;
00717
00718 todo= *num_data;
00719 if(todo > aaip->aa_missing)
00720 todo= aaip->aa_missing;
00721 if(todo > aaip->rec_missing)
00722 todo= aaip->rec_missing;
00723 if(!aaip->recs_invalid)
00724 aaip_push_to_recs(aaip, *data, todo, 1);
00725 aaip->rec_missing-= todo;
00726 aaip->aa_missing-= todo;
00727 (*num_data)-= todo;
00728 (*data)+= todo;
00729 if(aaip->rec_missing <= 0) {
00730 if(aaip->recs_invalid > 0) {
00731 if(aaip->rec_ends)
00732 aaip->recs_invalid--;
00733 } else {
00734 aaip->num_recs++;
00735 if(aaip->rec_ends) {
00736 aaip->num_components++;
00737 aaip->end_of_components= aaip->recs_fill;
00738 }
00739 }
00740 aaip->rec_head_missing= 2;
00741 }
00742 return(0);
00743 }
00744
00745
00746 static int aaip_consume_aa_head(struct aaip_state *aaip,
00747 unsigned char **data, size_t *num_data, int flag)
00748 {
00749 size_t todo;
00750 unsigned char aa_head[5];
00751
00752 todo= *num_data;
00753 if(todo >= aaip->aa_head_missing)
00754 todo= aaip->aa_head_missing;
00755 aaip_push_to_recs(aaip, *data, todo, 0);
00756 aaip->aa_head_missing-= todo;
00757 if(aaip->aa_head_missing == 0) {
00758 aaip_read_from_recs(aaip, aaip->recs_fill - 5, aa_head, 5, 0);
00759 if(aa_head[0] != aaip->aa_name[0] || aa_head[1] != aaip->aa_name[1] ||
00760 aa_head[3] != 1)
00761 return(-1);
00762 aaip->aa_missing= aa_head[2];
00763 aaip->aa_ends= !(aa_head[4] & 1);
00764 aaip->recs_fill-= 5;
00765 if(aaip->aa_missing >= 5)
00766 aaip->aa_missing-= 5;
00767 else
00768 aaip->aa_missing= 0;
00769 }
00770 (*num_data)-= todo;
00771 (*data)+= todo;
00772 return(1);
00773 }
00774
00775
00776 static int aaip_consume_aa_data(struct aaip_state *aaip,
00777 unsigned char **data, size_t *num_data, int flag)
00778 {
00779 size_t i;
00780 static unsigned char zero_char[2]= {0, 0};
00781
00782 while(*num_data > 0 && aaip->aa_missing > 0) {
00783 if(aaip->rec_head_missing > 0) {
00784 aaip_consume_rec_head(aaip, data, num_data, 0);
00785 if(*num_data == 0 || aaip->aa_missing <= 0)
00786 return(1);
00787 }
00788 aaip_consume_rec_data(aaip, data, num_data, 0);
00789 }
00790 if(aaip->aa_missing <= 0) {
00791 if(aaip->aa_ends) {
00792
00793 if(aaip->rec_head_missing != 2) {
00794 if(aaip->rec_head_missing) {
00795
00796 aaip_set_buffer_byte(aaip, aaip->recs_fill - 1, (unsigned char) 0, 0);
00797 aaip_push_to_recs(aaip, zero_char, 1, 0);
00798 } else {
00799
00800 for(i= 0; i < aaip->rec_missing; i++)
00801 aaip_push_to_recs(aaip, zero_char, 1, 1);
00802 }
00803 aaip->rec_head_missing= 2;
00804 aaip->rec_missing= 0;
00805 aaip->num_recs++;
00806 if(aaip->rec_ends) {
00807 aaip->num_components++;
00808 aaip->end_of_components= aaip->recs_fill;
00809 }
00810 }
00811 if(aaip->end_of_components != aaip->recs_fill &&
00812 aaip->end_of_components != 0) {
00813
00814
00815 aaip_push_to_recs(aaip, zero_char, 2, 0);
00816 aaip->num_recs++;
00817 aaip->num_components++;
00818 aaip->end_of_components= aaip->recs_fill;
00819 }
00820 if(!(aaip->first_is_name ^ (aaip->num_components % 2))) {
00821
00822
00823 aaip_push_to_recs(aaip, zero_char, 2, 0);
00824 aaip->num_recs++;
00825 aaip->num_components++;
00826 aaip->end_of_components= aaip->recs_fill;
00827 }
00828 aaip->aa_ends= 2;
00829 } else
00830 aaip->aa_head_missing= 5;
00831 }
00832 return(0);
00833 }
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 int aaip_submit_data(struct aaip_state *aaip,
00853 unsigned char *data, size_t num_data,
00854 size_t *ready_bytes, int flag)
00855 {
00856 int ret;
00857 unsigned char *in_data;
00858
00859 if(aaip->aa_ends == 3)
00860 return(4);
00861 in_data= data;
00862 if(num_data == 0)
00863 goto ex;
00864 if(aaip->recs_fill + num_data > Aaip_buffer_sizE)
00865 return(0);
00866
00867 while(num_data > 0) {
00868 if(aaip->aa_head_missing > 0) {
00869 ret= aaip_consume_aa_head(aaip, &data, &num_data, 0);
00870 if(ret < 0) {
00871 *ready_bytes= data - in_data;
00872 return(-1);
00873 }
00874 if(num_data == 0 || aaip->aa_missing <= 0)
00875 goto ex;
00876 }
00877 aaip_consume_aa_data(aaip, &data, &num_data, 0);
00878 if(aaip->aa_missing)
00879 break;
00880 }
00881 ex:;
00882 *ready_bytes= aaip->ready_bytes;
00883 if(aaip->num_components > 0)
00884 return(3);
00885 if(aaip->num_recs > 0)
00886 return(2);
00887 if(aaip->aa_ends && aaip->aa_head_missing == 0 && aaip->aa_missing == 0)
00888 aaip->aa_ends= 2;
00889 if(aaip->aa_ends == 2 && aaip->num_recs == 0)
00890 aaip->aa_ends= 3;
00891 if(aaip->aa_ends == 3)
00892 return(4);
00893 return(1);
00894 }
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 int aaip_fetch_data(struct aaip_state *aaip,
00914 char *result, size_t result_size, size_t *num_result,
00915 int flag)
00916 {
00917 int ret= -1, complete= 0, payload;
00918 unsigned int i, num_bytes= 0, h;
00919
00920 if(aaip->num_recs == 0)
00921 return(-1);
00922
00923
00924 h= 0;
00925 for(i= 0; i < aaip->num_recs && !complete; i++) {
00926 payload= aaip_get_buffer_byte(aaip, h + 1, 0);
00927 if(!(flag & 1)) {
00928 if(num_bytes + payload > result_size)
00929 return(-2);
00930 aaip_read_from_recs(aaip, h + 2, (unsigned char *) (result + num_bytes),
00931 payload, 0);
00932 *num_result= num_bytes + payload;
00933 }
00934 num_bytes+= payload;
00935 if(!(aaip_get_buffer_byte(aaip, h, 0) & 1))
00936 complete= 1;
00937 h+= payload + 2;
00938 }
00939 aaip->ready_bytes-= num_bytes;
00940 aaip->num_recs-= i;
00941
00942
00943 aaip_shift_recs(aaip, h, 0);
00944
00945
00946 ret= 2 * !aaip->first_is_name;
00947 if(complete) {
00948 aaip->first_is_name= !aaip->first_is_name;
00949 if(aaip->num_components > 0)
00950 aaip->num_components--;
00951 } else
00952 ret|= 1;
00953
00954 return(ret);
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 int aaip_skip_component(struct aaip_state *aaip, int flag)
00969 {
00970 int to_skip= 1;
00971
00972 if(aaip->first_is_name && !(flag & 1))
00973 to_skip= 2;
00974 if(aaip->recs_invalid) {
00975 aaip->recs_invalid+= to_skip;
00976 return(1);
00977 }
00978
00979 if(aaip->num_components) {
00980
00981 aaip_fetch_data(aaip, NULL, (size_t) 0, NULL, 1);
00982 to_skip--;
00983 }
00984 if(aaip->num_components && to_skip) {
00985
00986 aaip_fetch_data(aaip, NULL, (size_t) 0, NULL, 1);
00987 to_skip--;
00988 }
00989 if(to_skip) {
00990 aaip->recs_fill= 0;
00991 aaip->num_recs= 0;
00992 aaip->ready_bytes= 0;
00993 }
00994 aaip->recs_invalid= to_skip;
00995 if(aaip->aa_ends == 2 && aaip->num_recs == 0)
00996 aaip->aa_ends= 3;
00997 return(1 + (aaip->num_recs > 0));
00998 }
00999
01000
01001
01002
01003
01004 static int aaip_advance_pair(struct aaip_state *aaip,
01005 char *name, size_t name_size, size_t *name_fill,
01006 char *value, size_t value_size, size_t *value_fill,
01007 int flag)
01008 {
01009 int ret;
01010 char *wpt;
01011 size_t size, num;
01012
01013 retry:;
01014 if(aaip->first_is_name) {
01015 wpt= name + *name_fill;
01016 size= name_size - *name_fill;
01017 } else {
01018 wpt= value + *value_fill;
01019 size= value_size - *value_fill;
01020 }
01021 ret= aaip_fetch_data(aaip, wpt, size, &num, 0);
01022 if(ret == -2) {
01023 ret= aaip_skip_component(aaip, 0);
01024 *name_fill= *value_fill= 0;
01025 aaip->pairs_skipped++;
01026 if(ret == 2)
01027 goto retry;
01028 } else if(ret == -1) {
01029 return(-1);
01030 } else if(ret == 0) {
01031 (*name_fill)+= num;
01032
01033 ret= aaip_submit_data(aaip, NULL, (size_t) 0, &num, 0);
01034 if(ret == 2 || ret == 3) {
01035 ;
01036 ret= aaip_advance_pair(aaip, name, name_size, name_fill,
01037 value, value_size, value_fill, flag);
01038 return ret;
01039 } else if(ret == 4)
01040 return(5);
01041 } else if(ret == 1) {
01042 (*name_fill)+= num;
01043 } else if(ret == 2) {
01044 (*value_fill)+= num;
01045 if(aaip->num_components >= 2)
01046 return(3);
01047 if(aaip->aa_ends == 2 && aaip->num_recs == 0)
01048 aaip->aa_ends= 3;
01049 if(aaip->aa_ends == 3)
01050 return(4);
01051 return(2);
01052 } else if(ret == 3) {
01053 ;
01054 (*value_fill)+= num;
01055 } else {
01056 return(-1);
01057 }
01058 return(1);
01059 }
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086 int aaip_decode_pair(struct aaip_state *aaip,
01087 unsigned char *data, size_t num_data, size_t *consumed,
01088 char *name, size_t name_size, size_t *name_fill,
01089 char *value, size_t value_size, size_t *value_fill,
01090 int flag)
01091 {
01092 int ret;
01093 size_t ready_bytes;
01094
01095 *consumed= 0;
01096 if(aaip->pair_status < 0 || aaip->pair_status == 4 ||
01097 aaip->pair_status == 5) {
01098 ret= aaip->pair_status;
01099 goto ex;
01100 } else if(aaip->pair_status == 2 || aaip->pair_status == 3) {
01101 if(aaip->pair_status == 3 && num_data > 0)
01102 {ret= 0; goto ex;}
01103
01104 if(!aaip->first_is_name)
01105 aaip_fetch_data(aaip, NULL, (size_t) 0, NULL, 1);
01106 *name_fill= *value_fill= 0;
01107 }
01108
01109 if(num_data > 0) {
01110 ret= aaip_submit_data(aaip, data, num_data, &ready_bytes, 0);
01111 } else {
01112 ret= 1;
01113 if(aaip->num_components)
01114 ret= 3;
01115 else if(aaip->num_recs)
01116 ret= 2;
01117 }
01118 if(ret < 0) {
01119 *consumed= ready_bytes;
01120 {ret= -1; goto ex;}
01121 } else if(ret == 0) { ;
01122
01123 {ret= -2; goto ex;}
01124 } else if(ret == 1) {
01125 goto ex;
01126 } else if(ret == 2) {
01127 ;
01128 } else if(ret == 3) {
01129 ;
01130 } else if(ret == 4) {
01131 {ret= 5; goto ex;}
01132 } else
01133 {ret= -1; goto ex;}
01134
01135 *consumed= num_data;
01136 ret= aaip_advance_pair(aaip, name, name_size, name_fill,
01137 value, value_size, value_fill, 0);
01138 if(aaip->aa_ends == 3) {
01139 if(ret >= 2 && ret <= 4)
01140 ret= 4;
01141 else
01142 ret= 5;
01143 }
01144 ex:;
01145 aaip->pair_status= ret;
01146 return(ret);
01147 }
01148
01149
01150 unsigned int aaip_get_pairs_skipped(struct aaip_state *aaip, int flag)
01151 {
01152 return(aaip->pairs_skipped);
01153 }
01154
01155
01156
01157
01158
01159 static int aaip_write_acl_line(char **result, size_t *result_size,
01160 char *tag_type, char *qualifier,
01161 char *permissions, int flag)
01162 {
01163 size_t needed, tag_len, perm_len, qualifier_len;
01164
01165 tag_len= strlen(tag_type);
01166 qualifier_len= strlen(qualifier);
01167 perm_len= strlen(permissions);
01168 needed= tag_len + qualifier_len + perm_len + 3;
01169 if((flag & 1)) {
01170 (*result_size)+= needed;
01171 return(1);
01172 }
01173 if(needed + 1 > *result_size)
01174 return(-1);
01175 memcpy((*result), tag_type, tag_len);
01176 (*result)[tag_len]= ':';
01177 memcpy((*result) + tag_len + 1, qualifier, qualifier_len);
01178 (*result)[tag_len + 1 + qualifier_len]= ':';
01179 memcpy((*result) + tag_len + 1 + qualifier_len + 1, permissions, perm_len);
01180 (*result)[tag_len + 1 + qualifier_len + 1 + perm_len]= '\n';
01181 (*result)[tag_len + 1 + qualifier_len + 1 + perm_len + 1] = 0;
01182 (*result)+= needed;
01183 (*result_size)-= needed;
01184 return(1);
01185 }
01186
01187
01188 static int aaip_read_qualifier(unsigned char *data, size_t num_data,
01189 char *name, size_t name_size, size_t *name_fill,
01190 int flag)
01191 {
01192 int is_done= 0, rec_len= 0;
01193 unsigned char *rpt;
01194
01195 *name_fill= 0;
01196 for(rpt= data; !is_done; rpt+= rec_len) {
01197 rec_len= (*rpt) & 127;
01198 is_done= !((*rpt) & 128);
01199 if(*name_fill + rec_len >= name_size || rpt + 1 + rec_len - data > num_data)
01200 return(-1);
01201 memcpy(name + *name_fill, rpt + 1, rec_len);
01202 rpt+= 1 + rec_len;
01203 (*name_fill)+= rec_len;
01204 name[*name_fill]= 0;
01205 }
01206 return(1);
01207 }
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232 int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
01233 char *acl_text, size_t acl_text_size,
01234 size_t *acl_text_fill, int flag)
01235 {
01236 unsigned char *rpt;
01237 char perm_text[4], *wpt, name[1024];
01238 int type, qualifier= 0, perm, ret, i, cnt;
01239 size_t w_size, name_fill;
01240 uid_t uid;
01241 gid_t gid;
01242 struct passwd *pwd;
01243 struct group *grp;
01244
01245 cnt= flag & 1;
01246 *consumed= 0;
01247 wpt= acl_text;
01248 w_size= acl_text_size;
01249 *acl_text_fill= 0;
01250 for(rpt= data; rpt - data < num_data; ) {
01251 perm= *rpt;
01252 strcpy(perm_text, "---");
01253 if(perm & Aaip_READ)
01254 perm_text[0]= 'r';
01255 if(perm & Aaip_WRITE)
01256 perm_text[1]= 'w';
01257 if(perm & Aaip_EXEC)
01258 perm_text[2]= 'x';
01259
01260 type= (*rpt) >> 4;
01261 if(type == Aaip_FUTURE_VERSION)
01262 return(-3);
01263
01264 qualifier= !!((*rpt) & 8);
01265 if(qualifier) {
01266 ret= aaip_read_qualifier(rpt + 1, num_data - (rpt + 1 - data),
01267 name, sizeof(name), &name_fill, 0);
01268 if(ret <= 0)
01269 return(-1);
01270 }
01271
01272
01273 (*consumed)+= 1 + (qualifier ? name_fill + 1 : 0);
01274 rpt+= 1 + (qualifier ? name_fill + 1 : 0);
01275
01276 ret= 1;
01277 if(type == Aaip_TRANSLATE) {
01278 ;
01279 continue;
01280 } else if(type == Aaip_ACL_USER_OBJ) {
01281
01282 ret= aaip_write_acl_line(&wpt, &w_size, "user", "", perm_text, cnt);
01283 } else if(type == Aaip_ACL_USER) {
01284 ;
01285 ret= aaip_write_acl_line(&wpt, &w_size, "user", name, perm_text, cnt);
01286 } else if(type == Aaip_ACL_GROUP_OBJ) {
01287
01288 ret= aaip_write_acl_line(&wpt, &w_size, "group", "", perm_text, cnt);
01289 } else if(type == Aaip_ACL_GROUP) {
01290 ;
01291 ret= aaip_write_acl_line(&wpt, &w_size, "group", name, perm_text, cnt);
01292 } else if(type == Aaip_ACL_MASK) {
01293
01294 ret= aaip_write_acl_line(&wpt, &w_size, "mask", "", perm_text, cnt);
01295 } else if(type == Aaip_ACL_OTHER) {
01296
01297 ret= aaip_write_acl_line(&wpt, &w_size, "other", "", perm_text, cnt);
01298 } else if(type == Aaip_SWITCH_MARK) {
01299
01300 if((!(perm & Aaip_EXEC)) ^ (!!(flag & 2)))
01301 return(2);
01302 } else if(type == Aaip_ACL_USER_N) {
01303
01304 uid= 0;
01305 for(i= 0; i < name_fill; i++)
01306 uid= (uid << 8) | ((unsigned char *) name)[i];
01307 pwd= getpwuid(uid);
01308 if(pwd == NULL)
01309 sprintf(name, "%.f", (double) uid);
01310 else if(strlen(pwd->pw_name) >= sizeof(name))
01311 sprintf(name, "%.f", (double) uid);
01312 else
01313 strcpy(name, pwd->pw_name);
01314 ;
01315 ret= aaip_write_acl_line(&wpt, &w_size, "user", name, perm_text, cnt);
01316 } else if(type == Aaip_ACL_GROUP_N) {
01317 ;
01318 gid= 0;
01319 for(i= 0; i < name_fill; i++)
01320 gid= (gid << 8) | ((unsigned char *) name)[i];
01321 grp= getgrgid(gid);
01322 if(grp == NULL)
01323 sprintf(name, "%.f", (double) gid);
01324 else if(strlen(grp->gr_name) >= sizeof(name))
01325 sprintf(name, "%.f", (double) gid);
01326 else
01327 strcpy(name, grp->gr_name);
01328 ;
01329 ret= aaip_write_acl_line(&wpt, &w_size, "group", name, perm_text, cnt);
01330 } else {
01331
01332 return(-4);
01333 }
01334 if(ret <= 0)
01335 return(-2);
01336 }
01337 if(flag & 1)
01338 *acl_text_fill= w_size + 1;
01339 return(1);
01340 }
01341