Как я могу обновить значение указателя, извлекая значение из INI-файла?

Я пытаюсь сделать несколько исправлений и улучшений в 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 ***

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, Однако эта функция возвращает статическую память, которую НЕ следует перезаписывать. Поэтому вам нужно либо скопировать strcuture вручную, прежде чем вы начнете изменять его, либо вы предоставляете ему свою собственную память. Подробнее о том, как это сделать, вы можете обратиться к http://linux.die.net/man/3/getpwnam и посмотреть на getpwnam_r, Обычно вы заранее выделяете эту память и передаете ее функции. Вы должны убедиться, что выделено достаточно памяти, поскольку все записи помещаются в указанный вами буфер. При соответствующем изменении кода он не должен падать.

Другие вопросы по тегам