int maSetHttpGroup(MaAppweb *appweb, cchar *newGroup) { #if BLD_UNIX_LIKE struct group *gp; if (snumber(newGroup)) { appweb->gid = atoi(newGroup); if ((gp = getgrgid(appweb->gid)) == 0) { mprError("Bad group id: %d", appweb->gid); return MPR_ERR_CANT_ACCESS; } newGroup = gp->gr_name; } else { if ((gp = getgrnam(newGroup)) == 0) { mprError("Bad group name: %s", newGroup); return MPR_ERR_CANT_ACCESS; } appweb->gid = gp->gr_gid; } appweb->groupChanged = 1; #endif appweb->group = sclone(newGroup); return 0; }
int maSetHttpUser(MaAppweb *appweb, cchar *newUser) { #if BLD_UNIX_LIKE struct passwd *pp; if (snumber(newUser)) { appweb->uid = atoi(newUser); if ((pp = getpwuid(appweb->uid)) == 0) { mprError("Bad user id: %d", appweb->uid); return MPR_ERR_CANT_ACCESS; } newUser = pp->pw_name; } else { if ((pp = getpwnam(newUser)) == 0) { mprError("Bad user name: %s", newUser); return MPR_ERR_CANT_ACCESS; } appweb->uid = pp->pw_uid; } appweb->userChanged = 1; #endif appweb->user = sclone(newUser); return 0; }
static cchar *checkInteger(EdiValidation *vp, EdiRec *rec, cchar *fieldName, cchar *value) { if (value && *value) { if (snumber(value)) { return 0; } } return "is not an integer"; }
PUBLIC int httpSetGroupAccount(cchar *newGroup) { Http *http; http = HTTP; if (smatch(newGroup, "HTTP") || smatch(newGroup, "APPWEB")) { #if ME_UNIX_LIKE /* Only change group if root */ if (getuid() != 0) { return 0; } #endif #if MACOSX || FREEBSD newGroup = "_www"; #elif LINUX || ME_UNIX_LIKE { char *buf; newGroup = "nobody"; /* Debian has nogroup, Fedora has nobody. Ugh! */ if ((buf = mprReadPathContents("/etc/group", NULL)) != 0) { if (scontains(buf, "nogroup:")) { newGroup = "nogroup"; } } } #elif WINDOWS newGroup = "Administrator"; #endif } #if ME_UNIX_LIKE struct group *gp; if (snumber(newGroup)) { http->gid = atoi(newGroup); if ((gp = getgrgid(http->gid)) == 0) { mprLog("critical http", 0, "Bad group id: %d", http->gid); return MPR_ERR_CANT_ACCESS; } newGroup = gp->gr_name; } else { if ((gp = getgrnam(newGroup)) == 0) { mprLog("critical http", 0, "Bad group name: %s", newGroup); return MPR_ERR_CANT_ACCESS; } http->gid = gp->gr_gid; } http->groupChanged = 1; #endif http->group = sclone(newGroup); return 0; }
PUBLIC int httpSetUserAccount(cchar *newUser) { Http *http; http = HTTP; if (smatch(newUser, "HTTP") || smatch(newUser, "APPWEB")) { #if ME_UNIX_LIKE /* Only change user if root */ if (getuid() != 0) { mprLog("info http", 2, "Running as user \"%s\"", http->user); return 0; } #endif #if MACOSX || FREEBSD newUser = "******"; #elif LINUX || ME_UNIX_LIKE newUser = "******"; #elif WINDOWS newUser = "******"; #endif } #if ME_UNIX_LIKE { struct passwd *pp; if (snumber(newUser)) { http->uid = atoi(newUser); if ((pp = getpwuid(http->uid)) == 0) { mprLog("critical http", 0, "Bad user id: %d", http->uid); return MPR_ERR_CANT_ACCESS; } newUser = pp->pw_name; } else { if ((pp = getpwnam(newUser)) == 0) { mprLog("critical http", 0, "Bad user name: %s", newUser); return MPR_ERR_CANT_ACCESS; } http->uid = pp->pw_uid; } http->userChanged = 1; } #endif http->user = sclone(newUser); return 0; }
/* Parse the a date/time string and return the result in *time. Missing date items may be provided via the defaults argument. This is a tolerant parser. It is not validating and will do its best to parse any possible date string. */ PUBLIC int websParseDateTime(WebsTime *time, char *dateString, struct tm *defaults) { TimeToken *tt; struct tm tm; char *str, *next, *token, *cp, *sep; int64 value; int kind, hour, min, negate, value1, value2, value3, alpha, alpha2, alpha3; int dateSep, offset, zoneOffset, explicitZone, fullYear; if (!dateString) { dateString = ""; } offset = 0; zoneOffset = 0; explicitZone = 0; sep = ", \t"; cp = 0; next = 0; fullYear = 0; /* Set these mandatory values to -1 so we can tell if they are set to valid values WARNING: all the calculations use tm_year with origin 0, not 1900. It is fixed up below. */ tm.tm_year = -MAXINT; tm.tm_mon = tm.tm_mday = tm.tm_hour = tm.tm_sec = tm.tm_min = tm.tm_wday = -1; tm.tm_min = tm.tm_sec = tm.tm_yday = -1; #if ME_UNIX_LIKE && !CYGWIN tm.tm_gmtoff = 0; tm.tm_zone = 0; #endif /* Set to -1 to try to determine if DST is in effect */ tm.tm_isdst = -1; str = slower(dateString); /* Handle ISO dates: "2009-05-21t16:06:05.000z */ if (strchr(str, ' ') == 0 && strchr(str, '-') && str[slen(str) - 1] == 'z') { for (cp = str; *cp; cp++) { if (*cp == '-') { *cp = '/'; } else if (*cp == 't' && cp > str && isdigit((uchar) cp[-1]) && isdigit((uchar) cp[1]) ) { *cp = ' '; } } } token = stok(str, sep, &next); while (token && *token) { if (snumber(token)) { /* Parse either day of month or year. Priority to day of month. Format: <29> Jan <15> <2014> */ value = atoi(token); if (value > 3000) { *time = value; return 0; } else if (value > 32 || (tm.tm_mday >= 0 && tm.tm_year == -MAXINT)) { if (value >= 1000) { fullYear = 1; } tm.tm_year = (int) value - 1900; } else if (tm.tm_mday < 0) { tm.tm_mday = (int) value; } } else if ((*token == '+') || (*token == '-') || ((strncmp(token, "gmt", 3) == 0 || strncmp(token, "utc", 3) == 0) && ((cp = strchr(&token[3], '+')) != 0 || (cp = strchr(&token[3], '-')) != 0))) { /* Timezone. Format: [GMT|UTC][+-]NN[:]NN */ if (!isalpha((uchar) *token)) { cp = token; } negate = *cp == '-' ? -1 : 1; cp++; hour = getNum(&cp, timeSep); if (hour >= 100) { hour /= 100; } min = getNum(&cp, timeSep); zoneOffset = negate * (hour * 60 + min); explicitZone = 1; } else if (isalpha((uchar) *token)) { if ((tt = (TimeToken*) hashLookupSymbol(timeTokens, token)) != 0) { kind = tt->value & TOKEN_MASK; value = tt->value & ~TOKEN_MASK; switch (kind) { case TOKEN_DAY: tm.tm_wday = (int) value; break; case TOKEN_MONTH: tm.tm_mon = (int) value; break; case TOKEN_OFFSET: /* Named timezones or symbolic names like: tomorrow, yesterday, next week ... */ /* Units are seconds */ offset += (int) value; break; case TOKEN_ZONE: zoneOffset = (int) value; explicitZone = 1; break; default: /* Just ignore unknown values */ break; } } } else if ((cp = strchr(token, timeSep)) != 0 && isdigit((uchar) token[0])) { /* Time: 10:52[:23] Must not parse GMT-07:30 */ tm.tm_hour = getNum(&token, timeSep); tm.tm_min = getNum(&token, timeSep); tm.tm_sec = getNum(&token, timeSep); } else { dateSep = '/'; if (strchr(token, dateSep) == 0) { dateSep = '-'; if (strchr(token, dateSep) == 0) { dateSep = '.'; if (strchr(token, dateSep) == 0) { dateSep = 0; } } } if (dateSep) { /* Date: 07/28/2014, 07/28/08, Jan/28/2014, Jaunuary-28-2014, 28-jan-2014 Support order: dd/mm/yy, mm/dd/yy and yyyy/mm/dd Support separators "/", ".", "-" */ value1 = getNumOrSym(&token, dateSep, TOKEN_MONTH, &alpha); value2 = getNumOrSym(&token, dateSep, TOKEN_MONTH, &alpha2); value3 = getNumOrSym(&token, dateSep, TOKEN_MONTH, &alpha3); if (value1 > 31) { /* yy/mm/dd */ tm.tm_year = value1; tm.tm_mon = value2; tm.tm_mday = value3; } else if (value1 > 12 || alpha2) { /* dd/mm/yy Cannot detect 01/02/03 This will be evaluated as Jan 2 2003 below. */ tm.tm_mday = value1; tm.tm_mon = value2; tm.tm_year = value3; } else { /* The default to parse is mm/dd/yy unless the mm value is out of range */ tm.tm_mon = value1; tm.tm_mday = value2; tm.tm_year = value3; } } } token = stok(NULL, sep, &next); } /* Y2K fix and rebias */ if (0 <= tm.tm_year && tm.tm_year < 100 && !fullYear) { if (tm.tm_year < 50) { tm.tm_year += 2000; } else { tm.tm_year += 1900; } } if (tm.tm_year >= 1900) { tm.tm_year -= 1900; } /* Convert back to origin 0 for months */ if (tm.tm_mon > 0) { tm.tm_mon--; } /* Validate and fill in missing items with defaults */ validateTime(&tm, defaults); *time = makeTime(&tm); *time += -(zoneOffset * SEC_PER_MIN); *time += offset; return 0; }
static bool inRange(MprVersion *vp, cchar *expr) { char *cp, *ver, *op, *base, *pre, *all; cchar *high, *low; uint64 factor, min, max, num; while (isspace((uchar) *expr)) expr++; if (srmatch(expr, semExpr, &all, &op, &ver, NULL) <= 0) { mprLog("error", 5, "Bad version expression: %s", expr); return 0; } if (smatch(op, "~")) { /* ~VER Compatible with VER at the level of specificity given. ~1.2.3 == (>=1.2.3 <1.3.0) Compatible at the patch level ~1.2 == 1.2.x Compatible at the minor level ~1 == 1.x Compatible at the major level */ if (partCount(ver) == 3 && (cp = srchr(ver, '.')) != 0) { high = sjoin(snclone(ver, cp - ver), ".", MAX_VER_STR, NULL); if ((cp = schr(ver, '-')) != 0) { high = sjoin(high, cp, NULL); } return inRange(vp, sjoin(">=", ver, NULL)) && inRange(vp, sjoin("<", high, NULL)); } return inRange(vp, completeVersion(ver, "x")); } if (smatch(op, "^")) { /* ^VER Compatible with VER at the most significant level. ^0.2.3 == 0.2.3 <= VER < 0.3.0 ^1.2.3 == 1.2.3 <= VER < 2.0.0 So convert to a range */ high = ver; for (cp = ver, factor = VER_FACTOR * VER_FACTOR; *cp; cp++) { if (*cp == '.') { factor /= VER_FACTOR; } else if (isdigit((uchar) *cp) && *cp != '0') { num = (stoi(cp) + 1) * factor; high = numberToVersion(num); if ((cp = schr(ver, '-')) != 0) { high = sjoin(high, cp, NULL); } break; } } return inRange(vp, sjoin(">=", ver, NULL)) && inRange(vp, sjoin("<", high, NULL)); } ver = completeVersion(ver, "x"); if (srmatch(ver, semCriteria, &all, &base, &pre, NULL) <= 0) { mprLog("error", 5, "Cannot match version %s", ver); return 0; } if (vp->preVersion) { if (!pre) { return 0; } if (snumber(vp->preVersion)) { if (stoi(pre) < stoi(vp->preVersion)) { return 0; } } else { if (scmp(pre, vp->preVersion) < 0 && !smatch(pre, "-")) { return 0; } } } min = 0; max = MAX_VER * VER_FACTOR * VER_FACTOR; if (schr(ver, 'x')) { if (smatch(op, ">=")) { // 1.2.3 >= 2.x.x ... 1.2.3 >= 2.0.0 low = sreplace(ver, "x", "0"); min = versionToNumber(low); } else if (smatch(op, "<=")) { // 1.2.3 < 2.x.x ... 1.2.3 <2.MAX.MAX high = sreplace(ver, "x", MAX_VER_STR); max = versionToNumber(high); } else if (*op == '>') { // 1.2.3 > 2.x.x ... 1.2.3 > 2.0.0 low = sreplace(ver, "x", "0"); min = versionToNumber(low) + 1; } else if (*op == '<') { // 1.2.3 < 2.x.x ... 1.2.3 <2.MAX.MAX high = sreplace(ver, "x", MAX_VER_STR); max = versionToNumber(high) - 1; } else { low = sreplace(ver, "x", "0"); high = sreplace(ver, "x", MAX_VER_STR); return inRange(vp, sjoin(">=", low, NULL)) && inRange(vp, sjoin("<", high, NULL)); } } else if (smatch(op, ">=")) { min = versionToNumber(base); } else if (smatch(op, "<=")) { max = versionToNumber(base); } else if (*op == '>') { min = versionToNumber(base) + 1; } else if (*op == '<') { max = versionToNumber(base) - 1; } else { min = max = versionToNumber(base); } if (min <= vp->numberVersion && vp->numberVersion <= max) { return 1; } return 0; }