static acl_node* posix_acl_find(uint32_t inode,uint8_t acltype) { uint32_t h; acl_node *acn; h = HASHFN(inode,acltype); for (acn=hashtab[h] ; acn!=NULL ; acn=acn->next) { if (acn->inode == inode && acn->acltype == acltype) { return acn; } } return NULL; }
static void posix_acl_delete(uint32_t inode,uint8_t acltype) { uint32_t h; acl_node **acnp,*acn; h = HASHFN(inode,acltype); acnp = hashtab+h; while ((acn=*acnp)!=NULL) { if (acn->inode == inode && acn->acltype == acltype) { *acnp = acn->next; if (acn->acltab) { free(acn->acltab); } free(acn); } else { acnp = &(acn->next); } } }
static acl_node* posix_acl_create(uint32_t inode,uint8_t acltype) { uint32_t h; acl_node *acn; h = HASHFN(inode,acltype); acn = malloc(sizeof(acl_node)); passert(acn); acn->inode = inode; acn->acltype = acltype; acn->userperm = 0; acn->groupperm = 0; acn->otherperm = 0; acn->mask = 0; acn->namedusers = 0; acn->namedgroups = 0; acn->acltab = NULL; acn->next = hashtab[h]; hashtab[h] = acn; return acn; }
groups* groups_get_x(pid_t pid,uid_t uid,gid_t gid,uint8_t lockmode) { double t; uint32_t h; groups *g,*gn,*gf; if (debug_mode) { fprintf(stderr,"groups_get(pid=%"PRIu32",uid=%"PRIu32",gid=%"PRIu32")\n",(uint32_t)pid,(uint32_t)uid,(uint32_t)gid); } zassert(pthread_mutex_lock(&glock)); t = monotonic_seconds(); h = HASHFN(pid,uid,gid); // fprintf(stderr,"groups_get hash: %"PRIu32"\n",h); for (gf = NULL,g = groups_hashtab[h] ; g!=NULL ; g = gn) { gn = g->next; if (g->time + to < t && lockmode==0 && g->locked==0 && g->lcnt==0) { // fprintf(stderr,"groups_get remove node (%"PRIu32",%"PRIu32",%"PRIu32") insert_time: %.3lf ; current_time: %.3lf ; timeout: %.3lf\n",g->pid,g->uid,g->gid,g->time,t,to); groups_remove(g); } else { // fprintf(stderr,"groups_get check node (%"PRIu32",%"PRIu32",%"PRIu32")\n",g->pid,g->uid,g->gid); if (g->pid==pid && g->uid==uid && g->gid==gid) { gf = g; } } } g = gf; if (g) { if (debug_mode) { fprintf(stderr,"groups_get(pid=%"PRIu32",uid=%"PRIu32",gid=%"PRIu32") - found data in cache\n",(uint32_t)pid,(uint32_t)uid,(uint32_t)gid); } g->lcnt++; if (lockmode==1) { g->locked = 1; if (debug_mode) { fprintf(stderr,"groups_get(pid=%"PRIu32",uid=%"PRIu32",gid=%"PRIu32") - lock cache\n",(uint32_t)pid,(uint32_t)uid,(uint32_t)gid); } } if (g->lcnt==1 && g->locked==0 && g->uid==0) { // refresh groups for user 'root' - only root can change groups if (debug_mode) { fprintf(stderr,"groups_get(pid=%"PRIu32",uid=%"PRIu32",gid=%"PRIu32") - refresh cache\n",(uint32_t)pid,(uint32_t)uid,(uint32_t)gid); } if (g->gidtab) { free(g->gidtab); } g->gidcnt = get_groups(pid,gid,&(g->gidtab)); } if (lockmode==2) { g->locked = 0; if (debug_mode) { fprintf(stderr,"groups_get(pid=%"PRIu32",uid=%"PRIu32",gid=%"PRIu32") - unlock cache\n",(uint32_t)pid,(uint32_t)uid,(uint32_t)gid); } } } else { g = malloc(sizeof(groups)); g->time = t; g->pid = pid; g->uid = uid; g->gid = gid; g->lcnt = 1; if (lockmode==1) { // emergency case if (debug_mode) { fprintf(stderr,"groups_get(pid=%"PRIu32",uid=%"PRIu32",gid=%"PRIu32") - emergency mode\n",(uint32_t)pid,(uint32_t)uid,(uint32_t)gid); } g->gidtab = malloc(sizeof(uint32_t)); g->gidtab[0] = gid; g->gidcnt = 1; g->locked = 1; } else { g->gidcnt = get_groups(pid,gid,&(g->gidtab)); g->locked = 0; } g->next = groups_hashtab[h]; if (g->next) { g->next->prev = &(g->next); } g->prev = groups_hashtab+h; groups_hashtab[h] = g; // fprintf(stderr,"groups_get insert node (%"PRIu32",%"PRIu32",%"PRIu32")\n",g->pid,g->uid,g->gid); } zassert(pthread_mutex_unlock(&glock)); if (debug_mode) { fprintf(stderr,"groups_get(pid=%"PRIu32",uid=%"PRIu32",gid=%"PRIu32"):",(uint32_t)pid,(uint32_t)uid,(uint32_t)gid); for (h=0 ; h<g->gidcnt ; h++) { fprintf(stderr,"%c%"PRIu32,(h==0)?'(':',',g->gidtab[h]); } if (g->gidcnt==0) { fprintf(stderr,"EMPTY\n"); } else { fprintf(stderr,")\n"); } } return g; }