📄 attr_fn_acl.c
字号:
/* no array_strings control structure, make one */ i = newpas->as_npointers; pas = (struct array_strings *)malloc((i-1) * sizeof (char *) + sizeof(struct array_strings)); if ( !pas ) return (PBSE_SYSTEM); pas->as_npointers = i; pas->as_usedptr = 0; pas->as_bufsize = 0; pas->as_buf = (char *)0; pas->as_next = (char *)0; attr->at_val.at_arst = pas; } /* * At this point we know we have a array_strings struct initialized */ switch (op) { case SET: /* * Replace old array of strings with new array, this is * simply done by deleting old strings and adding the * new strings one at a time via Incr */ for (i=0; i< pas->as_usedptr; i++) pas->as_string[i] = (char *)0; /* clear all pointers */ pas->as_usedptr = 0; pas->as_next = pas->as_buf; if (newpas->as_usedptr == 0) break; /* none to set */ nsize = newpas->as_next - newpas->as_buf; /* space needed */ if ( nsize > pas->as_bufsize) { /* new won't fit */ if (pas->as_buf) free(pas->as_buf); nsize += nsize / 2; /* alloc extra space */ if ( !(pas->as_buf = malloc(nsize)) ) { pas->as_bufsize = 0; return (PBSE_SYSTEM); } pas->as_bufsize = nsize; } else { /* str does fit, clear buf */ (void)memset(pas->as_buf, 0, pas->as_bufsize); } pas->as_next = pas->as_buf; /* No break, "Set" falls into "Incr" to add strings */ case INCR: /* check for duplicates within new and between new and old */ if (chk_dup_acl(pas, newpas)) return (PBSE_DUPLIST); nsize = newpas->as_next - newpas->as_buf; /* space needed */ used = pas->as_next - pas->as_buf; /* space used */ if (nsize > (pas->as_bufsize - used)) { /* need to make more room for sub-strings */ need = pas->as_bufsize + 2 * nsize; /* alloc new buf */ if (pas->as_buf) pc = realloc(pas->as_buf, need); else pc = malloc(need); if (pc == (char *)0) return (PBSE_SYSTEM); offset = pc - pas->as_buf; pas->as_buf = pc; pas->as_next = pc + used; pas->as_bufsize = need; for (j=0; j<pas->as_usedptr; j++) /* adjust points */ pas->as_string[j] += offset; } j = pas->as_usedptr + newpas->as_usedptr; if (j > pas->as_npointers) { /* need more pointers */ j = 3 * j / 2; /* allocate extra */ need = sizeof(struct array_strings) + (j-1)*sizeof(char *); tmppas=(struct array_strings *)realloc((char *)pas,need); if (tmppas == (struct array_strings *)0) return (PBSE_SYSTEM); tmppas->as_npointers = j; pas = tmppas; attr->at_val.at_arst = pas; } /* now put in new strings in special ugacl sorted order */ for (i=0; i<newpas->as_usedptr; i++) { for (j=0; j<pas->as_usedptr; j++) { if (order_func(pas->as_string[j],newpas->as_string[i]) >0) break; } /* push up rest of old strings to make room for new */ offset = strlen(newpas->as_string[i]) + 1; if (j < pas->as_usedptr) { where = pas->as_string[j]; /* where to put in new */ pc = pas->as_next - 1; while (pc >= pas->as_string[j]) { /* shift data up */ *(pc + offset) = *pc; pc--; } for (k=pas->as_usedptr; k>j; k--) /* re adjust pointrs */ pas->as_string[k] = pas->as_string[k-1]+offset; } else { where = pas->as_next; } (void)strcpy(where, newpas->as_string[i]); pas->as_string[j] = where; pas->as_usedptr++; pas->as_next += offset; } break; case DECR: /* decrement (remove) string from array */ for (j=0; j<newpas->as_usedptr; j++) { for (i=0; i<pas->as_usedptr; i++) { if (!strcmp(pas->as_string[i], newpas->as_string[j])) { /* compact buffer */ nsize = strlen(pas->as_string[i]) + 1; pc = pas->as_string[i] + nsize; need = pas->as_next - pc; (void)memcpy(pas->as_string[i], pc, (int)need); pas->as_next -= nsize; /* compact pointers */ for ( ++i; i < pas->as_npointers; i++) pas->as_string[i-1] = pas->as_string[i] - nsize; pas->as_string[i-1] = (char *)0; pas->as_usedptr--; break; } } } break; default: return (PBSE_INTERNAL); } attr->at_flags |= ATR_VFLAG_SET | ATR_VFLAG_MODIFY; return (0);}/* * user_match - User order match * Match two strings by user, then from the tail end first * * Canidate string (first parameter) is a single user@host string. * * Master string (2nd parameter) is an entry from a user/group acl. * It should have a leading + or - which is ignored. Next is the user name * which is compared first. If the user name matches, then the host name is * checked. The host name may be a wild carded or null (including no '@'). * If the hostname is null, it is treated the same as "@*", a fully wild * carded hostname that matches anything. * * Returns 0 if strings match, 1 if not - to match strcmp() */static int user_match(can, master) const char *can; const char *master;{ /* match user name first */ do { if (*master != *can) return (1); /* doesn't match */ master++; can++; } while ((*master != '@') && (*master != '\0')); if (*master == '\0') { /* if full match or if master has no host (=wildcard) */ if ((*can == '\0') || (*can == '@')) return (0); else return (1); } else if (*can != '@') return (1); /* ok, now compare host/domain name working backwards */ /* if hit wild card in master ok to stop and report match */ return (hacl_match(can+1, master+1));}/* * user_order - user order compare * compare: * (1) the user names, if they are equal, then * (2) two host entrys from the tail end first * * Returns -1 if entry s1 sorts before s2 * 0 if equal * 1 if s1 sorts after s2 */static int user_order(s1, s2) char *s1; char *s2;{ int d; /* skip over the + or - prefix */ if ((*s1 == '+') || (*s1 == '-')) s1++; if ((*s2 == '+') || (*s2 == '-')) s2++; /* compare user names first, stop with '@' */ while (1) { if (d = (int)*s1 - (int)*s2) return (d); if ((*s1 == '@') || (*s1 == '\0')) return (host_order(s1+1, s2+1)); /* order host names */ s1++; s2++; }}/* * host acl order match - match two strings from the tail end first * * Master string (2nd parameter) is an entry from a host acl. It may have a * leading + or - which is ignored. It may also have an '*' as a leading * name segment to be a wild card - match anything. * * Strings match if identical, or if match up to leading '*' on master which * like a wild card, matches any prefix string on canidate domain name * * Returns 0 if strings match, 1 if not - to match strcmp() */static int hacl_match(can, master) const char *can; const char *master;{ const char *pc; const char *pm; pc = can + strlen(can) - 1; pm = master + strlen(master) - 1; while ((pc > can) && (pm > master)) { if (tolower(*pc) != tolower(*pm)) return (1); pc--; pm--; } /* comparison of one or both reached the start of the string */ if (pm == master) { if (*pm == '*') return (0); else if ((pc == can) && (tolower(*pc) == tolower(*pm))) return (0); } return (1);}/* * host reverse order compare - compare two host entrys from the tail end first * domain name segment at at time. * * Returns -1 if entry s1 sorts before s2 * 0 if equal * 1 if s1 sorts after s2 */static int host_order(s1, s2) char *s1; char *s2;{ int d; char *p1; char *p2; if ((*s1 == '+') || (*s1 == '-')) s1++; if ((*s2 == '+') || (*s2 == '-')) s2++; p1 = s1 + strlen(s1) - 1; p2 = s2 + strlen(s2) - 1; while (1) { d = (int)*p2 - (int)*p1; if ((p1 > s1) && (p2 > s2)) { if (d != 0) return (d); else { p1--; p2--; } } else if ((p1 == s1) && (p2 == s2)) { if (*p1 == '*') return (1); else if (*p2 == '*') return (-1); else return (d); } else if (p1 == s1) { return (1); } else { return (-1); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -