вторник, 18 ноября 2008 г.

rdesktop и длинные имена файлов

Было дело, создал я около года назад свой дистрибутив Linux. Свой дистрибутив конечно громко сказано - за основу взял пакеты Debian, пересобрал ядро, удалил лишнее, организовал процесс загрузки как мне нужно. Так получился дистрибутив Linux Micro RDP Client. Как следует из его названия, единственное его предназначение - соединение по RDP протоколу с сервером, и предоставление удаленного рабочего стола юзверю. Создание своего дистрибутива было вызвано необходимостью. Ранее на предприятие, где я тружусь поставлялись тонкие клиенты Ниеншанса с очень удобным и простым дистрибутивом NNZ Linux. Но появился в поле видимости другой поставщик с тонкими клиентами - Depo. Есессенно с более выгодной ценой, и более интересными машинками. Но вот только в качестве операционки они использовали PIXES - весьма неудобоваримый для пользователя и тугой в настройке для админа дистрибутив. Сторонние дистрибутивы либо не обладали достаточным функционалом, либо стоили денег (пусть даже небольших, но все равно жалко ;) ).
С какими трудностями я столкнулся в процессе создания дистрибутива - отделая история, ибо всяческих нюансов, тонкостей, и просто граблей я хапнул давольно-таки не мало (да и по большому счету до сих пор хватаю - разработка до сих пор не закрыта, а в качестве бетатестеров сидят работники немаленького предприятия ;) )

Итак, ближе к теме.
Наткнулся на такой баг - при редиректе флешки посредством инструменов rdesktop в рабочее пространство пользователя на сервере (флешка появляется как подключеный сетевой диск), у некоторых пользователей система напроч отказывается читать некоторые каталоги (даже корневой). Ругается что устройство отключено, или что нет прав. Выяснилось что проблема в длинных именах файлов: почему-то не перевариваются имена более 126 символов. Понятно что скорее всего где-то в rdesktop стоит ограничение или может просто элементарная ошибка.
К счастью для пользователей (кодер из меня не ахти, да и времени жаль, да еще и лень разбираться ;) ) в инете наткнулся на багзилу АльтЛинукса, где люди весьма успешно борются с данной проблемой.
Все решение проблемы уложилось в последовательность действий: скачка патча, наложение патча, сборка, собирание призов от пользователей :)
Кстати, эту проблему я встретил в rdesktop 1.5.0, однако для свежей на данный момент версии 1.6.0 проблема осталась актуальной.

PS: Сам патч шоб не потерять:
--- rdesktop.orig/disk.c 2008-02-16 03:13:25 +0300
+++ rdesktop/disk.c 2008-07-04 14:13:52 +0400
@@ -1201,8 +1201,8 @@
out_uint32_le(out, filestat.st_size); /* filesize low */
out_uint32_le(out, 0); /* filesize high */
out_uint32_le(out, file_attributes);
-   out_uint8(out, 2 * strlen(pdirent->d_name) + 2); /* unicode length */
-   out_uint8s(out, 7); /* pad? */
+   out_uint16(out, 2 * strlen(pdirent->d_name) + 2); /* unicode length */
+   out_uint8s(out, 6); /* pad? */
out_uint8(out, 0); /* 8.3 file length */
out_uint8s(out, 2 * 12); /* 8.3 unicode length */
rdp_out_unistr(out, pdirent->d_name, 2 * strlen(pdirent->d_name));

среда, 12 ноября 2008 г.

PPTP over NAT (решаем проблемы c GRE пакетами)

Сегодня вот столкнулся с ситуацией, когда пришлось поднимать VPN через сервер с NAT. Долго я мучался и рыл доки, пока не нашел модули ядра к iptables, чем все и закончилось. Все просто. Дописываем в автозагрузку сервера с NAT (файл rc.local) загрузку этих модулей:
modprobe ip_gre
modprobe ip_nat_pptp
modprobe ip_conntrack_pptp
Ну и естессно запускаем эти же команды в консоли от рута, чтоб не перезагружать сервер. После этих манипуляций VPN бегает на “Ура”.

PS: Оригинал:
http://silverghost.org.ua/2008/05/22/vpn-pptp-over-nat/

четверг, 6 ноября 2008 г.

Смена пароля root MySQL

Сменить утерянный пароль достаточно просто и требуется проделать следующие шаги:
1. Остановить mysql-сервер
# /usr/local/etc/rc.d/mysql-server stop
2. Запустить mysqld с опцией --skip-grant-tables
# mysqld_safe --skip-grant-tables &
3. Соединиться с mysql-сервером
# mysql -u root
4. Установить пароль root
mysql> use mysql;
mysql> update user set password=PASSWORD('root_password') where user='root' and host='localhost';
mysql> flush privileges;
mysql> quit
5. Остановить сервер
# killall mysqld_safe
6. Запустить сервер и проверить новый пароль.

PS: Оригинальная статья:
http://www.propheta.ru/2008/01/root-mysql.html

суббота, 1 ноября 2008 г.

Патчим deb-пакеты

Перешел как-то я по дурости (очень хотелось программку одну опробывать) на тестовый дистрибутив Дебиана. Все бы ничего (ну мелки баги, редкие падения каких-либо сервисов - это все понятно, на то и тестинг), но вот добила меня одна мелочь - в окне терминала при запуске mc раньше отображалось имя сервера, а начиная, если мне память не изменяет, с версии 2:4.6.2~git20080311-1 - пропала напрочь. Только текущая директория и усе... При большом количестве открытых терминалов (пусть даже 4-5 серверов) - очень становится проблематично найти нужное окно. Появилась идея что все-таки может быть и не прохо было бы попытаться внести изменения в пакет самостоятельно. Разбираться с кодом, конечно, не очень-то хотелось, но как раз попался мне на глаза патч из какого-то другого дистрибутива Linux, который как раз правил эту самую проблему. А если он правит там то почему бы ему и не исправить у меня?
Для начала нужны исходники:
apt-get source mc
качается, распаковывается, патчится... В итоге получаем директорию mc-4.6.2~git20080311 (текущий релиз mc на момент написания - 4.6.2~git20080311-4).
Дальше интереснее. Наверняка в своих расуждениях я не уверен, но найти другие пути, возможно, более правильные, мне пока не удалось. Но расуждая логически: если я внесу изменения прямо в исходники, то при сборке пакета не наложатся патчи (те что в директории debian/patches). Значит прежде чем вносить изменения нужно пропатчить исходники. Для этого, находясь уже в директории пакета, делаем три команды:
ln -s debian/patches/all.series series
ln -s debian/patches/ patches
quilt push -a
Что это за балеристика - можно прочесть в man quilt.
Патчи наложены, но для того, чтобы опосля изменений можно было сделать свой патч и присовокупить его к имеющимся в пакете патчам, нам нужно будет сравнивать измененные исходники с оригиналом. Для этого нужно скопировать полученый распакованный пакет (тот на который только что наложили патчи) куда-нибудь, например mc-4.6.2~git20080311.orig.
Вносим изменения в пакет.
И, собсна, делаем патч по полученым изменениям:
diff -urdN ./mc-4.6.2~git20080311.orig ./mc-4.6.2~git20080311 > my.patch
Усе. Теперь есть патч, который можно внедрить в пакет. Но пакет нужет теперь чистый, без патчей в исходниках. Самый простой путь - удалить каталог с распакованым пакетом, и распаковать его по новой:
apt-get source mc
Кстати, если не удалены полученые ранее с помощью apt-get файлы (исходники да патчи) - они даже скачиваться не будут :)
Копируем полученный патч куда-нибудь в директорию debian/patches/ (например я свой патч разместил в директории debian/patches/bugs) и правим файл debian/patches/all.series: добавляем в конец файла путь до собственного патча (например debian/patches/bugs/my.patch). Не забываем изменить changelog. И собираем пакет:
dpkg-buildpackage -us -uc

Собсна все... Можно устанавливать пакет:
dpkg -i ./mc_4.6.2~my~git20080311-4_i386.deb

PS: Кстати, сам патч что у меня получился (а то ведь как пить дать где-нибудь потеряю):
--- ./src/main.c        2008-11-01 15:09:54.000000000 +0500
+++ ./src/main.c        2008-11-01 15:27:34.000000000 +0500
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <pwd.h>

#include <sys/types.h>
#include <sys/stat.h>
@@ -278,6 +279,9 @@
/* The user's shell */
const char *shell = NULL;

+/* The xterm title */
+char *xterm_title_str = NULL;
+
/* Is the LANG UTF-8 ? */
gboolean is_utf8 = FALSE;

@@ -1621,9 +1625,23 @@
update_xterm_title_path (void)
{
char *p, *s;
+    char h[64];
+    struct passwd *pw;

if (xterm_flag && xterm_title) {
+       if ( xterm_title_str ) g_free (xterm_title_str);
p = s = g_strdup (strip_home_and_password (current_panel->cwd));
+       if ( !gethostname (h, 64) ) {
+           h[63] = '\0'; /* Be sure the hostname is NUL terminated */
+           s = g_strdup_printf ("%s:%s", h, s);
+           g_free (p);
+           p = s;
+       }
+       if ( (pw = getpwuid(getuid())) ) {
+           s = g_strdup_printf ("%s@%s", pw->pw_name, s);
+           g_free (p);
+           p = s;
+       }
do {
#ifndef UTF8
if (!is_printable ((unsigned char) *s))
@@ -1634,7 +1652,7 @@
} while (*++s);
fprintf (stdout, "\33]0;mc - %s\7", p);
fflush (stdout);
-       g_free (p);
+       xterm_title_str = p;
}
}

--- ./src/main.h        2008-11-01 15:09:54.000000000 +0500
+++ ./src/main.h        2008-11-01 15:28:32.000000000 +0500
@@ -70,6 +70,7 @@
extern int output_starts_shell;
extern int midnight_shutdown;
extern gboolean is_utf8;
+extern char *xterm_title_str;
extern char cmd_buf [512];
extern const char *shell;

--- ./src/view.c        2008-11-01 15:09:54.000000000 +0500
+++ ./src/view.c        2008-11-01 15:31:11.000000000 +0500
@@ -3368,6 +3368,11 @@
WButtonBar *bar;
Dlg_head *view_dlg;

+    if (xterm_flag && xterm_title && xterm_title_str) {
+       fprintf (stdout, "\33]0;mc - %s/%s\7", xterm_title_str, file);
+       fflush(stdout);
+    }
+
/* Create dialog and widgets, put them on the dialog */
view_dlg =
create_dlg (0, 0, LINES, COLS, NULL, view_dialog_callback,
@@ -3391,6 +3396,8 @@
}
destroy_dlg (view_dlg);

+    update_xterm_title_path();
+
return succeeded;
}