/* * Delete an Internet e-mail address from the directory. * * (NOTE: we don't actually use or need the citadel_addr variable; it's merely * here because the callback API expects to be able to send it.) */ int CtdlDirectoryDelUser(char *internet_addr, char *citadel_addr) { char key[SIZ]; syslog(LOG_DEBUG, "Delete directory entry: %s --> %s\n", internet_addr, citadel_addr); directory_key(key, internet_addr); return cdb_delete(CDB_DIRECTORY, key, strlen(key) ) == 0; }
/* * Purge the use table of old entries. * */ int PurgeUseTable(StrBuf *ErrMsg) { int purged = 0; struct cdbdata *cdbut; struct UseTable ut; struct UPurgeList *ul = NULL; struct UPurgeList *uptr; /* Phase 1: traverse through the table, discovering old records... */ if (CheckTDAPVeto(CDB_USETABLE, ErrMsg)) { syslog(LOG_DEBUG, "Purge use table: VETO!"); return 0; } syslog(LOG_DEBUG, "Purge use table: phase 1"); cdb_rewind(CDB_USETABLE); while(cdbut = cdb_next_item(CDB_USETABLE), cdbut != NULL) { /* * TODODRW: change this to create a new function time_t cdb_get_timestamp( struct cdbdata *) * this will release this file from the serv_network.h * Maybe it could be a macro that extracts and casts the reult */ if (cdbut->len > sizeof(struct UseTable)) memcpy(&ut, cdbut->ptr, sizeof(struct UseTable)); else { memset(&ut, 0, sizeof(struct UseTable)); memcpy(&ut, cdbut->ptr, cdbut->len); } cdb_free(cdbut); if ( (time(NULL) - ut.ut_timestamp) > USETABLE_RETAIN ) { uptr = (struct UPurgeList *) malloc(sizeof(struct UPurgeList)); if (uptr != NULL) { uptr->next = ul; safestrncpy(uptr->up_key, ut.ut_msgid, sizeof uptr->up_key); ul = uptr; } ++purged; } } /* Phase 2: delete the records */ syslog(LOG_DEBUG, "Purge use table: phase 2"); while (ul != NULL) { cdb_delete(CDB_USETABLE, ul->up_key, strlen(ul->up_key)); uptr = ul->next; free(ul); ul = uptr; } syslog(LOG_DEBUG, "Purge use table: finished (purged %d records)", purged); return(purged); }
/* * Purge the EUID Index of old records. * */ int PurgeEuidIndexTable(void) { int purged = 0; struct cdbdata *cdbei; struct EPurgeList *el = NULL; struct EPurgeList *eptr; long msgnum; struct CtdlMessage *msg = NULL; /* Phase 1: traverse through the table, discovering old records... */ syslog(LOG_DEBUG, "Purge EUID index: phase 1"); cdb_rewind(CDB_EUIDINDEX); while(cdbei = cdb_next_item(CDB_EUIDINDEX), cdbei != NULL) { memcpy(&msgnum, cdbei->ptr, sizeof(long)); msg = CtdlFetchMessage(msgnum, 0); if (msg != NULL) { CM_Free(msg); /* it still exists, so do nothing */ } else { eptr = (struct EPurgeList *) malloc(sizeof(struct EPurgeList)); if (eptr != NULL) { eptr->next = el; eptr->ep_keylen = cdbei->len - sizeof(long); eptr->ep_key = malloc(cdbei->len); memcpy(eptr->ep_key, &cdbei->ptr[sizeof(long)], eptr->ep_keylen); el = eptr; } ++purged; } cdb_free(cdbei); } /* Phase 2: delete the records */ syslog(LOG_DEBUG, "Purge euid index: phase 2"); while (el != NULL) { cdb_delete(CDB_EUIDINDEX, el->ep_key, el->ep_keylen); free(el->ep_key); eptr = el->next; free(el); el = eptr; } syslog(LOG_DEBUG, "Purge euid index: finished (purged %d records)", purged); return(purged); }
void cmd_rsen(char *argbuf) { char Token[SIZ]; long TLen; char Time[SIZ]; struct UseTable ut; struct cdbdata *cdbut; if (CtdlAccessCheck(ac_aide)) return; TLen = extract_token(Token, argbuf, 1, '|', sizeof Token); if (strncmp(argbuf, "GET", 3) == 0) { cdbut = cdb_fetch(CDB_USETABLE, Token, TLen); if (cdbut != NULL) { memcpy(&ut, cdbut->ptr, ((cdbut->len > sizeof(struct UseTable)) ? sizeof(struct UseTable) : cdbut->len)); cprintf("%d %ld\n", CIT_OK, ut.ut_timestamp); } else { cprintf("%d not found\n", ERROR + NOT_HERE); } } else if (strncmp(argbuf, "SET", 3) == 0) { memcpy(ut.ut_msgid, Token, TLen); extract_token(Time, argbuf, 2, '|', sizeof Time); ut.ut_timestamp = atol(Time); cdb_store(CDB_USETABLE, Token, TLen, &ut, sizeof(struct UseTable) ); cprintf("%d token updated\n", CIT_OK); } else if (strncmp(argbuf, "DEL", 3) == 0) { if (cdb_delete(CDB_USETABLE, Token, TLen)) cprintf("%d not found\n", ERROR + NOT_HERE); else cprintf("%d deleted.\n", CIT_OK); } else { cprintf("%d Usage: [GET|SET|DEL]|Token|timestamp\n", ERROR); } }
/* * Purge OpenID assocations for missing users (theoretically this will never delete anything) */ int PurgeStaleOpenIDassociations(void) { struct cdbdata *cdboi; struct ctdluser usbuf; HashList *keys = NULL; HashPos *HashPos; char *deleteme = NULL; long len; void *Value; const char *Key; int num_deleted = 0; long usernum = 0L; keys = NewHash(1, NULL); if (!keys) return(0); cdb_rewind(CDB_OPENID); while (cdboi = cdb_next_item(CDB_OPENID), cdboi != NULL) { if (cdboi->len > sizeof(long)) { memcpy(&usernum, cdboi->ptr, sizeof(long)); if (CtdlGetUserByNumber(&usbuf, usernum) != 0) { deleteme = strdup(cdboi->ptr + sizeof(long)), Put(keys, deleteme, strlen(deleteme), deleteme, NULL); } } cdb_free(cdboi); } /* Go through the hash list, deleting keys we stored in it */ HashPos = GetNewHashPos(keys, 0); while (GetNextHashPos(keys, HashPos, &len, &Key, &Value)!=0) { syslog(LOG_DEBUG, "Deleting associated OpenID <%s>", (char*)Value); cdb_delete(CDB_OPENID, Value, strlen(Value)); /* note: don't free(Value) -- deleting the hash list will handle this for us */ ++num_deleted; } DeleteHashPos(&HashPos); DeleteHash(&keys); return num_deleted; }
/* * Detach an OpenID from the currently logged in account */ void cmd_oidd(char *argbuf) { struct cdbdata *cdboi; char id_to_detach[1024]; int this_is_mine = 0; long usernum = 0L; if (CtdlGetConfigInt("c_disable_newu")) { cprintf("%d this system does not support openid.\n", ERROR + CMD_NOT_SUPPORTED); return; } if (CtdlAccessCheck(ac_logged_in)) return; extract_token(id_to_detach, argbuf, 0, '|', sizeof id_to_detach); if (IsEmptyStr(id_to_detach)) { cprintf("%d An empty OpenID URL is not allowed.\n", ERROR + ILLEGAL_VALUE); } cdb_rewind(CDB_OPENID); while (cdboi = cdb_next_item(CDB_OPENID), cdboi != NULL) { if (cdboi->len > sizeof(long)) { memcpy(&usernum, cdboi->ptr, sizeof(long)); if (usernum == CC->user.usernum) { this_is_mine = 1; } } cdb_free(cdboi); } if (!this_is_mine) { cprintf("%d That OpenID was not found or not associated with your account.\n", ERROR + ILLEGAL_VALUE); return; } cdb_delete(CDB_OPENID, id_to_detach, strlen(id_to_detach)); cprintf("%d %s detached from your account.\n", CIT_OK, id_to_detach); }
/* * Purge visits * * This is a really cumbersome "garbage collection" function. We have to * delete visits which refer to rooms and/or users which no longer exist. In * order to prevent endless traversals of the room and user files, we first * build linked lists of rooms and users which _do_ exist on the system, then * traverse the visit file, checking each record against those two lists and * purging the ones that do not have a match on _both_ lists. (Remember, if * either the room or user being referred to is no longer on the system, the * record is completely useless.) */ int PurgeVisits(void) { struct cdbdata *cdbvisit; visit vbuf; struct VPurgeList *VisitPurgeList = NULL; struct VPurgeList *vptr; int purged = 0; char IndexBuf[32]; int IndexLen; struct ValidRoom *vrptr; struct ValidUser *vuptr; int RoomIsValid, UserIsValid; /* First, load up a table full of valid room/gen combinations */ CtdlForEachRoom(AddValidRoom, NULL); /* Then load up a table full of valid user numbers */ ForEachUser(AddValidUser, NULL); /* Now traverse through the visits, purging irrelevant records... */ cdb_rewind(CDB_VISIT); while(cdbvisit = cdb_next_item(CDB_VISIT), cdbvisit != NULL) { memset(&vbuf, 0, sizeof(visit)); memcpy(&vbuf, cdbvisit->ptr, ( (cdbvisit->len > sizeof(visit)) ? sizeof(visit) : cdbvisit->len) ); cdb_free(cdbvisit); RoomIsValid = 0; UserIsValid = 0; /* Check to see if the room exists */ for (vrptr=ValidRoomList; vrptr!=NULL; vrptr=vrptr->next) { if ( (vrptr->vr_roomnum==vbuf.v_roomnum) && (vrptr->vr_roomgen==vbuf.v_roomgen)) RoomIsValid = 1; } /* Check to see if the user exists */ for (vuptr=ValidUserList; vuptr!=NULL; vuptr=vuptr->next) { if (vuptr->vu_usernum == vbuf.v_usernum) UserIsValid = 1; } /* Put the record on the purge list if it's dead */ if ((RoomIsValid==0) || (UserIsValid==0)) { vptr = (struct VPurgeList *) malloc(sizeof(struct VPurgeList)); vptr->next = VisitPurgeList; vptr->vp_roomnum = vbuf.v_roomnum; vptr->vp_roomgen = vbuf.v_roomgen; vptr->vp_usernum = vbuf.v_usernum; VisitPurgeList = vptr; } } /* Free the valid room/gen combination list */ while (ValidRoomList != NULL) { vrptr = ValidRoomList->next; free(ValidRoomList); ValidRoomList = vrptr; } /* Free the valid user list */ while (ValidUserList != NULL) { vuptr = ValidUserList->next; free(ValidUserList); ValidUserList = vuptr; } /* Now delete every visit on the purged list */ while (VisitPurgeList != NULL) { IndexLen = GenerateRelationshipIndex(IndexBuf, VisitPurgeList->vp_roomnum, VisitPurgeList->vp_roomgen, VisitPurgeList->vp_usernum); cdb_delete(CDB_VISIT, IndexBuf, IndexLen); vptr = VisitPurgeList->next; free(VisitPurgeList); VisitPurgeList = vptr; ++purged; } return(purged); }