📄 extensions.c
字号:
return (0); } /* is it in any of the disallowed regexps */ for (j = 3; j < MAXARGS; ++j) { /* ARGj == entry->arg[j] */ if (entry->arg[j]) {#if defined(HAVE_REGEXEC) if (regcomp(®exbuf, entry->arg[j], REG_EXTENDED) != 0) { reply(550, "HAVE_REGEX error");#elif defined(HAVE_REGEX) if ((sp = regcmp(entry->arg[j], (char *) 0)) == NULL) { reply(550, "HAVE_REGEX error");#else if ((sp = re_comp(entry->arg[j])) != 0) { perror_reply(550, sp);#endif return (0); }#if defined(HAVE_REGEXEC) if (regexec(®exbuf, path, 1, ®matchbuf, 0) == 0) {#elif defined(HAVE_REGEX)#ifdef M_UNIX regp = regex(sp, path); free(sp); if (regp != NULL) {#else if ((regex(sp, path)) != NULL) {#endif#else if ((re_exec(path)) == 1) {#endif pr_mesg(550, ARG1); reply(550, "%s: Permission denied on server. (Filename (deny))", name); return (0); } } } } } return (1);}int dir_check(char *name, uid_t * uid, gid_t * gid, int *d_mode, int *valid){ struct aclmember *entry = NULL; int match_value = -1; char *ap2 = NULL; char *ap3 = NULL; char *ap4 = NULL; char *ap5 = NULL; char *ap6 = NULL; char *ap7 = NULL; char cwdir[MAXPATHLEN]; char *pwdir; char abspwdir[MAXPATHLEN]; char relpwdir[MAXPATHLEN]; char path[MAXPATHLEN]; char *sp; struct stat stbuf; int stat_result = -1; char class[1024]; extern char *home; extern char chroot_path[]; (void) acl_getclass(class); *valid = 0; /* what's our current directory? */ /* XXX We could use dynamic RAM to store this path, but I'd rather just bail out with an error. The rest of wu is so crufy that a long path might just blow up later */ if ((strlen(name) + 1) > sizeof(path)) { perror_reply(550, "Path too long"); return (-1); } strcpy(path, name); sp = strrchr(path, '/'); if (sp) *sp = '\0'; else strcpy(path, "."); if ((fb_realpath(path, cwdir)) == NULL) { perror_reply(550, "Could not determine cwdir"); return (-1); } if ((fb_realpath(home, relpwdir)) == NULL) { perror_reply(550, "Could not determine pwdir"); return (-1); } if ((wu_realpath(home, abspwdir, chroot_path)) == NULL) { perror_reply(550, "Could not determine pwdir"); return (-1); } while (getaclentry("upload", &entry)) { char *q; int i = 0; int options = 1; int classfound = 0; int classmatched = 0; pwdir = abspwdir; while (options && (i < MAXARGS) && ((q = entry->arg[i]) != (char *) NULL) && (q[0] != '\0')) { if (strcasecmp(q, "absolute") == 0) { i++; pwdir = abspwdir; } else if (strcasecmp(q, "relative") == 0) { i++; pwdir = relpwdir; } else if (strncasecmp(q, "class=", 6) == 0) { i++; classfound = 1; if (strcasecmp(q + 6, class) == 0) classmatched = 1; } else if (strcmp(q, "-") == 0) { i++; options = 0; } else options = 0; } if (!classfound || classmatched) { int j; if (((i + 1) < MAXARGS) && ((q = entry->arg[i]) != (char *) NULL) && (q[0] != '\0') && (0 < path_compare(q, pwdir)) && ((j = path_compare(entry->arg[i + 1], cwdir)) >= match_value)) { match_value = j; ap2 = NULL; if (((i + 2) < MAXARGS) && ((q = entry->arg[i + 2]) != (char *) NULL) && (q[0] != '\0')) ap2 = q; ap3 = NULL; if (((i + 3) < MAXARGS) && ((q = entry->arg[i + 3]) != (char *) NULL) && (q[0] != '\0')) ap3 = q; ap4 = NULL; if (((i + 4) < MAXARGS) && ((q = entry->arg[i + 4]) != (char *) NULL) && (q[0] != '\0')) ap4 = q; ap5 = NULL; if (((i + 5) < MAXARGS) && ((q = entry->arg[i + 5]) != (char *) NULL) && (q[0] != '\0')) ap5 = q; ap6 = NULL; if (((i + 6) < MAXARGS) && ((q = entry->arg[i + 6]) != (char *) NULL) && (q[0] != '\0')) ap6 = q; ap7 = NULL; if (((i + 7) < MAXARGS) && ((q = entry->arg[i + 7]) != (char *) NULL) && (q[0] != '\0')) ap7 = q; } } } if (anonymous && (match_value < 0)) { reply(550, "%s: Permission denied on server. (Upload dirs)", name); return (0); } if ((ap2 && !strcasecmp(ap2, "no")) || (ap3 && !strcasecmp(ap3, "nodirs")) || (ap6 && !strcasecmp(ap6, "nodirs"))) { reply(550, "%s: Permission denied on server. (Upload dirs)", name); return (0); } if ((ap3 && *ap3 == '*') || (ap4 && *ap4 == '*')) stat_result = stat(path, &stbuf); if (ap3) { if ((ap3[0] != '*') || (ap3[1] != '\0')) *uid = atoi(ap3); /* the uid */ else if (stat_result == 0) *uid = stbuf.st_uid; } if (ap4) { if ((ap4[0] != '*') || (ap4[1] != '\0')) *gid = atoi(ap4); /* the gid */ else if (stat_result == 0) *gid = stbuf.st_gid; } if (ap7) { sscanf(ap7, "%o", d_mode); *valid = 1; } else if (ap5) { sscanf(ap5, "%o", d_mode); if (*d_mode & 0600) *d_mode |= 0100; if (*d_mode & 0060) *d_mode |= 0010; if (*d_mode & 0006) *d_mode |= 0001; *valid = 1; } return (1);}int upl_check(char *name, uid_t * uid, gid_t * gid, int *f_mode, int *valid){ int match_value = -1; char cwdir[MAXPATHLEN]; char *pwdir; char abspwdir[MAXPATHLEN]; char relpwdir[MAXPATHLEN]; char path[MAXPATHLEN]; char *sp; struct stat stbuf; int stat_result = -1; char *ap2 = NULL; char *ap3 = NULL; char *ap4 = NULL; char *ap5 = NULL; struct aclmember *entry = NULL; char class[1024]; extern char *home; extern char chroot_path[]; *valid = 0; (void) acl_getclass(class); /* what's our current directory? */ /* XXX We could use dynamic RAM to store this path, but I'd rather just bail out with an error. The rest of wu is so crufy that a long path might just blow up later */ if ((strlen(name) + 1) > sizeof(path)) { perror_reply(553, "Path too long"); return (-1); } strcpy(path, name); sp = strrchr(path, '/'); if (sp) *sp = '\0'; else strcpy(path, "."); if ((fb_realpath(path, cwdir)) == NULL) { perror_reply(553, "Could not determine cwdir"); return (-1); } if ((wu_realpath(home, abspwdir, chroot_path)) == NULL) { perror_reply(553, "Could not determine pwdir"); return (-1); } if ((fb_realpath(home, relpwdir)) == NULL) { perror_reply(553, "Could not determine pwdir"); return (-1); } /* * we are doing a "best match"... ..so we keep track of what "match * value" we have received so far... */ while (getaclentry("upload", &entry)) { char *q; int i = 0; int options = 1; int classfound = 0; int classmatched = 0; pwdir = abspwdir; while (options && (i < MAXARGS) && ((q = entry->arg[i]) != (char *) NULL) && (q[0] != '\0')) { if (strcasecmp(q, "absolute") == 0) { i++; pwdir = abspwdir; } else if (strcasecmp(q, "relative") == 0) { i++; pwdir = relpwdir; } else if (strncasecmp(q, "class=", 6) == 0) { i++; classfound = 1; if (strcasecmp(q + 6, class) == 0) classmatched = 1; } else if (strcmp(q, "-") == 0) { i++; options = 0; } else options = 0; } if (!classfound || classmatched) { int j; if (((i + 1) < MAXARGS) && ((q = entry->arg[i]) != (char *) NULL) && (q[0] != '\0') && (0 < path_compare(q, pwdir)) && ((j = path_compare(entry->arg[i + 1], cwdir)) >= match_value)) { match_value = j; ap2 = NULL; if (((i + 2) < MAXARGS) && ((q = entry->arg[i + 2]) != (char *) NULL) && (q[0] != '\0')) ap2 = q; ap3 = NULL; if (((i + 3) < MAXARGS) && ((q = entry->arg[i + 3]) != (char *) NULL) && (q[0] != '\0')) ap3 = q; ap4 = NULL; if (((i + 4) < MAXARGS) && ((q = entry->arg[i + 4]) != (char *) NULL) && (q[0] != '\0')) ap4 = q; ap5 = NULL; if (((i + 5) < MAXARGS) && ((q = entry->arg[i + 5]) != (char *) NULL) && (q[0] != '\0')) ap5 = q; } } } if (ap3 && ((!strcasecmp("dirs", ap3)) || (!strcasecmp("nodirs", ap3)))) ap3 = NULL; /* * if we did get matches ... else don't do any of this stuff */ if (match_value >= 0) { if (!strcasecmp(ap2, "yes")) { if ((ap3 && *ap3 == '*') || (ap4 && *ap4 == '*')) stat_result = stat(path, &stbuf); if (ap3) { if ((ap3[0] != '*') || (ap3[1] != '\0')) *uid = atoi(ap3); /* the uid */ else if (stat_result == 0) *uid = stbuf.st_uid; } if (ap4) { if ((ap4[0] != '*') || (ap4[1] != '\0')) *gid = atoi(ap4); /* the gid */ else if (stat_result == 0) *gid = stbuf.st_gid; *valid = 1; } if (ap5) sscanf(ap5, "%o", f_mode); /* the mode */ } else { reply(553, "%s: Permission denied on server. (Upload)", name); return (-1); } } else { /* * upload defaults to "permitted" */ /* Not if anonymous */ if (anonymous) { reply(553, "%s: Permission denied on server. (Upload)", name); return (-1); } return (1); } return (match_value);}int del_check(char *name){ int pdelete = (anonymous ? 0 : 1); struct aclmember *entry = NULL; while (getaclentry("delete", &entry) && ARG0 && ARG1 != NULL) { if (type_match(ARG1)) if (anonymous) { if (*ARG0 == 'y') pdelete = 1; } else if (*ARG0 == 'n') pdelete = 0; }/* H* fix: no deletion, period. You put a file here, I get to look at it. */#ifdef PARANOID pdelete = 0;#endif if (!pdelete) { reply(553, "%s: Permission denied on server. (Delete)", name); return (0); } else { return (1); }}/* The following is from the Debian add-ons. */#define lbasename(x) (strrchr(x,'/')?1+strrchr(x,'/'):x)int regexmatch(char *name, char *rgexp){#ifdef M_UNIX#ifdef HAVE_REGEX char *regp;#endif#endif#ifdef HAVE_REGEXEC regex_t regexbuf; regmatch_t regmatchbuf;#else char *sp;#endif#if defined(HAVE_REGEXEC) if (regcomp(®exbuf, rgexp, REG_EXTENDED) != 0) { reply(553, "HAVE_REGEX error");#elif defined(HAVE_REGEX) if ((sp = regcmp(rgexp, (char *) 0)) == NULL) { reply(553, "HAVE_REGEX error");#else if ((sp = re_comp(rgexp)) != 0) { perror_reply(553, sp);#endif return (0); }#if defined(HAVE_REGEXEC) if (regexec(®exbuf, name, 1, ®matchbuf, 0) != 0) {#elif defined(HAVE_REGEX)#ifdef M_UNIX regp = regex(sp, name); free(sp); if (regp == NULL) {#else if ((regex(sp, name)) == NULL) {#endif#else if ((re_exec(name)) != 1) {#endif return (0); } return (1);}static int allow_retrieve(char *name){ char realname[MAXPATHLEN + 1]; char localname[MAXPATHLEN + 1]; char *whichname; int i; size_t len; struct aclmember *entry = NULL; char *p, *q; int options; int classfound; int classmatched; char class[1024]; extern char chroot_path[]; (void) acl_getclass(class); if ((name == (char *) NULL) || (*name == '\0')) return 0; fb_realpath(name, localname); wu_realpath(name, realname, chroot_path); while (getaclentry("allow-retrieve", &entry)) { whichname = realname; i = 0; options = 1; classfound = 0; classmatched = 0; while (options && (i < MAXARGS) && ((q = entry->arg[i]) != (char *) NULL) && (q[0] != '\0')) { if (strcasecmp(q, "absolute") == 0) { i++; whichname = realname; } else if (strcasecmp(q, "relative") == 0) { i++; whichname = localname; } else if (strncasecmp(q, "class=", 6) == 0) { i++; classfound = 1; if (strcasecmp(q + 6, class) == 0) classmatched = 1; } else if (strcmp(q, "-") == 0) { i++; options = 0; } else options = 0; } if (!classfound || classmatched) { for (; (i < MAXARGS) && ((q = entry->arg[i]) != (char *) NULL) && (q[0] != '\0'); i++) { len = strlen(q); p = (q[0] == '/') ? whichname : lbasename(whichname); if (!wu_fnmatch(q, p, FNM_PATHNAME | FNM_LEADING_DIR)) { return 1; } } } } return 0;}int checknoretrieve(char *name){ char realname[MAXPATHLEN + 1]; char localname[MAXPATHLEN + 1]; char *whichname; int i; size_t len; struct aclmember *entry = NULL; char *p, *q; int options; int classfound; int classmatched; char class[1024]; extern struct passwd *pw; extern char chroot_path[]; extern char *remoteident; (void) acl_getclass(class); if ((name == (char *) NULL) || (*name == '\0')) return 0; fb_realpath(name, localname); wu_realpath(name, realname, chroot_path); while (getaclentry("noretrieve", &entry)) { whichname = realname; i = 0; options = 1; classfound = 0; classmatched = 0; while (options && (i < MAXARGS) && ((q = entry->arg[i]) != (char *) NULL) && (q[0] != '\0')) { if (strcasecmp(q, "absolute") == 0) { i++; whichname = realname; } else if (strcasecmp(q, "relative") == 0) { i++; whichname = localname; } else if (strncasecmp(q, "class=", 6) == 0) { i++; classfound = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -