/** Read data from an open file * * Read should return exactly the number of bytes requested except * on EOF or error, otherwise the rest of the data will be * substituted with zeroes. An exception to this is when the * 'direct_io' mount option is specified, in which case the return * value of the read system call will reflect the return value of * this operation. * */ int bb_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int retstat = 0; int count; int count2; log_msg("\nbb_read(path=\"%s\", buf=0x%08x, size=%d, offset=%lld, fi=0x%08x)\n", path, buf, size, offset, fi); // no need to get fpath on this one, since I work from fi->fh not the path log_fi(fi); /* * The pread() function attempts to read the specified amount (size) of * data from the specified file descriptor (fi->fh), into the specified * buffer (buf) starting at a point in the file (offset). Returns the * number of bytes read. */ retstat = pread(fi->fh, buf, size, offset); log_msg("\nFile \"%s\" has been encrypted\n", path); // Encrypts the chars before reading it for (count = 0; count < size; count++) { buf[count] = (buf[count]+1) % 256; } // Decrypts if HasAccess is true if (HasAccess(BB_DATA)) { for (count2 = 0; count2 < size; count2++) { buf[count2] = (buf[count2] == 0) ? 255 : ((buf[count2]-1) % 256); } log_msg("\nAuthorized decryption on file \"%s\"\n", path); } if (retstat < 0) retstat = bb_error("bb_read read"); return retstat; }
/** Change the owner and group of a file */ int bb_chown(const char *path, uid_t uid, gid_t gid) { int retstat = 0; char fpath[PATH_MAX]; log_msg("\nbb_chown(path=\"%s\", uid=%d, gid=%d)\n", path, uid, gid); bb_fullpath(fpath, path); // If unauthorized it will break out if (!HasAccess(BB_DATA)) { log_msg("\nUnauthorized modification prevented to file \"%s\".\n", path); return 0; } else{log_msg("\nModification authorized to file \"%s\".\n", path);} retstat = chown(fpath, uid, gid); if (retstat < 0) retstat = bb_error("bb_chown chown"); return retstat; }
// As with read(), the documentation above is inconsistent with the // documentation for the write() system call. int bb_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int retstat = 0; log_msg("\nbb_write(path=\"%s\", buf=0x%08x, size=%d, offset=%lld, fi=0x%08x)\n", path, buf, size, offset, fi); // no need to get fpath on this one, since I work from fi->fh not the path log_fi(fi); // If unauthorized it will break out if (!HasAccess(BB_DATA)) { log_msg("\nUnauthorized write prevented to file \"%s\".\n", path); return 0; } else {log_msg("\nWrite authorized to file \"%s\".\n", path);} retstat = pwrite(fi->fh, buf, size, offset); if (retstat < 0) retstat = bb_error("bb_write pwrite"); return retstat; }
static void m_list(struct Luser *lptr, struct NickInfo *nptr, int ac, char **av) { struct MemoInfo *mi = NULL; struct Memo *memoptr; char status[4]; if (!nptr) return; if (ac >= 2) { if (av[1][0] == '#') { #ifdef CHANNELSERVICES struct ChanInfo *ci; #endif #ifndef CHANNELSERVICES notice(n_MemoServ, lptr->nick, "Channel services are disabled"); return; #else if (!(ci = FindChan(av[1]))) { notice(n_MemoServ, lptr->nick, ERR_CH_NOT_REGGED, av[1]); return; } if (!HasAccess(ci, lptr, CA_AUTOOP)) { notice(n_MemoServ, lptr->nick, "AutoOp access is required to list memos for [\002%s\002]", ci->name); return; } mi = FindMemoList(ci->name); if (!mi) { notice(n_MemoServ, lptr->nick, "There are no recorded memos for [\002%s\002]", ci->name); return; } #endif /* CHANNELSERVICES */ } } if (!mi) { if (!(mi = FindMemoList(nptr->nick))) { notice(n_MemoServ, lptr->nick, "You have no recorded memos"); return; } } notice(n_MemoServ, lptr->nick, "-- Listing memos for [\002%s\002] --", mi->name); notice(n_MemoServ, lptr->nick, " Idx Sender Time Sent"); for (memoptr = mi->memos; memoptr; memoptr = memoptr->next) { if (memoptr->flags & MS_DELETE) strcpy(status, "(D)"); else if (mi->name[0] != '#') { if (memoptr->flags & MS_READ) strcpy(status, "(R)"); else strcpy(status, "(N)"); } else status[0] = '\0'; notice(n_MemoServ, lptr->nick, "%3s %-3d %-18s %s ago", status, memoptr->index, memoptr->sender, timeago(memoptr->sent, 1)); } notice(n_MemoServ, lptr->nick, "-- End of list --"); } /* m_list() */
static void m_purge(struct Luser *lptr, struct NickInfo *nptr, int ac, char **av) { struct MemoInfo *mi; int cnt; if (!nptr) return; if (ac >= 2) { #ifdef CHANNELSERVICES struct ChanInfo *ci; #endif #ifndef CHANNELSERVICES notice(n_MemoServ, lptr->nick, "Channel services are disabled"); return; #else if (!(ci = FindChan(av[1]))) { notice(n_MemoServ, lptr->nick, ERR_CH_NOT_REGGED, av[1]); return; } if (!HasAccess(ci, lptr, CA_SUPEROP)) { notice(n_MemoServ, lptr->nick, "SuperOp access is required to purge memos for [\002%s\002]", ci->name); return; } if (!(mi = FindMemoList(ci->name))) { notice(n_MemoServ, lptr->nick, "There are no recorded memos for [\002%s\002]", ci->name); return; } cnt = PurgeMemos(mi); notice(n_MemoServ, lptr->nick, "Memos marked for deletion on [\002%s\002] have been purged (%d found)", ci->name, cnt); return; #endif /* CHANNELSERVICES */ } else if (!(mi = FindMemoList(nptr->nick))) { notice(n_MemoServ, lptr->nick, "You have no recorded memos"); return; } cnt = PurgeMemos(mi); notice(n_MemoServ, lptr->nick, "Your memos marked for deletion have been purged (%d found)", cnt); } /* m_purge() */
static void m_send(struct Luser *lptr, struct NickInfo *nptr, int ac, char **av) { char *memotext, /* memo text */ *to; /* who the memo is sent to */ int index; struct NickInfo *master = NULL, *realptr = NULL; #ifdef CHANNELSERVICES struct ChanInfo *ci = NULL; #endif if (ac < 3) { notice(n_MemoServ, lptr->nick, "Syntax: SEND <nick/channel> <text>"); notice(n_MemoServ, lptr->nick, ERR_MORE_INFO, n_MemoServ, "SEND"); return; } if (*av[1] == '#') { #ifndef CHANNELSERVICES notice(n_MemoServ, lptr->nick, "Channel services are disabled"); return; #else if (!(ci = FindChan(av[1]))) { notice(n_MemoServ, lptr->nick, ERR_CH_NOT_REGGED, av[1]); return; } if (!HasAccess(ci, lptr, CA_AUTOOP)) { notice(n_MemoServ, lptr->nick, "AutoOp access is required to send a memo to [\002%s\002]", ci->name); return; } to = ci->name; #endif /* CHANNELSERVICES */ } else { /* it was sent to a nickname */ if (!(realptr = FindNick(av[1]))) { notice(n_MemoServ, lptr->nick, ERR_NOT_REGGED, av[1]); return; } master = GetMaster(realptr); assert(master != 0); if (!(master->flags & NS_MEMOS)) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is rejecting all memos", av[1]); return; } to = master->nick; } /* get the actual memo text now */ if (ac < 3) memotext = MyStrdup(""); else memotext = GetString(ac - 2, av + 2); index = StoreMemo(to, memotext, lptr); if (index) { notice(n_MemoServ, lptr->nick, "Memo has been recorded for [\002%s\002]", realptr ? realptr->nick : to); if (realptr && master) { /* * It was sent to a nickname - check if they are online * and identified and optionally notify them * * we should have here linklist traversal and notifying all clients. * however, that could be a bit cpu intensitive to do for every * memo, so i haven't done it so far. -kre */ if ((master->flags & NS_MEMONOTIFY) && (realptr->flags & NS_IDENTIFIED) && FindClient(realptr->nick)) { notice(n_MemoServ, realptr->nick, "You have a new memo from \002%s\002 (#%d)", lptr->nick, index); notice(n_MemoServ, realptr->nick, "Type \002/msg %s READ %d\002 to read it", n_MemoServ, index); } } /* if (ni) */ #ifdef CHANNELSERVICES else { struct Channel *chptr; struct ChanAccess *ca; char *newtext; /* * It was sent to a channel - notify every AOP or higher */ if ((ci) && (chptr = FindChannel(to))) { struct ChannelUser *cu; struct NickInfo *tmpn; for (cu = chptr->firstuser; cu; cu = cu->next) { if (FindService(cu->lptr)) continue; tmpn = GetLink(cu->lptr->nick); if (HasAccess(ci, cu->lptr, CA_AUTOOP)) { if (tmpn) { /* don't notify people who don't want memos */ if (!(tmpn->flags & NS_MEMOS) || !(tmpn->flags & NS_MEMONOTIFY)) continue; } notice(n_MemoServ, cu->lptr->nick, "New channel memo from \002%s\002 (#%d)", lptr->nick, index); notice(n_MemoServ, cu->lptr->nick, "Type \002/msg %s READ %s %d\002 to read it", n_MemoServ, chptr->name, index); } } } newtext = (char *) MyMalloc(strlen(memotext) + strlen(ci->name) + 4); ircsprintf(newtext, "(%s) %s", ci->name, memotext); for (ca = ci->access; ca; ca = ca->next) { if (ca->nptr) StoreMemo(ca->nptr->nick, newtext, lptr); } MyFree(newtext); } /* else */ #endif /* CHANNELSERVICES */ } /* if (index) */ MyFree (memotext); } /* m_send() */
static void m_forward(struct Luser *lptr, struct NickInfo *nptr, int ac, char **av) { struct MemoInfo *from, *target; struct Memo *memoptr = NULL; struct Memo *fromptr; char *to; /* who the memo is sent to */ int index, cnt; char buf[MAXLINE]; struct NickInfo *master, *realptr; #ifdef CHANNELSERVICES struct ChanInfo *ci = NULL; #endif if (!nptr) return; if (ac < 3) { notice(n_MemoServ, lptr->nick, "Syntax: FORWARD <index|ALL> <nick/channel>"); notice(n_MemoServ, lptr->nick, ERR_MORE_INFO, n_MemoServ, "FORWARD"); return; } if (!(from = FindMemoList(nptr->nick))) { notice(n_MemoServ, lptr->nick, "You have no recorded memos"); return; } index = IsNum(av[1]); if ((index < 0) || (index > from->memocnt) || (!index && (irccmp(av[1], "ALL") != 0))) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is an invalid index", av[1]); return; } master = realptr = NULL; if (*av[2] == '#') { #ifndef CHANNELSERVICES notice(n_MemoServ, lptr->nick, "Channel services are disabled"); return; #else if (!(ci = FindChan(av[2]))) { notice(n_MemoServ, lptr->nick, ERR_CH_NOT_REGGED, av[2]); return; } if (!HasAccess(ci, lptr, CA_AUTOOP)) { notice(n_MemoServ, lptr->nick, "AutoOp access is required to forward a memo to [\002%s\002]", ci->name); return; } to = ci->name; #endif } else { /* it was sent to a nickname */ if (!(realptr = FindNick(av[2]))) { notice(n_MemoServ, lptr->nick, ERR_NOT_REGGED, av[2]); return; } master = GetMaster(realptr); assert(master != 0); if (!(master->flags & NS_MEMOS)) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is rejecting all memos", realptr->nick); return; } to = master->nick; } if (!(target = FindMemoList(to))) { target = MakeMemoList(); target->name = MyStrdup(to); AddMemoList(target); } else if (from == target) { /* * If we let someone forward memos to themselves, * the below loop will never end, eventually malloc()'ing too * much and crashing - head it off at the pass */ notice(n_MemoServ, lptr->nick, "You cannot forward memos to yourself"); return; } if (MaxMemos && (target->memocnt >= MaxMemos)) { notice(n_MemoServ, lptr->nick, "%s has reached the maximum memo limit, and cannot receive more", to); return; } cnt = 0; for (fromptr = from->memos; fromptr; fromptr = fromptr->next) { if (!index || (fromptr->index == index)) { memset(&buf, 0, MAXLINE); target->memocnt++; target->newmemos++; cnt++; memoptr = MakeMemo(); memoptr->sender = MyStrdup(lptr->nick); memoptr->sent = current_ts; memoptr->index = target->memocnt; strcpy(buf, "[Fwd]: "); strncat(buf, fromptr->text, MAXLINE - 8); memoptr->text = MyStrdup(buf); AddMemo(target, memoptr); if (MaxMemos && (target->memocnt >= MaxMemos)) break; } } if (!index) ircsprintf(buf, "All memos have"); else ircsprintf(buf, "Memo #%d has", index); notice(n_MemoServ, lptr->nick, "%s been forwarded to [\002%s\002]", buf, target->name); if (master && realptr) { /* * It was sent to a nickname - check if they are online * and notify them */ if ((master->flags & NS_MEMONOTIFY) && (realptr->flags & NS_IDENTIFIED) && FindClient(realptr->nick)) { notice(n_MemoServ, realptr->nick, "You have %d new forwarded memo%s from \002%s\002", cnt, (cnt == 1) ? "" : "s", memoptr->sender); notice(n_MemoServ, realptr->nick, "Type \002/msg %s LIST\002 to view %s", n_MemoServ, (cnt == 1) ? "it" : "them"); } } /* if (master && realptr) */ #ifdef CHANNELSERVICES else { struct Channel *chptr; /* * It was sent to a channel - notify every AOP or higher */ if ((ci) && (chptr = FindChannel(target->name))) { struct ChannelUser *cu; struct NickInfo *tmpn; for (cu = chptr->firstuser; cu; cu = cu->next) { if (FindService(cu->lptr)) continue; tmpn = GetLink(cu->lptr->nick); if (HasAccess(ci, cu->lptr, CA_AUTOOP)) { if (tmpn) { if (!(tmpn->flags & NS_MEMOS) || !(tmpn->flags & NS_MEMONOTIFY)) continue; } notice(n_MemoServ, cu->lptr->nick, "%d new forwarded channel memo%s from \002%s\002", cnt, (cnt == 1) ? "" : "s", memoptr->sender); notice(n_MemoServ, cu->lptr->nick, "Type \002/msg %s LIST %s\002 to view %s", n_MemoServ, chptr->name, (cnt == 1) ? "it" : "them"); } } } } /* else */ #endif /* CHANNELSERVICES */ } /* m_forward() */
static void m_undel(struct Luser *lptr, struct NickInfo *nptr, int ac, char **av) { struct MemoInfo *mi; struct Memo *memoptr; char istr[MAXLINE]; int index; if (!nptr) return; if (ac < 2) { notice(n_MemoServ, lptr->nick, "Syntax: UNDEL [channel] <index|all>"); notice(n_MemoServ, lptr->nick, ERR_MORE_INFO, n_MemoServ, "UNDEL"); return; } if (ac >= 3) { #ifdef CHANNELSERVICES struct ChanInfo *ci; #endif #ifndef CHANNELSERVICES notice(n_MemoServ, lptr->nick, "Channel services are disabled"); return; #else if (!(ci = FindChan(av[1]))) { notice(n_MemoServ, lptr->nick, ERR_CH_NOT_REGGED, av[1]); return; } if (!HasAccess(ci, lptr, CA_SUPEROP)) { notice(n_MemoServ, lptr->nick, "SuperOp access is required to undelete memos for [\002%s\002]", ci->name); return; } if (!(mi = FindMemoList(ci->name))) { notice(n_MemoServ, lptr->nick, "There are no recorded memos for [\002%s\002]", ci->name); return; } index = IsNum(av[2]); #endif /* CHANNELSERVICES */ } else { if (!(mi = FindMemoList(nptr->nick))) { notice(n_MemoServ, lptr->nick, "You have no recorded memos"); return; } index = IsNum(av[1]); } if ((index < 0) || (index > mi->memocnt) || (!index && (irccmp(av[(ac >= 3) ? 2 : 1], "ALL") != 0))) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is an invalid index", av[(ac >= 3) ? 2 : 1]); return; } for (memoptr = mi->memos; memoptr; memoptr = memoptr->next) { if (!index || (memoptr->index == index)) memoptr->flags &= ~MS_DELETE; } if (index) ircsprintf(istr, "Memo #%d has", index); else strcpy(istr, "All memos have"); if (ac >= 3) notice(n_MemoServ, lptr->nick, "%s been unmarked for deletion for [\002%s\002]", istr, av[1]); else notice(n_MemoServ, lptr->nick, "%s been unmarked for deletion", istr); } /* m_undel() */
static void m_read(struct Luser *lptr, struct NickInfo *nptr, int ac, char **av) { struct MemoInfo *mi; int index; struct Memo *memoptr; char istr[10]; if (!nptr) return; if (ac < 2) { notice(n_MemoServ, lptr->nick, "Syntax: READ [channel] <index|all>"); notice(n_MemoServ, lptr->nick, ERR_MORE_INFO, n_MemoServ, "READ"); return; } if (ac >= 3) { #ifdef CHANNELSERVICES struct ChanInfo *ci; #endif #ifndef CHANNELSERVICES notice(n_MemoServ, lptr->nick, "Channel services are disabled"); return; #else if (!(ci = FindChan(av[1]))) { notice(n_MemoServ, lptr->nick, ERR_CH_NOT_REGGED, av[1]); return; } if (!HasAccess(ci, lptr, CA_AUTOOP)) { notice(n_MemoServ, lptr->nick, "AutoOp access is required to read memos for [\002%s\002]", ci->name); return; } if (!(mi = FindMemoList(ci->name))) { notice(n_MemoServ, lptr->nick, "There are no recorded memos for [\002%s\002]", ci->name); return; } index = IsNum(av[2]); #endif /* CHANNELSERVICES */ } else { if (!(mi = FindMemoList(nptr->nick))) { notice(n_MemoServ, lptr->nick, "You have no recorded memos"); return; } index = IsNum(av[1]); } if ((index < 0) || (index > mi->memocnt) || (!index && (irccmp(av[(ac >= 3) ? 2 : 1], "ALL") != 0))) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is an invalid index", av[(ac >= 3) ? 2 : 1]); return; } for (memoptr = mi->memos; memoptr; memoptr = memoptr->next) { if (!index || (memoptr->index == index)) { notice(n_MemoServ, lptr->nick, "Memo #%d from %s (sent %s ago):", memoptr->index, memoptr->sender, timeago(memoptr->sent, 1)); notice(n_MemoServ, lptr->nick, memoptr->text); if (ac < 3) { /* only mark nickname memos as read - not channel memos */ if (!(memoptr->flags & MS_READ)) mi->newmemos--; memoptr->flags |= MS_READ; } } } if (index) ircsprintf(istr, "%d", index); else strcpy(istr, "ALL"); if (ac >= 3) notice(n_MemoServ, lptr->nick, "To delete, type \002/msg %s DEL %s %s", n_MemoServ, av[1], istr); else notice(n_MemoServ, lptr->nick, "To delete, type \002/msg %s DEL %s", n_MemoServ, istr); } /* m_read() */
bool CanWrite(const TCred &cred) const { return HasAccess(cred, 2); }
bool CanRead(const TCred &cred) const { return HasAccess(cred, 4); }