/* perform put command */ static int procput(const char *path, const char *pkbuf, int pksiz, TCMAP *cols, int omode, int dmode){ TCTDB *tdb = tctdbnew(); if(g_dbgfd != INVALID_HANDLE_VALUE) tctdbsetdbgfd(tdb, g_dbgfd); if(!tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(tdb); if(!tctdbopen(tdb, path, TDBOWRITER | omode)){ printerr(tdb); tctdbdel(tdb); return 1; } bool err = false; char pknumbuf[TCNUMBUFSIZ]; if(pksiz < 1){ pksiz = sprintf(pknumbuf, "%lld", (long long)tctdbgenuid(tdb)); pkbuf = pknumbuf; } const char *vbuf; switch(dmode){ case -1: if(!tctdbputkeep(tdb, pkbuf, pksiz, cols)){ printerr(tdb); err = true; } break; case 1: if(!tctdbputcat(tdb, pkbuf, pksiz, cols)){ printerr(tdb); err = true; } break; case 10: vbuf = tcmapget2(cols, "_num"); if(!vbuf) vbuf = "1"; if(tctdbaddint(tdb, pkbuf, pksiz, tcatoi(vbuf)) == INT_MIN){ printerr(tdb); err = true; } break; case 11: vbuf = tcmapget2(cols, "_num"); if(!vbuf) vbuf = "1.0"; if(isnan(tctdbadddouble(tdb, pkbuf, pksiz, tcatof(vbuf)))){ printerr(tdb); err = true; } break; default: if(!tctdbput(tdb, pkbuf, pksiz, cols)){ printerr(tdb); err = true; } break; } if(!tctdbclose(tdb)){ if(!err) printerr(tdb); err = true; } tctdbdel(tdb); return err ? 1 : 0; }
/* * Create a new user session. This is done upon each successful login. */ void create_session(unsigned long long sid) { char session_id[SID_LEN + 1]; char restrict_ip[2] = "0\0"; char pkbuf[256]; char timestamp[21]; char ssid[21]; char tenant[TENANT_MAX + 1]; char *username; int primary_key_size; MYSQL_RES *res; TCTDB *tdb; TCMAP *cols; GHashTable *db_row = NULL; username = make_mysql_safe_string(get_var(qvars, "username")); res = sql_query("SELECT uid, name, capabilities FROM passwd WHERE " "username = '******'", username); db_row = get_dbrow(res); get_tenant(env_vars.host, tenant); generate_hash(session_id, SHA256); if (strcmp(get_var(qvars, "restrict_ip"), "true") == 0) { d_fprintf(debug_log, "Restricting session to origin ip " "address\n"); restrict_ip[0] = '1'; } tdb = tctdbnew(); tctdbopen(tdb, SESSION_DB, TDBOWRITER | TDBOCREAT); primary_key_size = sprintf(pkbuf, "%ld", (long)tctdbgenuid(tdb)); snprintf(timestamp, sizeof(timestamp), "%ld", (long)time(NULL)); snprintf(ssid, sizeof(ssid), "%llu", sid); cols = tcmapnew3("tenant", tenant, "sid", ssid, "uid", get_var(db_row, "uid"), "username", get_var(qvars, "username"), "name", get_var(db_row, "name"), "login_at", timestamp, "last_seen", timestamp, "origin_ip", env_vars.remote_addr, "client_id", env_vars.http_user_agent, "session_id", session_id, "csrf_token", "\0", "restrict_ip", restrict_ip, "capabilities", get_var(db_row, "capabilities"), NULL); tctdbput(tdb, pkbuf, primary_key_size, cols); tcmapdel(cols); tctdbclose(tdb); tctdbdel(tdb); fcgx_p("Set-Cookie: session_id=%s; path=/; httponly\r\n", session_id); mysql_free_result(res); free_vars(db_row); free(username); }
/* perform importtsv command */ static int procimporttsv(const char *path, const char *file, int omode, bool sc){ FILE *ifp = file ? fopen(file, "rb") : stdin; if(!ifp){ fprintf(stderr, "%s: could not open\n", file ? file : "(stdin)"); return 1; } TCTDB *tdb = tctdbnew(); if(g_dbgfd != INVALID_HANDLE_VALUE) tctdbsetdbgfd(tdb, g_dbgfd); if(!tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(tdb); int64_t msiz = 0; TCMAP *info = tcsysinfo(); if(info){ msiz = tcatoi(tcmapget4(info, "total", "0")); tcmapdel(info); } if(!tctdbsetinvcache(tdb, msiz >= (1 << 30) ? msiz / 4 : 0, 1.0)) printerr(tdb); if(!tctdbopen(tdb, path, TDBOWRITER | TDBOCREAT | omode)){ printerr(tdb); tctdbdel(tdb); if(ifp != stdin) fclose(ifp); return 1; } bool err = false; char *line, numbuf[TCNUMBUFSIZ]; int cnt = 0; while(!err && (line = mygetline(ifp)) != NULL){ char *pv = strchr(line, '\t'); if(!pv){ tcfree(line); continue; } *pv = '\0'; if(sc) tcstrutfnorm(line, TCUNSPACE | TCUNLOWER | TCUNNOACC | TCUNWIDTH); const char *pkey; if(*line == '\0'){ sprintf(numbuf, "%lld", (long long)tctdbgenuid(tdb)); pkey = numbuf; } else { pkey = line; } if(!tctdbput3(tdb, pkey, pv + 1)){ printerr(tdb); err = true; } tcfree(line); if(cnt > 0 && cnt % 100 == 0){ putchar('.'); fflush(stdout); if(cnt % 5000 == 0) printf(" (%08d)\n", cnt); } cnt++; } printf(" (%08d)\n", cnt); if(!tctdbclose(tdb)){ if(!err) printerr(tdb); err = true; } tctdbdel(tdb); if(ifp != stdin) fclose(ifp); return err ? 1 : 0; }
/* * Sets up the user_session structure. This contains various bits of * information pertaining to the users session. */ void set_user_session(void) { TCTDB *tdb; TDBQRY *qry; TCLIST *res; TCMAP *cols; int rsize; int primary_key_size; char pkbuf[256]; char session_id[SID_LEN + 1]; char login_at[21]; char last_seen[21]; char uid[11]; char sid[21]; char restrict_ip[2]; char capabilities[4]; char user_hdr[1025]; char *xss_string; const char *rbuf; /* * Don't assume the order we get the cookies back is the * same order as we sent them. */ if (strncmp(env_vars.http_cookie, "session_id", 10) == 0) snprintf(session_id, sizeof(session_id), "%s", env_vars.http_cookie + 11); else snprintf(session_id, sizeof(session_id), "%s", env_vars.http_cookie + 88); tdb = tctdbnew(); tctdbopen(tdb, SESSION_DB, TDBOREADER | TDBOWRITER); /* Get the users stored session */ qry = tctdbqrynew(tdb); tctdbqryaddcond(qry, "session_id", TDBQCSTREQ, session_id); res = tctdbqrysearch(qry); rbuf = tclistval(res, 0, &rsize); cols = tctdbget(tdb, rbuf, rsize); tcmapiterinit(cols); memset(&user_session, 0, sizeof(user_session)); snprintf(user_session.tenant, sizeof(user_session.tenant), "%s", tcmapget2(cols, "tenant")); user_session.sid = strtoull(tcmapget2(cols, "sid"), NULL, 10); user_session.uid = atoi(tcmapget2(cols, "uid")); user_session.username = strdup(tcmapget2(cols, "username")); user_session.name = strdup(tcmapget2(cols, "name")); user_session.login_at = atol(tcmapget2(cols, "login_at")); user_session.last_seen = time(NULL); snprintf(user_session.origin_ip, sizeof(user_session.origin_ip), "%s", tcmapget2(cols, "origin_ip")); user_session.client_id = strdup(tcmapget2(cols, "client_id")); snprintf(user_session.session_id, sizeof(user_session.session_id), "%s", tcmapget2(cols, "session_id")); snprintf(user_session.csrf_token, sizeof(user_session.csrf_token), "%s", tcmapget2(cols, "csrf_token")); user_session.restrict_ip = atoi(tcmapget2(cols, "restrict_ip")); user_session.capabilities = atoi(tcmapget2(cols, "capabilities")); tcmapdel(cols); tclistdel(res); tctdbqrydel(qry); /* * Set the user header banner, which displays the users name, uid and * whether they are an Approver and or Admin. */ xss_string = xss_safe_string(user_session.name); snprintf(user_hdr, sizeof(user_hdr), "<big><big> %s</big></big><small>" "<span class = \"lighter\"> (%d) </span>" "</small>", xss_string, user_session.uid); free(xss_string); if (IS_APPROVER() && IS_ADMIN()) strncat(user_hdr, "<span class = \"t_red\">(Approver / Admin)" "</span>", 1024 - strlen(user_hdr)); else if (IS_APPROVER()) strncat(user_hdr, "<span class = \"t_red\">(Approver)" "</span>", 1024 - strlen(user_hdr)); else if (IS_ADMIN()) strncat(user_hdr, "<span class = \"t_red\">(Admin)" "</span>", 1024 - strlen(user_hdr)); strncat(user_hdr, " ", 1024 - strlen(user_hdr)); user_session.user_hdr = strdup(user_hdr); /* * We want to update the last_seen timestamp in the users session. * This entails removing the old session first then storing the new * updated session. */ qry = tctdbqrynew(tdb); tctdbqryaddcond(qry, "session_id", TDBQCSTREQ, session_id); res = tctdbqrysearch(qry); rbuf = tclistval(res, 0, &rsize); tctdbout(tdb, rbuf, strlen(rbuf)); tclistdel(res); tctdbqrydel(qry); primary_key_size = sprintf(pkbuf, "%ld", (long)tctdbgenuid(tdb)); snprintf(login_at, sizeof(login_at), "%ld", user_session.login_at); snprintf(last_seen, sizeof(last_seen), "%ld", user_session.last_seen); snprintf(uid, sizeof(uid), "%u", user_session.uid); snprintf(sid, sizeof(sid), "%llu", user_session.sid); snprintf(restrict_ip, sizeof(restrict_ip), "%d", user_session.restrict_ip); snprintf(capabilities, sizeof(capabilities), "%d", user_session.capabilities); cols = tcmapnew3("tenant", user_session.tenant, "sid", sid, "uid", uid, "username", user_session.username, "name", user_session.name, "login_at", login_at, "last_seen", last_seen, "origin_ip", user_session.origin_ip, "client_id", user_session.client_id, "session_id", user_session.session_id, "csrf_token", user_session.csrf_token, "restrict_ip", restrict_ip, "capabilities", capabilities, NULL); tctdbput(tdb, pkbuf, primary_key_size, cols); tcmapdel(cols); tctdbclose(tdb); tctdbdel(tdb); }