荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: jjk (pq), 信区: InstallBBS
标  题: SMTH_013  FireBird 一个很严重的 Bug 的修正
发信站: 荔园晨风BBS站 (Thu Nov 29 11:21:52 2001), 转信

发信人: Admin (新的一天从零开始), 信区: BBSDev
标  题: SMTH_013  FireBird 一个很严重的 Bug 的修正
发信站: 北大未名站 (2001年05月24日11:26:55 星期四), 站内信件

发信人: Leeward (Initializing 40%), 信区: BBSMan_Dev
标  题: SMTH_013  FireBird 一个很严重的 Bug 的修正
发信站: BBS 水木清华站 (Mon Mar 22 04:01:03 1999) WWW-POST


发信人: Leeward (学习学习再学习,干活干活再干活), 信区: BBSMan_Dev
标  题: SMTH_012  将版面文章转成 HTML 格式并压缩打包
发信站: BBS 水木清华站 (Tue Jul 13 23:30:26 1999)

这是一个很严重的 Bug,在 FireBird 2.3/2.5/2.6 上均检测到了它的存在。
其它版本未经检测。

这个 Bug 是早些时候由 QuickBASIC 网友在本站 sysop 版发文指出的。

这个 Bug 如果不修正,那么在一定的条件下(这个条件很容易满足),
任何网友(不管权限如何)都可以通过一定的操作(这个操作也不复杂),
删除任何他能看到和曾经发表过文章的版面之内的别人的大量文章。

对此本站做了简单的修正,本文后面的部分将附上修正代码和必要的说明。
鉴于这个 Bug 具有很强的破坏性,对如何测试和复现它,就不进行说明了。

同时,希望已经知道详情的网友,以及看了修正代码后推测出详情的网友,
出于对其它网友和站点的尊重和爱护,不要把详情公布出来,以免造成不必要的损失。

另外,还请大家向其它站点转告关于这个 Bug 的信息。

本站只公布自己的修正代码,供大家参考和指正;
具体的 Bug 详情不予公布,也不对任何利用这个 Bug 制造的破坏事件承担任何责任。

=============================================================================

以下是修正代码,适用于 FireBird 2.5/2.6,其它版本未经测试。

1. bbs_src/bbs.c 的 edit_title 函数:

  > 添加两个变量定义 <
    long   i;
    struct fileheader xfh;

  > substitute_record(direct, fileinfo, sizeof(*fileinfo), ent) 调用前插入 <
          /* Leeward 99.07.12 added below to fix a big bug */
          setbdir(buf, currboard);
          for (i = ent; i > 0; i --)
          {
            if (0 == get_record(buf, &xfh, sizeof(xfh), i))
            {
              if (0 == strcmp(xfh.filename, fileinfo->filename))
              {
                ent = i;
                break;
              }
            }
          }
          if (0 == i)
            return PARTUPDATE;
          /* Leeward 99.07.12 added above to fix a big bug */

2. bbs_src/record.c 的 delete_file 函数:

  > ent = 1; 一行改为 ent = 0; <

=============================================================================

同类的问题代码里其它地方还有若干,但是由于不至造成其它用户的文章被删,
我们没有进行修正。

以上代码仅供参考。
--

        我 们 的 一 切 追 求 和 作 为, 都 有 一 个 令 人 厌 倦 的 过 程

   作 为 一 个 不 识 厌 倦 为 何 物 的 人, 便 掌 握 了 生 命 的 全 部 秘 密

※ 修改:·Leeward 於 Jul 14 00:00:36 修改本文·[FROM:  202.112.58.200]

--

     目前正在搜集整理内存管理相关资料
            欢迎提供

     泛一叶轻舟,漂流海上,逍遥有过于斯乎?


※ 来源:·北大未名站 bbs.pku.edu.cn·[FROM: 162.105.203.8]
--
※ 转寄:·北大未名站 bbs.pku.edu.cn·[FROM: 210.39.3.50]
--


本文描述的代码在 FireBird 2.5 和 2.6 上均可使用.

