00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef lint
00035 #if 0
00036 static char sccsid[] = "@(#)sel_subs.c 8.1 (Berkeley) 5/31/93";
00037 #endif
00038 #endif
00039
00040 #include <sys/types.h>
00041 #include <sys/time.h>
00042 #include <sys/stat.h>
00043 #include <pwd.h>
00044 #include <time.h>
00045 #include <grp.h>
00046 #include <stdio.h>
00047 #include <string.h>
00048 #include <strings.h>
00049 #include <unistd.h>
00050 #include <stdlib.h>
00051 #include "pax.h"
00052 #include "sel_subs.h"
00053 #include "extern.h"
00054
00055 static int str_sec(char *, time_t *);
00056 static int usr_match(ARCHD *);
00057 static int grp_match(ARCHD *);
00058 static int trng_match(ARCHD *);
00059
00060 static TIME_RNG *trhead = NULL;
00061 static TIME_RNG *trtail = NULL;
00062 static USRT **usrtb = NULL;
00063 static GRPT **grptb = NULL;
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 int
00077 sel_chk(ARCHD *arcn)
00078 {
00079 if (((usrtb != NULL) && usr_match(arcn)) ||
00080 ((grptb != NULL) && grp_match(arcn)) ||
00081 ((trhead != NULL) && trng_match(arcn)))
00082 return(1);
00083 return(0);
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 int
00102 usr_add(char *str)
00103 {
00104 u_int indx;
00105 USRT *pt;
00106 struct passwd *pw;
00107 uid_t uid;
00108
00109
00110
00111
00112 if ((str == NULL) || (*str == '\0'))
00113 return(-1);
00114 if ((usrtb == NULL) &&
00115 ((usrtb = (USRT **)calloc(USR_TB_SZ, sizeof(USRT *))) == NULL)) {
00116 paxwarn(1, "Unable to allocate memory for user selection table");
00117 return(-1);
00118 }
00119
00120
00121
00122
00123 if (str[0] != '#') {
00124
00125
00126
00127 if ((str[0] == '\\') && (str[1] == '#'))
00128 ++str;
00129 if ((pw = getpwnam(str)) == NULL) {
00130 paxwarn(1, "Unable to find uid for user: %s", str);
00131 return(-1);
00132 }
00133 uid = (uid_t)pw->pw_uid;
00134 } else
00135 # ifdef NET2_STAT
00136 uid = (uid_t)atoi(str+1);
00137 # else
00138 uid = (uid_t)strtoul(str+1, NULL, 10);
00139 # endif
00140 endpwent();
00141
00142
00143
00144
00145 indx = ((unsigned)uid) % USR_TB_SZ;
00146 if ((pt = usrtb[indx]) != NULL) {
00147 while (pt != NULL) {
00148 if (pt->uid == uid)
00149 return(0);
00150 pt = pt->fow;
00151 }
00152 }
00153
00154
00155
00156
00157 if ((pt = (USRT *)malloc(sizeof(USRT))) != NULL) {
00158 pt->uid = uid;
00159 pt->fow = usrtb[indx];
00160 usrtb[indx] = pt;
00161 return(0);
00162 }
00163 paxwarn(1, "User selection table out of memory");
00164 return(-1);
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174 static int
00175 usr_match(ARCHD *arcn)
00176 {
00177 USRT *pt;
00178
00179
00180
00181
00182 pt = usrtb[((unsigned)arcn->sb.st_uid) % USR_TB_SZ];
00183 while (pt != NULL) {
00184 if (pt->uid == arcn->sb.st_uid)
00185 return(0);
00186 pt = pt->fow;
00187 }
00188
00189
00190
00191
00192 return(1);
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202 int
00203 grp_add(char *str)
00204 {
00205 u_int indx;
00206 GRPT *pt;
00207 struct group *gr;
00208 gid_t gid;
00209
00210
00211
00212
00213 if ((str == NULL) || (*str == '\0'))
00214 return(-1);
00215 if ((grptb == NULL) &&
00216 ((grptb = (GRPT **)calloc(GRP_TB_SZ, sizeof(GRPT *))) == NULL)) {
00217 paxwarn(1, "Unable to allocate memory fo group selection table");
00218 return(-1);
00219 }
00220
00221
00222
00223
00224 if (str[0] != '#') {
00225
00226
00227
00228 if ((str[0] == '\\') && (str[1] == '#'))
00229 ++str;
00230 if ((gr = getgrnam(str)) == NULL) {
00231 paxwarn(1,"Cannot determine gid for group name: %s", str);
00232 return(-1);
00233 }
00234 gid = gr->gr_gid;
00235 } else
00236 # ifdef NET2_STAT
00237 gid = (gid_t)atoi(str+1);
00238 # else
00239 gid = (gid_t)strtoul(str+1, NULL, 10);
00240 # endif
00241 endgrent();
00242
00243
00244
00245
00246 indx = ((unsigned)gid) % GRP_TB_SZ;
00247 if ((pt = grptb[indx]) != NULL) {
00248 while (pt != NULL) {
00249 if (pt->gid == gid)
00250 return(0);
00251 pt = pt->fow;
00252 }
00253 }
00254
00255
00256
00257
00258 if ((pt = (GRPT *)malloc(sizeof(GRPT))) != NULL) {
00259 pt->gid = gid;
00260 pt->fow = grptb[indx];
00261 grptb[indx] = pt;
00262 return(0);
00263 }
00264 paxwarn(1, "Group selection table out of memory");
00265 return(-1);
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275 static int
00276 grp_match(ARCHD *arcn)
00277 {
00278 GRPT *pt;
00279
00280
00281
00282
00283 pt = grptb[((unsigned)arcn->sb.st_gid) % GRP_TB_SZ];
00284 while (pt != NULL) {
00285 if (pt->gid == arcn->sb.st_gid)
00286 return(0);
00287 pt = pt->fow;
00288 }
00289
00290
00291
00292
00293 return(1);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 int
00326 trng_add(char *str)
00327 {
00328 TIME_RNG *pt;
00329 char *up_pt = NULL;
00330 char *stpt;
00331 char *flgpt;
00332 int dot = 0;
00333
00334
00335
00336
00337 if ((str == NULL) || (*str == '\0')) {
00338 paxwarn(1, "Empty time range string");
00339 return(-1);
00340 }
00341
00342
00343
00344
00345 if ((flgpt = strrchr(str, '/')) != NULL)
00346 *flgpt++ = '\0';
00347
00348 for (stpt = str; *stpt != '\0'; ++stpt) {
00349 if ((*stpt >= '0') && (*stpt <= '9'))
00350 continue;
00351 if ((*stpt == ',') && (up_pt == NULL)) {
00352 *stpt = '\0';
00353 up_pt = stpt + 1;
00354 dot = 0;
00355 continue;
00356 }
00357
00358
00359
00360
00361 if ((*stpt == '.') && (!dot)) {
00362 ++dot;
00363 continue;
00364 }
00365 paxwarn(1, "Improperly specified time range: %s", str);
00366 goto out;
00367 }
00368
00369
00370
00371
00372 if ((pt = (TIME_RNG *)malloc(sizeof(TIME_RNG))) == NULL) {
00373 paxwarn(1, "Unable to allocate memory for time range");
00374 return(-1);
00375 }
00376
00377
00378
00379
00380
00381 if ((flgpt == NULL) || (*flgpt == '\0'))
00382 pt->flgs = CMPMTME;
00383 else {
00384 pt->flgs = 0;
00385 while (*flgpt != '\0') {
00386 switch(*flgpt) {
00387 case 'M':
00388 case 'm':
00389 pt->flgs |= CMPMTME;
00390 break;
00391 case 'C':
00392 case 'c':
00393 pt->flgs |= CMPCTME;
00394 break;
00395 default:
00396 paxwarn(1, "Bad option %c with time range %s",
00397 *flgpt, str);
00398 goto out;
00399 }
00400 ++flgpt;
00401 }
00402 }
00403
00404
00405
00406
00407 pt->low_time = pt->high_time = time(NULL);
00408 if (*str != '\0') {
00409
00410
00411
00412 if (str_sec(str, &(pt->low_time)) < 0) {
00413 paxwarn(1, "Illegal lower time range %s", str);
00414 (void)free((char *)pt);
00415 goto out;
00416 }
00417 pt->flgs |= HASLOW;
00418 }
00419
00420 if ((up_pt != NULL) && (*up_pt != '\0')) {
00421
00422
00423
00424 if (str_sec(up_pt, &(pt->high_time)) < 0) {
00425 paxwarn(1, "Illegal upper time range %s", up_pt);
00426 (void)free((char *)pt);
00427 goto out;
00428 }
00429 pt->flgs |= HASHIGH;
00430
00431
00432
00433
00434 if (pt->flgs & HASLOW) {
00435 if (pt->low_time > pt->high_time) {
00436 paxwarn(1, "Upper %s and lower %s time overlap",
00437 up_pt, str);
00438 (void)free((char *)pt);
00439 return(-1);
00440 }
00441 }
00442 }
00443
00444 pt->fow = NULL;
00445 if (trhead == NULL) {
00446 trtail = trhead = pt;
00447 return(0);
00448 }
00449 trtail->fow = pt;
00450 trtail = pt;
00451 return(0);
00452
00453 out:
00454 paxwarn(1, "Time range format is: [yy[mm[dd[hh]]]]mm[.ss][/[c][m]]");
00455 return(-1);
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465 static int
00466 trng_match(ARCHD *arcn)
00467 {
00468 TIME_RNG *pt;
00469
00470
00471
00472
00473
00474 pt = trhead;
00475 while (pt != NULL) {
00476 switch(pt->flgs & CMPBOTH) {
00477 case CMPBOTH:
00478
00479
00480
00481
00482 if (((pt->flgs & HASLOW) &&
00483 (arcn->sb.st_mtime < pt->low_time) &&
00484 (arcn->sb.st_ctime < pt->low_time)) ||
00485 ((pt->flgs & HASHIGH) &&
00486 (arcn->sb.st_mtime > pt->high_time) &&
00487 (arcn->sb.st_ctime > pt->high_time))) {
00488 pt = pt->fow;
00489 continue;
00490 }
00491 break;
00492 case CMPCTME:
00493
00494
00495
00496 if (((pt->flgs & HASLOW) &&
00497 (arcn->sb.st_ctime < pt->low_time)) ||
00498 ((pt->flgs & HASHIGH) &&
00499 (arcn->sb.st_ctime > pt->high_time))) {
00500 pt = pt->fow;
00501 continue;
00502 }
00503 break;
00504 case CMPMTME:
00505 default:
00506
00507
00508
00509 if (((pt->flgs & HASLOW) &&
00510 (arcn->sb.st_mtime < pt->low_time)) ||
00511 ((pt->flgs & HASHIGH) &&
00512 (arcn->sb.st_mtime > pt->high_time))) {
00513 pt = pt->fow;
00514 continue;
00515 }
00516 break;
00517 }
00518 break;
00519 }
00520
00521 if (pt == NULL)
00522 return(1);
00523 return(0);
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 static int
00535 str_sec(char *str, time_t *tval)
00536 {
00537 struct tm *lt;
00538 char *dot = NULL;
00539
00540 lt = localtime(tval);
00541 if ((dot = strchr(str, '.')) != NULL) {
00542
00543
00544
00545 *dot++ = '\0';
00546 if (strlen(dot) != 2)
00547 return(-1);
00548 if ((lt->tm_sec = ATOI2(dot)) > 61)
00549 return(-1);
00550 } else
00551 lt->tm_sec = 0;
00552
00553 switch (strlen(str)) {
00554 case 10:
00555
00556
00557
00558
00559 if ((lt->tm_year = ATOI2(str)) < 69)
00560 lt->tm_year += 100;
00561 str += 2;
00562
00563 case 8:
00564
00565
00566
00567
00568 if ((lt->tm_mon = ATOI2(str)) > 12)
00569 return(-1);
00570 --lt->tm_mon;
00571 str += 2;
00572
00573 case 6:
00574
00575
00576
00577 if ((lt->tm_mday = ATOI2(str)) > 31)
00578 return(-1);
00579 str += 2;
00580
00581 case 4:
00582
00583
00584
00585 if ((lt->tm_hour = ATOI2(str)) > 23)
00586 return(-1);
00587 str += 2;
00588
00589 case 2:
00590
00591
00592
00593 if ((lt->tm_min = ATOI2(str)) > 59)
00594 return(-1);
00595 break;
00596 default:
00597 return(-1);
00598 }
00599
00600
00601
00602 if ((*tval = mktime(lt)) == -1)
00603 return(-1);
00604 return(0);
00605 }