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
00035
00036 #include <sys/types.h>
00037 #include <sys/stat.h>
00038 #include <sys/mman.h>
00039 #include <unistd.h>
00040 #include <string.h>
00041 #include <dirent.h>
00042 #include <fcntl.h>
00043 #include <ctype.h>
00044 #include <strings.h>
00045
00046 #ifndef _GNU_SOURCE
00047 #define _GNU_SOURCE
00048 #include <stdio.h>
00049 #include <stdlib.h>
00050 #endif
00051 #include <fnmatch.h>
00052
00053 #include <libxml/xmlmemory.h>
00054 #include <libxml/tree.h>
00055 #include <libxml/parser.h>
00056
00057 #include "gridsite.h"
00058
00059 #ifdef SUNCC
00060
00061
00062 static char* strsep(char** str, const char* delims)
00063 {
00064 char* token;
00065 if (*str==NULL) {
00066
00067 return NULL;
00068 }
00069
00070 token=*str;
00071 while (**str!='\0') {
00072 if (strchr(delims,**str)!=NULL) {
00073 **str='\0';
00074 (*str)++;
00075 return token;
00076 }
00077 (*str)++;
00078 }
00079
00080 *str=NULL;
00081 return token;
00082 }
00083
00084 #endif
00085
00086
00087
00088
00089
00090 char *grst_perm_syms[] = { "none",
00091 "read",
00092 "exec",
00093 "list",
00094 "write",
00095 "admin",
00096 NULL };
00097
00098 GRSTgaclPerm grst_perm_vals[] = { GRST_PERM_NONE,
00099 GRST_PERM_READ,
00100 GRST_PERM_EXEC,
00101 GRST_PERM_LIST,
00102 GRST_PERM_WRITE,
00103 GRST_PERM_ADMIN,
00104 -1 };
00105
00106 int GRSTgaclInit(void)
00107 {
00108 xmlInitParser();
00109
00110 LIBXML_TEST_VERSION
00111
00112 xmlKeepBlanksDefault(0);
00113
00114 return 1;
00115 }
00116
00117
00118
00119 GRSTgaclAcl *GRSTgaclAclParse(xmlDocPtr, xmlNodePtr, GRSTgaclAcl *);
00120 GRSTgaclAcl *GRSTxacmlAclParse(xmlDocPtr, xmlNodePtr, GRSTgaclAcl *);
00121
00122
00123
00124
00125
00126 GRSTgaclCred *GRSTgaclCredCreate(char *auri_prefix, char *auri_suffix)
00127
00128
00129
00130
00131 {
00132 int i;
00133 char auri[16384];
00134 GRSTgaclCred *newcred;
00135
00136 if ((auri_prefix != NULL) && (auri_suffix == NULL))
00137 sprintf(auri,"%s",auri_prefix);
00138 else if ((auri_prefix == NULL) && (auri_suffix != NULL))
00139 sprintf(auri,"%s",auri_suffix);
00140 else if ((auri_prefix != NULL) && (auri_suffix != NULL))
00141 sprintf(auri, "%s%s", auri_prefix, auri_suffix);
00142 else return NULL;
00143
00144 for (i=0; (auri[i] != '\0') && isspace(auri[i]); ++i) ;
00145
00146 for (i=strlen(auri) - 1; (i >= 0) && isspace(auri[i]); --i)
00147 auri[i]='\0';
00148
00149 newcred = malloc(sizeof(GRSTgaclCred));
00150 if (newcred == NULL)
00151 {
00152 return NULL;
00153 }
00154
00155 newcred->auri = auri;
00156 newcred->delegation = 0;
00157 newcred->nist_loa = 0;
00158 newcred->notbefore = 0;
00159 newcred->notafter = 0;
00160 newcred->next = NULL;
00161
00162 return newcred;
00163 }
00164
00165 GRSTgaclCred *GRSTgaclCredNew(char *type)
00166
00167
00168
00169
00170 {
00171 if (type == NULL) return NULL;
00172
00173 if ((strcmp(type, "person" ) == 0) ||
00174 (strcmp(type, "voms" ) == 0) ||
00175 (strcmp(type, "dn-list") == 0) ||
00176 (strcmp(type, "dns" ) == 0) ||
00177 (strcmp(type, "level" ) == 0)) return GRSTgaclCredCreate("", NULL);
00178
00179 if (strcmp(type, "any-user") == 0)
00180 return GRSTgaclCredCreate("gacl:", "any-user");
00181
00182 if (strcmp(type, "auth-user") == 0)
00183 return GRSTgaclCredCreate("gacl:", "auth-user");
00184
00185 return NULL;
00186 }
00187
00188 int GRSTgaclCredAddValue(GRSTgaclCred *cred, char *name, char *rawvalue)
00189
00190
00191
00192 {
00193 int i;
00194 char *value, *encoded_value;
00195
00196 if ((cred == NULL) || (cred->auri == NULL)) return 0;
00197 free(cred->auri);
00198 cred->auri = NULL;
00199
00200
00201
00202 value = rawvalue;
00203 while ((*value != '\0') && isspace(*value)) ++value;
00204
00205 value = strdup(value);
00206 for (i=strlen(value) - 1; (i >= 0) && isspace(value[i]); --i) value[i]='\0';
00207
00208 encoded_value = GRSThttpUrlMildencode(value);
00209
00210 if (strcmp(name, "dn") == 0)
00211 {
00212 sprintf(cred->auri, "dn:%s", encoded_value);
00213 free(value);
00214 free(encoded_value);
00215 return 1;
00216 }
00217 else if (strcmp(name, "fqan") == 0)
00218 {
00219 sprintf(cred->auri, "fqan:%s", encoded_value);
00220 free(value);
00221 free(encoded_value);
00222 return 1;
00223 }
00224 else if (strcmp(name, "url") == 0)
00225 {
00226 sprintf(cred->auri, "%s", encoded_value);
00227 free(value);
00228 free(encoded_value);
00229 return 1;
00230 }
00231 else if (strcmp(name, "hostname") == 0)
00232 {
00233 sprintf(cred->auri, "dns:%s", encoded_value);
00234 free(value);
00235 free(encoded_value);
00236 return 1;
00237 }
00238 else if (strcmp(name, "nist-loa") == 0)
00239 {
00240 sprintf(cred->auri, "nist-loa:%s", encoded_value);
00241 free(value);
00242 free(encoded_value);
00243 return 1;
00244 }
00245
00246 free(value);
00247 free(encoded_value);
00248 return 0;
00249 }
00250
00251 int GRSTgaclCredFree(GRSTgaclCred *cred)
00252
00253
00254
00255
00256 {
00257 if (cred == NULL) return 1;
00258
00259 if (cred->auri != NULL) free(cred->auri);
00260 free(cred);
00261
00262 return 1;
00263 }
00264
00265 static int GRSTgaclCredsFree(GRSTgaclCred *firstcred)
00266
00267
00268
00269 {
00270 if (firstcred == NULL) return 0;
00271
00272 if (firstcred->next != NULL) GRSTgaclCredsFree(firstcred->next);
00273
00274 return GRSTgaclCredFree(firstcred);
00275 }
00276
00277 static int GRSTgaclCredInsert(GRSTgaclCred *firstcred, GRSTgaclCred *newcred)
00278
00279
00280
00281
00282
00283 {
00284 if (firstcred == NULL) return 0;
00285
00286 if (firstcred->next == NULL)
00287 {
00288 firstcred->next = newcred;
00289 return 1;
00290 }
00291
00292 return GRSTgaclCredInsert(firstcred->next, newcred);
00293 }
00294
00295 int GRSTgaclEntryAddCred(GRSTgaclEntry *entry, GRSTgaclCred *cred)
00296
00297
00298
00299
00300 {
00301 if (entry == NULL) return 0;
00302
00303 if (entry->firstcred == NULL)
00304 {
00305 entry->firstcred = cred;
00306 return 1;
00307 }
00308 else return GRSTgaclCredInsert(entry->firstcred, cred);
00309 }
00310
00311 static int GRSTgaclCredRemoveCred(GRSTgaclCred *firstcred, GRSTgaclCred *oldcred)
00312
00313
00314
00315
00316
00317
00318 {
00319 if (firstcred == NULL) return 0;
00320
00321 return 1;
00322 }
00323
00324 int GRSTgaclEntryDelCred(GRSTgaclEntry *entry, GRSTgaclCred *cred)
00325
00326
00327
00328
00329 {
00330 if (entry == NULL) return 0;
00331
00332 return GRSTgaclCredRemoveCred(entry->firstcred, cred);
00333 }
00334
00335 int GRSTgaclCredPrint(GRSTgaclCred *cred, FILE *fp)
00336
00337
00338
00339 {
00340 char *q;
00341
00342 if ((cred->auri != NULL) && (cred->auri[0] != '\0'))
00343 {
00344 fprintf(fp, "<cred>\n<auri>");
00345
00346 for (q=cred->auri; *q != '\0'; ++q)
00347 if (*q == '<') fputs("<", fp);
00348 else if (*q == '>') fputs(">", fp);
00349 else if (*q == '&') fputs("&" , fp);
00350 else if (*q == '\'') fputs("'", fp);
00351 else if (*q == '"') fputs(""", fp);
00352 else fputc(*q, fp);
00353
00354 fprintf(fp, "</auri>\n");
00355
00356 if (cred->nist_loa > 0)
00357 fprintf(fp, "<nist-loa>%d</nist-loa>\n", cred->nist_loa);
00358
00359 if (cred->delegation > 0)
00360 fprintf(fp, "<delegation>%d</delegation>\n", cred->delegation);
00361
00362 fprintf(fp, "</cred>\n");
00363
00364 return 1;
00365 }
00366
00367 return 0;
00368 }
00369
00370 int GRSTgaclCredCmpAuri(GRSTgaclCred *cred1, GRSTgaclCred *cred2)
00371
00372
00373
00374
00375 {
00376 if ((cred1 == NULL) && (cred2 == NULL)) return 0;
00377
00378 if (cred1 == NULL) return -1;
00379
00380 if (cred2 == NULL) return 1;
00381
00382 if ((cred1->auri == NULL) && (cred2->auri == NULL)) return 0;
00383
00384 if (cred1->auri == NULL) return -1;
00385
00386 if (cred2->auri == NULL) return 1;
00387
00388 return strcmp(cred1->auri, cred2->auri);
00389 }
00390
00391
00392
00393
00394
00395 GRSTgaclEntry *GRSTgaclEntryNew(void)
00396
00397
00398
00399
00400 {
00401 GRSTgaclEntry *newentry;
00402
00403 newentry = (GRSTgaclEntry *) malloc(sizeof(GRSTgaclEntry));
00404 if (newentry == NULL) return NULL;
00405
00406 newentry->firstcred = NULL;
00407 newentry->allowed = 0;
00408 newentry->denied = 0;
00409 newentry->next = NULL;
00410
00411 return newentry;
00412 }
00413
00414 int GRSTgaclEntryFree(GRSTgaclEntry *entry)
00415
00416
00417
00418 {
00419 if (entry == NULL) return 1;
00420
00421 GRSTgaclCredsFree(entry->firstcred);
00422
00423 free(entry);
00424
00425 return 1;
00426 }
00427
00428 static int GRSTgaclEntriesFree(GRSTgaclEntry *entry)
00429
00430
00431
00432
00433 {
00434 if (entry == NULL) return 0;
00435
00436 if (entry->next != NULL) GRSTgaclEntriesFree(entry->next);
00437
00438 return GRSTgaclEntryFree(entry);
00439 }
00440
00441 static int GRSTgaclEntryInsert(GRSTgaclEntry *firstentry, GRSTgaclEntry *newentry)
00442
00443
00444
00445
00446
00447 {
00448 if (firstentry == NULL) return 0;
00449
00450 if (firstentry->next == NULL)
00451 {
00452 firstentry->next = newentry;
00453 return 1;
00454 }
00455
00456 return GRSTgaclEntryInsert(firstentry->next, newentry);
00457 }
00458
00459 int GRSTgaclAclAddEntry(GRSTgaclAcl *acl, GRSTgaclEntry *entry)
00460
00461
00462
00463
00464 {
00465 if (acl == NULL) return 0;
00466
00467 if (acl->firstentry == NULL)
00468 {
00469 acl->firstentry = entry;
00470 return 1;
00471 }
00472 else return GRSTgaclEntryInsert(acl->firstentry, entry);
00473 }
00474
00475 int GRSTgaclEntryPrint(GRSTgaclEntry *entry, FILE *fp)
00476 {
00477 GRSTgaclCred *cred;
00478 GRSTgaclPerm i;
00479
00480 fputs("<entry>\n", fp);
00481
00482 for (cred = entry->firstcred; cred != NULL; cred = cred->next)
00483 GRSTgaclCredPrint(cred, fp);
00484
00485 if (entry->allowed)
00486 {
00487 fputs("<allow>", fp);
00488
00489 for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i)
00490 if ((entry->allowed) & i) GRSTgaclPermPrint(i, fp);
00491
00492 fputs("</allow>\n", fp);
00493 }
00494
00495
00496 if (entry->denied)
00497 {
00498 fputs("<deny>", fp);
00499
00500 for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i)
00501 if (entry->denied & i) GRSTgaclPermPrint(i, fp);
00502
00503 fputs("</deny>\n", fp);
00504 }
00505
00506 fputs("</entry>\n", fp);
00507
00508 return 1;
00509 }
00510
00511
00512
00513
00514
00515 int GRSTgaclPermPrint(GRSTgaclPerm perm, FILE *fp)
00516 {
00517 GRSTgaclPerm i;
00518
00519 for (i=GRST_PERM_READ; grst_perm_syms[i] != NULL; ++i)
00520 if (perm == grst_perm_vals[i])
00521 {
00522 fprintf(fp, "<%s/>", grst_perm_syms[i]);
00523 return 1;
00524 }
00525
00526 return 0;
00527 }
00528
00529 int GRSTgaclEntryAllowPerm(GRSTgaclEntry *entry, GRSTgaclPerm perm)
00530 {
00531 entry->allowed = entry->allowed | perm;
00532
00533 return 1;
00534 }
00535
00536 int GRSTgaclEntryUnallowPerm(GRSTgaclEntry *entry, GRSTgaclPerm perm)
00537 {
00538 entry->allowed = entry->allowed & ~perm;
00539
00540 return 1;
00541 }
00542
00543 int GRSTgaclEntryDenyPerm(GRSTgaclEntry *entry, GRSTgaclPerm perm)
00544 {
00545 entry->denied = entry->denied | perm;
00546
00547 return 1;
00548 }
00549
00550 int GRSTgaclEntryUndenyPerm(GRSTgaclEntry *entry, GRSTgaclPerm perm)
00551 {
00552 entry->denied = entry->denied & ~perm;
00553
00554 return 1;
00555 }
00556
00557 char *GRSTgaclPermToChar(GRSTgaclPerm perm)
00558
00559
00560
00561
00562 {
00563 char *p = NULL;
00564 GRSTgaclPerm i;
00565
00566 for (i=0; grst_perm_syms[i] != NULL; ++i)
00567 if (perm & grst_perm_vals[i]) p = grst_perm_syms[i];
00568
00569 return p;
00570 }
00571
00572 GRSTgaclPerm GRSTgaclPermFromChar(char *s)
00573
00574
00575
00576 {
00577 GRSTgaclPerm i;
00578
00579 for (i=0; grst_perm_syms[i] != NULL; ++i)
00580 if (strcasecmp(grst_perm_syms[i], s) == 0) return grst_perm_vals[i];
00581
00582 return -1;
00583 }
00584
00585
00586
00587
00588
00589 GRSTgaclAcl *GRSTgaclAclNew(void)
00590
00591
00592
00593
00594 {
00595 GRSTgaclAcl *newacl;
00596
00597 newacl = (GRSTgaclAcl *) malloc(sizeof(GRSTgaclAcl));
00598 if (newacl == NULL) return NULL;
00599
00600 newacl->firstentry = NULL;
00601
00602 return newacl;
00603 }
00604
00605 int GRSTgaclAclFree(GRSTgaclAcl *acl)
00606
00607
00608
00609 {
00610 if (acl == NULL) return 1;
00611
00612 GRSTgaclEntriesFree(acl->firstentry);
00613
00614 return 1;
00615 }
00616
00617 int GRSTgaclAclPrint(GRSTgaclAcl *acl, FILE *fp)
00618 {
00619 GRSTgaclEntry *entry;
00620
00621 fputs("<gacl version=\"0.9.0\">\n", fp);
00622
00623 for (entry = acl->firstentry; entry != NULL; entry = entry->next)
00624 GRSTgaclEntryPrint(entry, fp);
00625
00626 fputs("</gacl>\n", fp);
00627
00628 return 1;
00629 }
00630
00631 int GRSTgaclAclSave(GRSTgaclAcl *acl, char *filename)
00632 {
00633 int ret;
00634 FILE *fp;
00635
00636 fp = fopen(filename, "w");
00637 if (fp == NULL) return 0;
00638
00639 fputs("<?xml version=\"1.0\"?>\n", fp);
00640
00641 ret = GRSTgaclAclPrint(acl, fp);
00642
00643 fclose(fp);
00644
00645 return ret;
00646 }
00647
00648
00649
00650
00651
00652
00653
00654 static GRSTgaclCred *GRSTgaclCredParse(xmlNodePtr cur)
00655
00656
00657
00658
00659 {
00660 xmlNodePtr cur2;
00661 GRSTgaclCred *cred = NULL;
00662
00663
00664
00665 if (strcmp((char *) cur->name, "cred") == 0)
00666 {
00667 for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next)
00668 {
00669 if (!xmlIsBlankNode(cur2) &&
00670 (strcmp((char *) cur2->name, "auri") == 0))
00671 {
00672 if (cred != NULL)
00673 {
00674 GRSTgaclCredFree(cred);
00675 cred = NULL;
00676 return NULL;
00677 }
00678
00679 cred = GRSTgaclCredCreate((char *) xmlNodeGetContent(cur2),NULL);
00680 }
00681 }
00682
00683 if (cred == NULL) return NULL;
00684
00685 for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next)
00686 {
00687 if (xmlIsBlankNode(cur2)) continue;
00688
00689 if (strcmp((char *) cur2->name, "nist-loa") == 0)
00690 {
00691 cred->nist_loa = atoi((char *) xmlNodeGetContent(cur2));
00692 }
00693 else if (strcmp((char *) cur2->name, "delegation") == 0)
00694 {
00695 cred->delegation = atoi((char *) xmlNodeGetContent(cur2));
00696 }
00697 }
00698
00699 return cred;
00700 }
00701
00702
00703
00704 cred = GRSTgaclCredNew((char *) cur->name);
00705
00706 for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next)
00707 {
00708 if (!xmlIsBlankNode(cur2))
00709 GRSTgaclCredAddValue(cred, (char *) cur2->name,
00710 (char *) xmlNodeGetContent(cur2));
00711 }
00712
00713 return cred;
00714 }
00715
00716 static GRSTgaclEntry *GRSTgaclEntryParse(xmlNodePtr cur)
00717
00718
00719
00720
00721 {
00722 int i;
00723 xmlNodePtr cur2;
00724 GRSTgaclEntry *entry;
00725 GRSTgaclCred *cred;
00726
00727 if (xmlStrcmp(cur->name, (const xmlChar *) "entry") != 0) return NULL;
00728
00729 cur = cur->xmlChildrenNode;
00730
00731 entry = GRSTgaclEntryNew();
00732
00733 while (cur != NULL)
00734 {
00735 if (xmlIsBlankNode(cur))
00736 {
00737 cur=cur->next;
00738 continue;
00739 }
00740 else if (xmlStrcmp(cur->name, (const xmlChar *) "allow") == 0)
00741 {
00742 for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next)
00743 if (!xmlIsBlankNode(cur2))
00744 {
00745 for (i=0; grst_perm_syms[i] != NULL; ++i)
00746 if (xmlStrcmp(cur2->name,
00747 (const xmlChar *) grst_perm_syms[i]) == 0)
00748 GRSTgaclEntryAllowPerm(entry, grst_perm_vals[i]);
00749 }
00750 }
00751 else if (xmlStrcmp(cur->name, (const xmlChar *) "deny") == 0)
00752 {
00753 for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next)
00754 if (!xmlIsBlankNode(cur2))
00755 {
00756 for (i=0; grst_perm_syms[i] != NULL; ++i)
00757 if (xmlStrcmp(cur2->name,
00758 (const xmlChar *) grst_perm_syms[i]) == 0)
00759 GRSTgaclEntryDenyPerm(entry, grst_perm_vals[i]);
00760 }
00761 }
00762 else if ((cred = GRSTgaclCredParse(cur)) != NULL)
00763 {
00764 if (!GRSTgaclEntryAddCred(entry, cred))
00765 {
00766 GRSTgaclCredFree(cred);
00767 GRSTgaclEntryFree(entry);
00768 return NULL;
00769 }
00770 }
00771 else
00772 {
00773 GRSTgaclEntryFree(entry);
00774 return NULL;
00775 }
00776
00777 cur=cur->next;
00778 }
00779
00780 return entry;
00781 }
00782
00783 GRSTgaclAcl *GRSTgaclAclLoadFile(char *filename)
00784 {
00785 xmlDocPtr doc;
00786 xmlNodePtr cur;
00787 GRSTgaclAcl *acl=NULL;
00788
00789 GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile() starting");
00790
00791 if (filename == NULL)
00792 {
00793 GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile() cannot open a NULL filename");
00794 return NULL;
00795 }
00796
00797 doc = xmlParseFile(filename);
00798 if (doc == NULL)
00799 {
00800 GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile failed to open ACL file %s", filename);
00801 return NULL;
00802 }
00803
00804 cur = xmlDocGetRootElement(doc);
00805 if (cur == NULL)
00806 {
00807 xmlFreeDoc(doc);
00808 GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile failed to parse root of ACL file %s", filename);
00809 return NULL;
00810 }
00811
00812 if (!xmlStrcmp(cur->name, (const xmlChar *) "Policy"))
00813 {
00814 GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile parsing XACML");
00815 acl=GRSTxacmlAclParse(doc, cur, acl);
00816 }
00817 else if (!xmlStrcmp(cur->name, (const xmlChar *) "gacl"))
00818 {
00819 GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile parsing GACL");
00820 acl=GRSTgaclAclParse(doc, cur, acl);
00821 }
00822 else
00823 {
00824 xmlFreeDoc(doc);
00825 return NULL;
00826 }
00827
00828 xmlFreeDoc(doc);
00829 return acl;
00830 }
00831
00832 GRSTgaclAcl *GRSTgaclAclParse(xmlDocPtr doc, xmlNodePtr cur, GRSTgaclAcl *acl)
00833 {
00834 GRSTgaclEntry *entry;
00835
00836 cur = cur->xmlChildrenNode;
00837
00838 acl = GRSTgaclAclNew();
00839
00840 while (cur != NULL)
00841 {
00842 if (!xmlIsBlankNode(cur))
00843 {
00844 entry = GRSTgaclEntryParse(cur);
00845 if (entry == NULL)
00846 {
00847 GRSTgaclAclFree(acl);
00848
00849 return NULL;
00850 }
00851
00852 GRSTgaclAclAddEntry(acl, entry);
00853 }
00854
00855 cur=cur->next;
00856 }
00857
00858 return acl;
00859 }
00860 int GRSTgaclFileIsAcl(char *pathandfile)
00861
00862
00863 {
00864 char *filename;
00865
00866 filename = rindex(pathandfile, '/');
00867 if (filename == NULL) filename = pathandfile;
00868 else filename++;
00869
00870 return (strncmp((const char*)filename, GRST_ACL_FILE, sizeof(GRST_ACL_FILE) - 1) == 0);
00871 }
00872
00873 char *GRSTgaclFileFindAclname(char *pathandfile)
00874
00875
00876
00877 {
00878 int len;
00879 char *path, *file, *p;
00880 struct stat statbuf;
00881
00882 len = strlen(pathandfile);
00883 if (len == 0) return NULL;
00884
00885 path = malloc(len + sizeof(GRST_ACL_FILE) + 2);
00886 strcpy(path, pathandfile);
00887
00888 if ((stat(path, &statbuf) == 0) &&
00889 S_ISDIR(statbuf.st_mode) &&
00890 (path[len-1] != '/'))
00891 {
00892 strcat(path, "/");
00893 ++len;
00894 }
00895
00896 if (path[len-1] != '/')
00897 {
00898 p = rindex(pathandfile, '/');
00899 if (p != NULL)
00900 {
00901 file = &p[1];
00902 p = rindex(path, '/');
00903 sprintf(p, "/%s:%s", GRST_ACL_FILE, file);
00904
00905 if (stat(path, &statbuf) == 0) return path;
00906
00907 *p = '\0';
00908 }
00909 }
00910
00911 while (path[0] != '\0')
00912 {
00913 strcat(path, "/");
00914 strcat(path, GRST_ACL_FILE);
00915
00916 if (stat(path, &statbuf) == 0) return path;
00917
00918 p = rindex(path, '/');
00919 *p = '\0';
00920
00921 p = rindex(path, '/');
00922 if (p == NULL) break;
00923
00924 *p = '\0';
00925 }
00926
00927 free(path);
00928 return NULL;
00929 }
00930
00931 GRSTgaclAcl *GRSTgaclAclLoadforFile(char *pathandfile)
00932
00933
00934 {
00935 char *path;
00936 GRSTgaclAcl *acl;
00937
00938 path = GRSTgaclFileFindAclname(pathandfile);
00939
00940 if (path != NULL)
00941 {
00942 acl = GRSTgaclAclLoadFile(path);
00943 free(path);
00944 return acl;
00945 }
00946
00947 return NULL;
00948 }
00949
00950
00951
00952
00953
00954 GRSTgaclUser *GRSTgaclUserNew(GRSTgaclCred *cred)
00955 {
00956 GRSTgaclUser *user;
00957
00958 if (cred == NULL) return NULL;
00959
00960 user = malloc(sizeof(GRSTgaclUser));
00961
00962 if (user != NULL)
00963 {
00964 user->firstcred = cred;
00965 user->dnlists = NULL;
00966 }
00967
00968 return user;
00969 }
00970
00971 int GRSTgaclUserFree(GRSTgaclUser *user)
00972 {
00973 if (user == NULL) return 1;
00974
00975 if (user->firstcred != NULL) GRSTgaclCredsFree(user->firstcred);
00976
00977 if (user->dnlists != NULL) free(user->dnlists);
00978
00979 free(user);
00980
00981 return 1;
00982 }
00983
00984 int GRSTgaclUserAddCred(GRSTgaclUser *user, GRSTgaclCred *cred)
00985 {
00986 GRSTgaclCred *crediter;
00987
00988 if ((user == NULL) || (cred == NULL)) return 0;
00989
00990 if (user->firstcred == NULL)
00991 {
00992 user->firstcred = cred;
00993 cred->next = NULL;
00994 return 1;
00995 }
00996
00997 crediter = user->firstcred;
00998
00999 while (crediter->next != NULL) crediter = crediter->next;
01000
01001 crediter->next = cred;
01002 cred->next = NULL;
01003
01004 return 1;
01005 }
01006
01007 int GRSTgaclUserHasCred(GRSTgaclUser *user, GRSTgaclCred *cred)
01008
01009 {
01010 int nist_loa = 999;
01011 GRSTgaclCred *crediter;
01012
01013 if ((cred == NULL) || (cred->auri == NULL)) return 0;
01014
01015 if (strcmp(cred->auri, "gacl:any-user") == 0) return 1;
01016
01017 if ((user == NULL) || (user->firstcred == NULL)) return 0;
01018
01019 if (strncmp((const char*)cred->auri, "dns:", 4) == 0)
01020 {
01021 for (crediter=user->firstcred;
01022 crediter != NULL;
01023 crediter = crediter->next)
01024 if ((crediter->auri != NULL) &&
01025 (strncmp((const char*)crediter->auri, "dns:", 4) == 0))
01026 #ifdef SUNCC
01027 return (fnmatch(cred->auri, crediter->auri, 0) == 0);
01028 #else
01029 return (fnmatch(cred->auri, crediter->auri, FNM_CASEFOLD) == 0);
01030 #endif
01031
01032 return 0;
01033 }
01034
01035 if (strcmp(cred->auri, "gacl:auth-user") == 0)
01036 {
01037 for (crediter=user->firstcred;
01038 crediter != NULL;
01039 crediter = crediter->next)
01040 if ((crediter->auri != NULL) &&
01041 (strncmp((const char*)crediter->auri, "dn:", 3) == 0)) return 1;
01042
01043 return 0;
01044 }
01045
01046 if (sscanf(cred->auri, "nist-loa:%d", &nist_loa) == 1)
01047 {
01048 for (crediter=user->firstcred;
01049 crediter != NULL;
01050 crediter = crediter->next)
01051 if ((crediter->auri != NULL) &&
01052 (strncmp((const char*)crediter->auri, "dn:", 3) == 0) &&
01053 (crediter->nist_loa >= nist_loa)) return 1;
01054
01055 return 0;
01056 }
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068 for (crediter=user->firstcred; crediter != NULL; crediter = crediter->next)
01069 if ((crediter->auri != NULL) &&
01070 (strcmp(crediter->auri, cred->auri) == 0)) return 1;
01071
01072 return 0;
01073 }
01074
01075 GRSTgaclCred *GRSTgaclUserFindCredtype(GRSTgaclUser *user, char *type)
01076
01077 {
01078 GRSTgaclCred *cred;
01079
01080 if (user == NULL) return NULL;
01081
01082 cred = user->firstcred;
01083
01084 while (cred != NULL)
01085 {
01086 if ((strcmp(type, "person") == 0) &&
01087 (strncmp((const char*)cred->auri, "dn:", 3) == 0)) return cred;
01088
01089 if ((strcmp(type, "voms") == 0) &&
01090 (strncmp((const char*)cred->auri, "fqan:", 5) == 0)) return cred;
01091
01092 if ((strcmp(type, "dns") == 0) &&
01093 (strncmp((const char*)cred->auri, "dns:", 4) == 0)) return cred;
01094
01095 if ((strcmp(type, "dn-list") == 0) &&
01096 ((strncmp((const char*)cred->auri, "http:", 5) == 0) ||
01097 (strncmp((const char*)cred->auri, "https:", 6) == 0))) return cred;
01098
01099 cred = cred->next;
01100 }
01101
01102 return NULL;
01103 }
01104
01105 int GRSTgaclUserSetDNlists(GRSTgaclUser *user, char *dnlists)
01106 {
01107 if (user->dnlists != NULL) free(user->dnlists);
01108
01109 if (dnlists == NULL) user->dnlists = NULL;
01110 else user->dnlists = strdup(dnlists);
01111
01112 return GRSTgaclUserLoadDNlists(user, dnlists);
01113 }
01114
01115 static void recurse4dnlists(GRSTgaclUser *user, char *dir,
01116 int recurse_level, GRSTgaclCred *dn_cred)
01117
01118
01119 {
01120 int fd, linestart, i;
01121 char *mapped, *s;
01122 char fullfilename[16384];
01123 size_t dn_len;
01124 struct stat statbuf;
01125 DIR *dirDIR;
01126 struct dirent *file_ent;
01127 GRSTgaclCred *cred;
01128
01129 if (recurse_level >= GRST_RECURS_LIMIT) return;
01130
01131 dn_len = strlen(dn_cred->auri) - 3;
01132
01133
01134
01135 dirDIR = opendir(dir);
01136
01137 if (dirDIR == NULL) return;
01138
01139 while ((file_ent = readdir(dirDIR)) != NULL)
01140 {
01141 if (file_ent->d_name[0] == '.') continue;
01142
01143 sprintf(fullfilename, "%s/%s", dir, file_ent->d_name);
01144
01145 GRSTerrorLog(GRST_LOG_DEBUG, "recurse4dnlists opens %s", fullfilename);
01146
01147 if ((fd = open(fullfilename, O_RDONLY)) < 0)
01148 ;
01149 else if (fstat(fd, &statbuf) != 0)
01150 ;
01151 else if (S_ISDIR(statbuf.st_mode))
01152 recurse4dnlists(user, fullfilename, recurse_level + 1, dn_cred);
01153 else if ((S_ISREG(statbuf.st_mode) || S_ISLNK(statbuf.st_mode)) &&
01154 ((mapped = mmap(NULL, statbuf.st_size,
01155 PROT_READ, MAP_PRIVATE, fd, 0)) != MAP_FAILED))
01156 {
01157 linestart = 0;
01158
01159 while (linestart + dn_len <= statbuf.st_size)
01160 {
01161 GRSTerrorLog(GRST_LOG_DEBUG, "recurse4dnlists at %ld in %s",
01162 linestart, fullfilename);
01163
01164 for (i=0;
01165 (linestart + i < statbuf.st_size) && (i < dn_len);
01166 ++i)
01167 if (mapped[linestart + i] != dn_cred->auri[3+i]) break;
01168
01169 GRSTerrorLog(GRST_LOG_DEBUG, "recurse4dnlists at %d %d %d %d",
01170 linestart, i, dn_len, statbuf.st_size);
01171
01172 if ((i == dn_len) &&
01173 ((linestart+i == statbuf.st_size) ||
01174 (mapped[linestart+i] == '\n') ||
01175 (mapped[linestart+i] == '\r')))
01176 {
01177 s = GRSThttpUrlDecode(file_ent->d_name);
01178 cred = GRSTgaclCredCreate(s, NULL);
01179 GRSTerrorLog(GRST_LOG_DEBUG,
01180 "recurse4dnlists adds %s", s);
01181 free(s);
01182
01183 GRSTgaclCredSetNotBefore(cred, dn_cred->notbefore);
01184 GRSTgaclCredSetNotAfter(cred, dn_cred->notafter);
01185 GRSTgaclCredSetDelegation(cred, dn_cred->delegation);
01186 GRSTgaclCredSetNistLoa(cred, dn_cred->nist_loa);
01187
01188 GRSTgaclUserAddCred(user, cred);
01189 break;
01190 }
01191
01192 linestart += i;
01193
01194 while ((linestart < statbuf.st_size) &&
01195 (mapped[linestart] != '\n') &&
01196 (mapped[linestart] != '\r')) ++linestart;
01197
01198 while ((linestart < statbuf.st_size) &&
01199 ((mapped[linestart] == '\n') ||
01200 (mapped[linestart] == '\r'))) ++linestart;
01201 }
01202
01203 munmap(mapped, statbuf.st_size);
01204 }
01205
01206 if (fd < 0) close(fd);
01207 }
01208
01209 closedir(dirDIR);
01210 }
01211
01212 int GRSTgaclUserLoadDNlists(GRSTgaclUser *user, char *dnlists)
01213
01214
01215
01216
01217 {
01218 char *dn_lists_dirs, *dn_list_ptr, *dirname;
01219 GRSTgaclCred *dn_cred;
01220
01221
01222
01223 if (dnlists == NULL) dnlists = getenv("GRST_DN_LISTS");
01224
01225 if (dnlists == NULL) dnlists = GRST_DN_LISTS;
01226
01227 if (*dnlists == '\0') return 1;
01228
01229
01230
01231 if (user == NULL) return 1;
01232
01233 for (dn_cred = user->firstcred; dn_cred != NULL; dn_cred = dn_cred->next)
01234 {
01235 if (strncmp((const char*)dn_cred->auri, "dn:", 3) == 0) break;
01236 }
01237
01238 if (dn_cred == NULL) return 1;
01239
01240
01241
01242 dn_lists_dirs = strdup(dnlists);
01243 dn_list_ptr = dn_lists_dirs;
01244
01245 while ((dirname = strsep(&dn_list_ptr, ":")) != NULL)
01246 {
01247 recurse4dnlists(user, dirname, 0, dn_cred);
01248 }
01249
01250 free(dn_lists_dirs);
01251 return 1;
01252 }
01253
01254
01255
01256
01257
01258 #if 0
01259 static char *recurse4file(char *dir, char *file, int recurse_level)
01260
01261
01262 {
01263 char fullfilename[16384], fulldirname[16384];
01264 struct stat statbuf;
01265 DIR *dirDIR;
01266 struct dirent *file_ent;
01267
01268
01269
01270 sprintf(fullfilename, "%s/%s", dir, file);
01271 if (stat(fullfilename, &statbuf) == 0) return fullfilename;
01272
01273
01274
01275 if (recurse_level >= GRST_RECURS_LIMIT) return NULL;
01276
01277 dirDIR = opendir(dir);
01278
01279 if (dirDIR == NULL) return NULL;
01280
01281 while ((file_ent = readdir(dirDIR)) != NULL)
01282 {
01283 if (file_ent->d_name[0] == '.') continue;
01284
01285 sprintf(fulldirname, "%s/%s", dir, file_ent->d_name);
01286
01287 if ((stat(fulldirname, &statbuf) == 0) &&
01288 S_ISDIR(statbuf.st_mode) &&
01289 ((fullfilename = recurse4file(fulldirname, file,
01290 recurse_level + 1)) != NULL))
01291 {
01292 closedir(dirDIR);
01293 return fullfilename;
01294 }
01295
01296 }
01297
01298 closedir(dirDIR);
01299
01300 return NULL;
01301 }
01302 #endif
01303
01304 int GRSTgaclDNlistHasUser(char *listurl, GRSTgaclUser *user)
01305 {
01306 return GRSTgaclUserHasAURI(user, listurl);
01307 }
01308
01309 int GRSTgaclUserHasAURI(GRSTgaclUser *user, char *auri)
01310 {
01311 GRSTgaclCred *cred;
01312
01313 if ((auri == NULL) || (user == NULL)) return 0;
01314
01315 for (cred = user->firstcred; cred != NULL; cred = cred->next)
01316 {
01317 if (strcmp(auri, cred->auri) == 0) return 1;
01318 }
01319
01320 return 0;
01321 }
01322
01323 GRSTgaclPerm GRSTgaclAclTestUser(GRSTgaclAcl *acl, GRSTgaclUser *user)
01324
01325
01326
01327
01328
01329 {
01330 int flag, onlyanyuser;
01331 GRSTgaclPerm allowperms = 0, denyperms = 0, allowed;
01332 GRSTgaclEntry *entry;
01333 GRSTgaclCred *cred;
01334
01335 if (acl == NULL) return 0;
01336
01337 for (entry = acl->firstentry; entry != NULL; entry = entry->next)
01338 {
01339 flag = 1;
01340 onlyanyuser = 1;
01341
01342
01343
01344 for (cred = entry->firstcred; cred != NULL; cred = cred->next)
01345 if (!GRSTgaclUserHasCred(user, cred)) flag = 0;
01346 else if (strcmp(cred->auri, "gacl:any-user") != 0) onlyanyuser = 0;
01347
01348 if (!flag) continue;
01349
01350
01351
01352
01353
01354 allowed = entry->allowed;
01355
01356 if (onlyanyuser)
01357 allowed = entry->allowed & ~GRST_PERM_WRITE & ~GRST_PERM_ADMIN;
01358 else allowed = entry->allowed;
01359
01360 allowperms = allowperms | allowed;
01361 denyperms = denyperms | entry->denied;
01362 }
01363
01364 return (allowperms & (~ denyperms));
01365
01366 }
01367
01368 GRSTgaclPerm GRSTgaclAclTestexclUser(GRSTgaclAcl *acl, GRSTgaclUser *user)
01369
01370
01371
01372
01373
01374
01375 {
01376 int flag;
01377 GRSTgaclPerm perm = 0;
01378 GRSTgaclEntry *entry;
01379 GRSTgaclCred *cred;
01380
01381 if (acl == NULL) return 0;
01382
01383 for (entry = acl->firstentry; entry != NULL; entry = entry->next)
01384 {
01385 flag = 0;
01386
01387 for (cred = entry->firstcred; cred != NULL; cred = cred->next)
01388 {
01389 if (strncmp((const char*)cred->auri, "dn:", 3) != 0)
01390
01391
01392 {
01393 flag = 1;
01394 break;
01395 }
01396
01397 if (!GRSTgaclUserHasCred(user, cred))
01398
01399
01400 {
01401 flag = 1;
01402 break;
01403 }
01404 }
01405
01406 if (flag) perm = perm | entry->allowed;
01407 }
01408
01409 return perm;
01410 }
01411
01412
01413
01414
01415
01416 GRSTgaclEntry *GACLparseEntry(xmlNodePtr cur)
01417 {
01418 return GRSTgaclEntryParse(cur);
01419 }