修改代码由 Luzi 于 Sat Oct 24 14:25:05 1998 在 BBS 水木清华站 开发并运行.

=========================================================================

为了维持代码原有的用户信息结构不变,
因此用户的离线时间记录在用户的 home 目录下的 exit 文件中.

bbs_src/bbs.c 里增加两个函数 get_exit_time 和 record_exit_time
bbs_src/talk.c 和 bbs_src/chat.c 里各增加一处调用 get_exit_time 的语句,
并判断若获得的离线时间早于上次上线时间,则显示“因在线上或非常断线不详”.

此外,如果被查询者在线但是隐身中,查询结果是:
具有看隐身者权限的用户,显示被查询者在线上,
没有看隐身者权限的用户,若被查询者有非隐身窗口,那么显示其在线上,
                        否则显示其上次的离站时间.

=========================================================================

bbs_src/bbs.c 中添加的函数:

time_t get_exit_time(id,exittime) /* 获取离线时间,id:用户ID,
                                   exittime:保存返回的时间,结束符为\n
                                            建议定义为 char exittime[40]
                                   Luzi 1998/10/23 */
/* Leeward 98.10.26 add return value: time_t */
char *id;
char *exittime;
{
    char path[80];
    FILE *fp;
    time_t now = 1; /* if fopen failed return 1 -- Leeward */
    sethomefile( path, id , "exit");
    fp=fopen(path, "rb");
    if (fp!=NULL)
    {
      fread(&now,sizeof(time_t),1,fp);
      fclose(fp);
      strcpy(exittime, ctime(&now));
    }
    else exittime[0]='\n';

    return now;
}

void record_exit_time()   /* 记录离线时间  Luzi 1998/10/23 */
{
    char path[80];
    FILE *fp;
    time_t now;
    sethomefile( path, currentuser.userid , "exit");
    fp=fopen(path, "wb");
    if (fp!=NULL)
      {
         now=time(NULL);
         fwrite(&now,sizeof(time_t),1,fp);
         fclose(fp);
        }
}

=========================================================================

bbs_src/talk.c 中 t_query 函数:
添加变量定义:char exittime[40];
              time_t exit_time,temp/*Haohmaru.98.12.04*/;
添加代码:
/* 获得离线时间 Luzi 1998/10/23 */
    exit_time = get_exit_time(lookupuser.userid,exittime);
    if( (newline = strchr(exittime, '\n')) != NULL )
        *newline = '\0';

    if (exit_time <= lookupuser.lastlogin
     || (uin.active && uin.pid
         && (!uin.invisible || (uin.invisible && HAS_PERM(PERM_SEECLOAK)))))
      strcpy(exittime,"因在线上或非常断线不详");
    if (exit_time <= lookupuser.lastlogin
   && (uin.invisible&& !HAS_PERM(PERM_SEECLOAK)))
      {
        temp=lookupuser.lastlogin+5;
        strcpy(exittime,ctime(&temp));/*Haohmaru.98.12.04.让隐身用户看上去
                        离线时间比上线时间晚5秒钟*/
        if( (newline = strchr(exittime, '\n')) != NULL )
        *newline = '\0';
      }
    prints( "\n上次在  [%s] 从 [%s] 到本站一游。\n离线时间[%s] ", genbuf,
        (lookupuser.lasthost[0] == '\0' ? "(不详)" : lookupuser.lasthost),
        exittime);

=========================================================================

bbs_src/chat.c 中 call_query 函数:
添加变量定义:time_t exit_time,temp;
添加代码:
/* 获得离线时间 Luzi 1998/10/23 */
        exit_time = get_exit_time(lookupuser.userid,genbuf);
        if( (newline = strchr(genbuf, '\n')) != NULL )
            *newline = '\0';
        if (exit_time > lookupuser.lastlogin) strcpy(inbuf,genbuf);
