0

我正在尝试对Jailkit进行一些修复和增强。源代码在 CVS 版本控制中,所以我将它克隆到 GitHub

设置方式是,您将用户的主目录编辑为/etc/passwd

/home/jail/./home/username

然后该getjaildir函数读取传入的内容,oldhomedir直到它在字符串上从右到左找到第一个/./匹配项,然后将设置为该字符串jaildir左侧的内容和newhomedir右侧的所有内容。

我希望能够jaildir用配置文件中的值覆盖 - 但我很烂,c所以即使手动设置变量我也很难。

这是功能

/* if it returns 1 it will allocate new memory for jaildir and newhomedir
 * else it will return 0
 */
int getjaildir(const char *oldhomedir, char **jaildir, char **newhomedir) {
    int i=strlen(oldhomedir);
    /* we will not accept /./ as jail, so we continue looking while i > 4 (minimum then is /a/./ )
     * we start at the end so if there are multiple /path/./path2/./path3 the user will be jailed in the most minimized path
     */
    while (i > 4) {
/*      DEBUG_MSG("oldhomedir[%d]=%c\n",i,oldhomedir[i]);*/
        if (oldhomedir[i] == '/' && oldhomedir[i-1] == '.' && oldhomedir[i-2] == '/') {
            DEBUG_MSG("&oldhomedir[%d]=%s\n",i,&oldhomedir[i]);
            *jaildir = strndup(oldhomedir, i-2);
            *newhomedir = strdup(&oldhomedir[i]);
            return 1;
        }
        i--;
    }
    return 1;
}

经过多次尝试更复杂的解决方案后,我尝试了一个非常简单的硬编码变体:

int getjaildir(const char *oldhomedir, char **jaildir, char **newhomedir) {
    *jaildir = "/home/jail";
    *newhomedir = "/home/username";
    return 1;
}

这在 linux 上编译得很好,但是当我运行它时,我最终得到Segmentation fault (11). 我阅读了指针、地址、解除引用、变量类型、字符串连接等,但不幸的是我习惯了松散类型的语言,所以这很难。我究竟做错了什么?

更新

getjaildir我没有在函数中设置值,而是尝试在邮件循环中设置它们。

在循环的顶部,我们有变量定义:

    char *jaildir=NULL, *newhome=NULL, *shell=NULL;

这里是调用设置它们的函数的地方:

if (!getjaildir(pw->pw_dir, &jaildir, &newhome)) {
        syslog(LOG_ERR, "abort, failed to read the jail and the home from %s for user %s (%d)",pw->pw_dir, pw->pw_name, getuid());
        exit(17);
}

我可以在之后立即执行此操作以覆盖这些值吗?

jaildir="/home/jail";
newhome="/home/testuser";

当我尝试这个时,它给了我:

*** glibc detected *** -su: munmap_chunk(): invalid pointer: 0x00000000004046ee ***
4

1 回答 1

1

你怎么叫getjaildir

当我尝试它时,它可以正常工作。

int getjaildir(const char *oldhomedir, char **jaildir, char **newhomedir)
{
    *jaildir = "/home/jail";
    *newhomedir = "/home/username";
    return 1;
}

int main(int argc, char *argv[])
{
    char *ohome = "ohome";
    char *nhome = "nhome";
    char *jdir = "jdir";
    getjaildir(ohome, &jdir, &nhome);

    printf("%s:%s:%s\n", ohome, jdir, nhome);
}

输出:

ohome:/home/jail:/home/username

更新

我查看了 oyur 链接,现在我想我知道问题所在了。您正在通过调用 检索密码结构gepwnam。然而,这个函数返回一个静态内存,你不应该覆盖它。因此,您要么必须在开始修改之前手动复制结构,要么为它提供自己的内存。有关如何执行此操作的详细信息,您可以参考http://linux.die.net/man/3/getpwnam并查看getpwnam_r. 基本上,您事先分配此内存并将其传递给函数。您必须确保分配了足够的内存,因为所有条目都放入了您提供的缓冲区。当您相应地更改代码时,它不应该崩溃。

于 2013-06-06T06:40:44.827 回答