/* * List the OpenIDs associated with the currently logged in account */ void cmd_oidl(char *argbuf) { struct cdbdata *cdboi; 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; cdb_rewind(CDB_OPENID); cprintf("%d Associated OpenIDs:\n", LISTING_FOLLOWS); 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) { cprintf("%s\n", cdboi->ptr + sizeof(long)); } } cdb_free(cdboi); } cprintf("000\n"); }
/* * List ALL OpenIDs in the database */ void cmd_oida(char *argbuf) { struct cdbdata *cdboi; long usernum; struct ctdluser usbuf; if (CtdlGetConfigInt("c_disable_newu")) { cprintf("%d this system does not support openid.\n", ERROR + CMD_NOT_SUPPORTED); return; } if (CtdlAccessCheck(ac_aide)) return; cdb_rewind(CDB_OPENID); cprintf("%d List of all OpenIDs in the database:\n", LISTING_FOLLOWS); 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) { usbuf.fullname[0] = 0; } cprintf("%s|%ld|%s\n", cdboi->ptr + sizeof(long), usernum, usbuf.fullname ); } cdb_free(cdboi); } cprintf("000\n"); }
/* * 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); }
/* * Get Next Unregistered User */ void cmd_gnur(char *argbuf) { struct cdbdata *cdbus; struct ctdluser usbuf; if (CtdlAccessCheck(ac_aide)) { return; } if ((CtdlGetConfigInt("MMflags") & MM_VALID) == 0) { cprintf("%d There are no unvalidated users.\n", CIT_OK); return; } /* There are unvalidated users. Traverse the user database, * and return the first user we find that needs validation. */ cdb_rewind(CDB_USERS); while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) { memset(&usbuf, 0, sizeof(struct ctdluser)); memcpy(&usbuf, cdbus->ptr, ((cdbus->len > sizeof(struct ctdluser)) ? sizeof(struct ctdluser) : cdbus->len)); cdb_free(cdbus); if ((usbuf.flags & US_NEEDVALID) && (usbuf.axlevel > AxDeleted)) { cprintf("%d %s\n", MORE_DATA, usbuf.fullname); cdb_close_cursor(CDB_USERS); return; } } /* If we get to this point, there are no more unvalidated users. * Therefore we clear the "users need validation" flag. */ begin_critical_section(S_CONTROL); int flags; flags = CtdlGetConfigInt("MMflags"); flags = flags & (~MM_VALID); CtdlSetConfigInt("MMflags", flags); end_critical_section(S_CONTROL); cprintf("%d *** End of registration.\n", CIT_OK); }
/* * 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; }
void cmd_whok(char *cmdbuf) { struct ctdluser temp; struct cdbdata *cdbus; int ra; cprintf("%d Who knows room:\n", LISTING_FOLLOWS); cdb_rewind(CDB_USERS); while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) { memset(&temp, 0, sizeof temp); memcpy(&temp, cdbus->ptr, sizeof temp); cdb_free(cdbus); CtdlRoomAccess(&CC->room, &temp, &ra, NULL); if ((!IsEmptyStr(temp.fullname)) && (CC->room.QRflags & QR_INUSE) && (ra & UA_KNOWN) ) cprintf("%s\n", temp.fullname); } cprintf("000\n"); }
/* * 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); }
/* * Implements the GETACL command. */ void imap_getacl(int num_parms, ConstStr *Params) { char roomname[ROOMNAMELEN]; char savedroom[ROOMNAMELEN]; int msgs, new; int ret; struct ctdluser temp; struct cdbdata *cdbus; int ra; StrBuf *rights; if (num_parms != 3) { IReply("BAD usage error"); return; } /* * Search for the specified room or folder */ ret = imap_grabroom(roomname, Params[2].Key, 1); if (ret != 0) { IReply("NO Invalid mailbox name or access denied"); return; } /* * CtdlUserGoto() formally takes us to the desired room. (If another * folder is selected, save its name so we can return there!!!!!) */ if (IMAP->selected) { strcpy(savedroom, CC->room.QRname); } CtdlUserGoto(roomname, 0, 0, &msgs, &new, NULL, NULL); IAPuts("* ACL "); IPutCParamStr(2); /* * Traverse the userlist */ rights = NewStrBuf(); cdb_rewind(CDB_USERS); while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) { memset(&temp, 0, sizeof temp); memcpy(&temp, cdbus->ptr, sizeof temp); cdb_free(cdbus); CtdlRoomAccess(&CC->room, &temp, &ra, NULL); if (!IsEmptyStr(temp.fullname)) { imap_acl_flags(rights, ra); if (StrLength(rights) > 0) { IAPuts(" "); IPutStr(temp.fullname, strlen(temp.fullname)); IAPuts(" "); iaputs(SKEY( rights)); } } } FreeStrBuf(&rights); IAPuts("\r\n"); /* * If another folder is selected, go back to that room so we can resume * our happy day without violent explosions. */ if (IMAP->selected) { CtdlUserGoto(savedroom, 0, 0, &msgs, &new, NULL, NULL); }