/*Haohmaru.98.12.04.和菜单查询结果一致*/
    if (exit_time <= lookupuser.lastlogin
     || (uin.active && uin.pid
         && (!uin.invisible || (uin.invisible && HAS_PERM(PERM_SEECLOAK)))))
      strcpy(inbuf,"因在线上或非常断线不详");
    if (exit_time <= lookupuser.lastlogin
     && (uin.invisible&& !HAS_PERM(PERM_SEECLOAK)))
      {
        temp=lookupuser.lastlogin+5;
        strcpy(inbuf,ctime(&temp));/*Haohmaru.98.12.04.让隐身用户看上去
                                     离线时间比上线时间晚5秒钟*/
        if( (newline = strchr(inbuf, '\n')) != NULL )
        *newline = '\0';
      }
 /*       else strcpy(inbuf,"[因非常断线不详]");*/
    sprintf(genbuf, "离线时间为 %s \n",inbuf);
    printchatline(genbuf);

=========================================================================

WWW 代码也有相应的若干修改.

本站的 WWW 代码已经公开在
 http://bbs.net.tsinghua.edu.cn/BBSMan_Dev/SMTH-WWW.tgz
里面已经包含了所有的修改.
详细介绍请参看本版 SMTH-009 本站 WWW 服务代码 系列文章.

具体说,WWW 代码进行下列相应修改:

bbs2www/bbsquery.c 的 main 函数中添加下列代码块(和相应变量定义):
     /* Leeward 98.10.24 */
     sethomefile(exittime, lookupuser.userid, "exit");
     if (fpe = fopen(exittime, "r")) {
       fread(&now, sizeof(time_t), 1, fpe);
       fclose(fpe);
       strcpy(exittime, ctime(&now));
     } else exittime[0] = '\n';
     if ( (newline = strchr(exittime, '\n')) != NULL ) *newline = '\0';
     search_ulist(&uin, t_cmpuids, getuser(lookupuser.userid));
     if (now < lookupuser.lastlogin
      || (uin.active && uin.pid && !uin.invisible))
       strcpy(exittime,"因在线上或异常断线不详");
     printf("离线时间 [%s] ", exittime);

PS: WWW 查询时,并没有引入“查询者ID的概念”:PP
    所以正在隐身上站的人被查时将不显示“在线上”字样----
    无论进行查询的人是否具有“可见隐身”的权限。


此外,WWW 代码中修改上线时间的同时,均修改离线时间为上线时间之后一秒:P

修改均按照下列形式:
            /* Leeward 98.10.26 */
            sprintf(exitfile, "home/%c/%s/exit", toupper(ID[0]), ID);
            if (- 1 == (fh = open(exitfile, O_WRONLY|O_CREAT, 0644))) {
              printf(":Err: failed login exit time for userid %s\n", ID );
            } else {
              record.lastlogin ++;
              write(fh, &record.lastlogin, sizeof(record.lastlogin));
              close(fh);
            }

上述修改分别作用于:
bbs2www/bbsmail.c 的 updateuserec 函数;
bbs_src/local_utl/bbspost.c 的 check_userec 函数。

=========================================================================

bbs_src/bbspop3d.c 因为不修改用户信息,所以未作任何修改。
--

        我 们 的 一 切 追 求 和 作 为, 都 有 一 个 令 人 厌 倦 的 过 程

   作 为 一 个 不 识 厌 倦 为 何 物 的 人, 便 掌 握 了 生 命 的 全 部 秘 密

※ 修改:·Leeward 於 Mar 22 04:07:37 修改本文·[FROM: zyu.ne.mediaone]

--

     目前正在搜集整理内存管理相关资料
            欢迎提供

     泛一叶轻舟,漂流海上,逍遥有过于斯乎?


※ 来源:·北大未名站 bbs.pku.edu.cn·[FROM: 162.105.203.8]
--
※ 转寄:·北大未名站 bbs.pku.edu.cn·[FROM: 210.39.3.50]
--
※ 修改:·jjk 於 Dec  5 11:35:06 修改本文·[FROM: 192.168.0.146]
※ 转载:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.0.146]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店