Friday, December 08, 2006

WSUS Deployment Issues

As mentioned in a previous post, I have deployed Windows Server Update Services (WSUS) in our company network. While overall the deployment went well, there were a number of issues with several computers, and overcoming them was a bit of a challenge. Most of the issues can be diagnosed by examining the WindowsUpdate.log file located in Windows directory. Here I'm going to share my experience.
  1. Some computers were running Windows 2000 with Service Pack 2. This version simply doesn't support automatic updates. The solution was to upgrade to Service Pack 4 manually.
  2. A common problem on both Windows XP and Windows 2000 computers was broken MS XML installation. This manifested in the following errors in WindowsUpdate.log:
    WARNING: GetConfig failure, error = 0x80244001, soap client error = 1,
      soap error code = 0, HTTP status code = 200
    WARNING: Sync of Updates: 0x80244001
    WARNING: Failed to synchronize, error = 0x80244001
    WARNING: Exit code = 0x80244001
    

    Error code 0x80244001, which means "SOAP client initialization failure", is indicative of MS XML installation problem. The solution is to reinstall MSXML 3.0 SP5 from here.

    Another manifestation of MS XML problem was the following in WindowsUpdate.log:

    WARNING: Sync of Updates: 0x80040111
    WARNING: Failed to synchronize, error = 0x80040111
    WARNING: CEventNamespaceDefinition::Init failed = 80040111.
    WARNING: InitReportingComponents failed: 80040111
    WARNING: Exit code = 0x80040111
    

    Error code 0x80040111, which means "ClassFactory cannot supply requested class", also most likely is caused by broken MS XML. The solution is the same.

  3. Even after MS XML reinstall, some computers failed to synchronize, displaying the following in the WindowsUpdate.log:
    WARNING: Sync of Updates: 0x80244010
    WARNING: Failed to synchronize, error = 0x80244010
    WARNING: Exit code = 0x80244010
    WARNING: WU client failed Searching for update with error 0x80244010
    

    Error code 0x80244010, which means "The maximum allowed number of round trips to the server was exceeded", in my experience can be dealt with as follows: either try again, or, if it occurs repeatedly, reset updates database. To reset the database, follow these steps:

    1. Stop automatic updates service (with "net stop wuauserv" command or in Services console)
    2. Delete or rename directory Windows\SoftwareDistribution
    3. Start automatic updates service (with "net start wuauserv" command or in Services console)
    4. Run "wuauclt /resetauthorization /detectnow" command

Tuesday, October 31, 2006

Extreme Diet Coke & Mentos Experiments II - The Domino Effect

The guys from EepyBird are back, with 251 bottles of Diet Coke and over 1,500 Mentos mints. In Experiment #137, they did a mint-powered version of the Bellagio fountains. This time, it's one giant Coke & Mentos chain reaction that has to be seen to be believed. Keywords: eepybird eepy bird mentos coke diet coke mentos experiment fountain soda science geyser experiments fountains geysers

Monday, October 30, 2006

Занимательная задача: 100 заключенных и 2 миски

Еще занимательная задача о 100 заключенных и сумасшедшем начальнике тюрьмы :-).

В тюрьме содержатся 100 заключенных. Начальник собирается провести с ними следующий эксперимент. Каждый день один заключенный приводится в особую комнату. В ней есть две полки (верхняя и нижняя), на которых стоит две миски, красная и синяя. Зайдя в комнату, заключенный должен переставить одну из мисок (любую, по своему выбору) на другую полку. Начальное положение мисок неизвестно. Порядок вызова заключенных неизвестен, но начальник гарантирует, что рано или поздно любой заключенный побывает в комнате сколь угодно много раз. Задача заключенных: кто-то из них должен объявить, что уже все побывали в комнате хотя бы по одному разу. Если он угадал - все освобождаются. Перед началом эксперимента заключенные могут договориться о стратегии, но после начала они не общаются. Как заключенным освободиться?

Занимательная задача: тестирование приборов

Есть множество приборов, часть которых исправна, а часть неисправна. Приборы умеют тестировать друг друга. Для тестирования приборы подключаются друг к другу и каждый сообщает про другого, исправен ли тот. При этом исправный прибор всегда верно диагностирует любой другой прибор, а неисправный выдает произвольный результат: иногда он выдаст верный диагноз, а иногда неверный. Задача:
  1. При условии, что исправных приборов больше половины, установить, какие приборы верные.
  2. Доказать, что если исправных приборов половина или меньше, то невозможно определить, какие приборы верные.

Задача рассказана мне Г.М. Фельдманом.

Wednesday, October 25, 2006

Занимательная задача: два шарика

Есть дом в 100 этажей и два одинаковых стеклянных шарика. Ясно, что если сбросить шарик с досточно высокого этажа, он разобьется. Задача: при помощи имеющихся двух шариков найти минимальный этаж, с которого шарик разобъется, совершив при этом минимальное число бросаний. При этом если шарик не разбился, его можно поднять и бросать еще раз, а если разбился - то шарика больше нет.

Задача рассказана мне Г.М. Фельдманом

Занимательная задача: подсчет в темноте

По периметру круглого складского помещения расставлено много одинаковых контейнеров. На каждом мелом написан какой-то номер. Номера идут в произвольном порядке и могут повторяться. На складе темно, но у нас есть фонарик, который может осветить только один контейнер, рядом с которым мы находимся. Мы можем произвольно перемещаться по складу. Подойдя к контейнеру, мы может стереть имеющийся на нем номер и написать любой другой.

В этих условиях нам надо посчитать, сколько контейнеров есть на складе. Как это сделать?

Задача рассказана мне Г.М. Фельдманом

Tuesday, October 24, 2006

Занимательная задача: 100 заключенных

В тюрьме содержится 100 заключенных. Начальник тюрьмы решил провести над ними следующий эксперимент. Заключенным сообщают, что завтра их всех выстроят на тюремном дворе в колонну по одному. Каждому на голову будет надет колпак, на котором сзади написан произвольный номер от 1 до 100 (номера идут в произвольном порядке и могут повторяться). Т.о. каждый заключенный видит номера коллег, стоящих в колонне впереди него, но не видит свой и тех, кто стоит за ним. Последнему в колонне заключенному предложат угадать свой номер, и он должен назвать вслух свое предположение. Затем то же должен сделать второй с конца и т.д. вплоть до первого в колонне. Тот, кто угадал свой номер, выходит на свободу. Перед началом эксперимента заключенные могут договориться о совместной стратегии.

Вопрос: сколько заключенных смогут освободиться?

Задача рассказана мне Г.М. Фельдманом

Monday, October 23, 2006

More NetBIOS woes

A Windows XP computer in our network exhibited a strange problem. It could connect to a network share via remote server's NetBIOS name (e.g. \\server\share), but not fully-qualified DNS name (e.g. \\server.domain.com\share). This had all sorts of interesting consequences. For one, group policy failed to apply to this computer, because it needs to access the group policy files on the domain controller's SYSVOL share via the domain's DNS name. The event log showed an error like this: "Windows cannot access the file gpt.ini for GPO CN={Policy GUID},CN=Policies,CN=System,DC=domain,DC=com The file must be present at the location \\domain.com\Policies\{Policy GUID} (Network path not found) Group Policy processing aborted". Of course it was failing because it could not access the domain controller via the \\domain.com DNS name. This group policy failure in turn prevented the computer from receiving updates from the local WSUS server, and so on.

As it turned out, the problem was that TCP/IP NetBIOS Helper Service was not running. Starting the service resolved the problem. Once again, NetBIOS is a must.

A particularly bad thing about the TCP/IP NetBIOS Helper Service is that one cannot force it to start via group policy. If the service is not running on a computer, group policy will not apply to this computer, as my example demonstrates.

Thursday, October 05, 2006

Installing Windows Server Update services (WSUS)

I've installed WSUS in my company's network. Right now it's being tested by a limited number of users, but things seem to run well. Installation and configuration is easy, and fully described in Deployment and Operations guides from Microsoft. A couple of things the guides didn't mention, though. First, I had to install this hotfix on the WSUS server computer, otherwise clients failed to update. Second, Automatic Updates (wuauserv) service as well as Background Intelligent Transfer Service (BITS) must be running on all client computers that update from a WSUS service. The former sounds obvious yet is easy to overlook, and BITS even less obvious for a new user of WSUS. An good way to ensure that the required services are running is through Group Policy. Since Microsoft recommends that WSUS settings are set in a separate GPO, and not in the Default Domain Policy, this WSUS GPO is a good place to configure Automatic Updates service to autostart (although one can do it in any other GPO as well). To do so, open this GPO in Group Policy Object Editor, and navigate to Computer Configuration - Windows Settings - Security Settings - System Services. Locate Automatic Updates services in the list, double-click and set the "Service startup mode" to automatic, like this:

Caveat: you also need to configure services security (the Security dialog pops up automatically). Here make sure to add "Authenticated Users" group with Read permission like this:

If you fail to do so, the Automatic Updates service will fail to start with "Error 0x80004015: The class is configured to run as a security id different from the caller". This is discussed in detail here. Repeat these steps for the Background Intelligent Transfer Service (BITS).

On a related note, in order to test WSUS with a limited number of computers I employed the following approach. As Microsoft guides recommend, I created a separate WSUS policy GPO with WSUS settings in Group Policy Management Console. I linked it to the top-level domain, but using the Security Filtering feature I specified that it only applies to a few selected computers. Once testing is successfully, I will replace this list of computers with "Authenticated Users" group so that the policy applies to all.

Friday, September 29, 2006

Из жизни исключений

Вот некоторые интересные факты из жизни исключений (exceptions) в языке Delphi Pascal. Статья подразумевает, что читатель знает, что такое exception и как с ними работают. Здесь освещены некоторые любопытные и менее очевидные моменты.

1. Исключения в конструкторе

Если в конструкторе любого объекта произойдет исключение, будет автоматически вызван деструктор этого объекта. Это обеспечивается "магией" компилятора. Отсюда следует, что правильной идиомой для создания и уничтожения класса является:
Obj = TSomeClass.Create;
try
  // ... работа с Obj
finally
  Obj.Free;
end;
Т.о. если исключение произойдет в конструкторе, деструктор будет вызван автоматически, а если после завершения конструктора - то деструктор будет вызван через Free из блока finally.

Строго говоря, не является ошибочным и следующий вариант:

Obj = nil;
try
  Obj = TSomeClass.Create;
  // ... работа с Obj
finally
  Obj.Free;
end;
Однако, такой способ некрасив и избыточен (лишнее присвоение Obj = nil). К тому же, помещение конструктора в блок try-finally само по себе вовсе не помогает против исключения в конструкторе. В самом деле, посмотрим внимательнее на строчку "Obj = TSomeClass.Create;". Здесь сначала выполняется конструктор, а потом его результат присваевается переменной Obj. Если в конструкторе произойдет исключение, то до присвоения переменной дело просто не дойдет. Поэтому в блоке finally переменная Obj по-прежнему будет nil. Так что только автоматический вызов деструктора может предотвратить потерю ресурсов при исключении в конструкторе. Вероятно поэтому создатели Delphi его и сделали. Сложно предложить другой способ.

Другое важное следствие - деструктор должен быть готов к работе с не до конца созданным объектом. Например, рассмотрим следующий класс:

type
  TExample = class
  private
    FList : TList;
    // ...
  public
    constructor Create;
    destructor Destroy; override;
    // ...
  end;

constructor TExample.Create;
begin
  inherited;
  // ... иницилизация других private-полей
  FList := TList.Create;
end;

destructor TExample.Destroy;
var
  I : Integer;
begin
  for I := 0 to FList.Count - 1 do
    // что-то сделать с FList[I]
  FList.Free;
  inherited;
end;
Деструктор этого класса содержит потенциальную опасность. Если исключение произойдет в конструкторе до того, как FList был создан, то деструктор будет вызван автоматически, и при этом FList будет все еще nil. Т.о. обращение FList.Count вызовет access violation, которе "замаскирует" изначальное исключение, так что сложно будет понять, что именно случилось не так. Правильнее было написать:
destructor TExample.Destroy;
var
  I : Integer;
begin
  if FList <> nil then begin
    for I := 0 to FList.Count - 1 do
      // что-то сделать с FList[I]
    FList.Free;
  end;
  inherited;
end;

AfterConstruction и BeforeDestruction

Теперь вспомним, что все классы в Delphi имеют два унаследованных от TObject "магических" метода AfterConstruction и BeforeDestruction. Первый из них вызывается сразу после конструктора, второй - непосредственно перед деструктором. Интересно отметить, что если исключение произойдет в AfterConstruction, деструктор будет вызван автоматически точно также, как если бы исключение произошло бы в конструкторе. Еще более интересно то, что при возникновении исключения в конструкторе ни AfterConstruction ни BeforeDestruction не вызываются (при возникновении исключения в AfterConstruction метод BeforeDestruction тоже не вызывается). Можно только догадываться, почему Delphi ведет себя именно так, но, по-видимому, вызывать AfterConstruction в таком случае представлялось разработчикам Delphi нелогичным - раз "Construction" не завершено, то и "AfterConstruction" быть не должно. А вызов BeforeDestruction при том, что AfterConstruction не сработал, привел бы к ряду проблем. Например, для классов, унаследованных от TInterfacedObject. Дело в том, что InterfacedObject.InitInstance устанавливает счетчик ссылок RefCount а 1, а TInterfacedObject.AfterConstruction уменьшает RefCount на 1. Делается это для того, чтобы в процессе работы конструктора объект вдруг не уничтожился, это если RefCount увеличится, а потом уменьшится до 0 (В help'e пишут по этому поводу: "When an instance of TInterfacedObject is allocated, RefCount is incremented to prevent its destruction while processing the constructor. AfterConstruction decrements that RefCount to re-establish the correct reference count after all constructors have executed."). Так что, если в конструкторе такого объекта произойдет исключение, то при вызове деструктора RefCount будет равен 1. Если бы в этот момент сработал BeforeDestruction, чей код имеет вид
if RefCount <> 0 then Error(reInvalidPtr);
то мы получили бы run-time error "Invalid pointer operation" вместо "нормального" исключения.

Так или иначе, BeforeDestruction вызван не будет. Помимо упомянутого обхода потенциальной проблемы с TInterfacedObject, это имеет еще такие последствия (которые иногда полезно иметь в виду)

  • Если объект унаследован от TCustomForm или TDataModule, то обработчик события OnDestroy вызван не будет (что логично, т.к. OnCreate тоже не вызывался)
  • Если объект унаследован от TComponent, то при вызове деструктора в ComponentState не будет флага csDestroying

2. Исключения в OnCreate и OnDestroy

Классы, порожденные от TCustomForm и TDataModule имеют события OnCreate и OnDestroy. События эти вызываются из методов DoCreate и DoDestroy этих классов. Эти методы перехватывают любое исключение, которые могло бы произойти в обработчиках этих событий и обрабатывают его с помощью Application.HandleException. Таким образом, если в событии OnCreate вашей формы произойдет исключение, оно будет тут же обработано через Application.HandleException, конструктор не будет прерван, и форма будет создана успешно (т.е. автоматического вызова деструктора, описанного в предыдущем пункте не произойдет). Насколько форма будет при этом функциональна - другой вопрос. Поэтому если при создании формы нужно проделать какую-то критическую операцию - т.е. такую операцию, что при ее неудаче форме вообще нет смысла создаваться - то надо делать ее в конструкторе, а не в событии OnCreate.

3. Исключения в initialization и finalization

Если исключение произойдет в секции initialization или finalization какого-либо из модулей, то оно вообще не будет обработано и программа завершится аварийно с run-time error 217. Казалось бы, исключение должно быть обработано с помощью ExceptProc из SysUtils, но почему-то этого не происходит.

4. Исключения при создании COM-объектов

Исключения при создании COM-объектов связаны с еще большим количеством проблем, чем исключения при создании других объектов. Как известно, если метод COM-объекта объявлен как safecall, то компилятор Delphi неявно "заворачивает" его в блок try-except, причем в блоке except вызывается метод SafeCallException, который гасит исключение, зато обставляет все таким образом, чтобы клиент, вызывающий данный метод, мог восстановить исключение. Таким образом исключение передаются практически "прозрачно" от COM-сервера к его клиенту ("практически", потому что класс исключения у клиента будет уже не тем, что на сервере, а всегда EOleException).

К сожалению, все это не работает при создании COM-объекта. Когда клиент создает COM-сервер (с помощью CreateCOMObject или чего-то аналотичного), COM-объект создается своей фабрикой классов. Если в конструкторе COM-объекта или его методе Initialize произойдет исключение, оно будет перехвачено в методе фабрики классов TComObjectFactory.CreateInstanceLic. При этом, если свойство фабрики классов ShowErrors имеет значение True (а это значение по умолчанию), сервер выдаст MessageBox с текстом ошибки. У клиента же вызов CreateCOMObject завершится маловразумительной ошибкой "Критический сбой" (код E_UNEXPECTED). Все это еще ничего, если сервер является inprocess (DLL) или локальным. Если же сервер вызывается удаленно (через DCOM), то скорей всего он вообще не имеет доступа к экрану серверного компьютера, так что показанный из TComObjectFactory.CreateInstanceLic MessageBox с текстом ошибки не будет виден и нажать на нем "ОК" будет невозможно. В результате сервер намертво зависнет. Даже если серверный процесс имеет доступ к экрану (что будет иметь место, если на сервере Windows 95/98, или же DCOM сконфигурирован соответствующим образом), то все равно сообщение об ошибке на экране сервера мало поможет клиенту. Выводы из этого такие:

  • Если предполагается использование COM-сервера через DCOM, то необходимо выставлять ShowErrors в False у всех фабрик классов.
  • Конструктор и метод Initialize COM-объектов не должны вызывать исключения. Все равно клиент не поймет в чем дело.
Если же при создании COM-объекта необхоодимо проделать какие-либо потенциально опасные (могущие привести к исключению) действия (например, связаться с базой данных), то возможны такие обходные варианты:
  1. Потенциально опасные действия делать в отдельном методе, который клиент вызывает сразу после создания объекта
  2. Обрамить потенциально опасные действия блоком try-except, причем в except погасить исключение и выставить некое свойство "инициализация неуспешна". Клиент в таком случае сразу после создания объекта должен проверить это свойство.
Оба варианта не очень красивы - требуют от клиента лишнего вызова сервера (потенциально по сети). Это отнимает лишнее время, к тому же клиент может просто забыть вызвать дополнительный метод. Но ничего лучше автор предложить пока не может. Призываю читателей этого текста придумать лучшее решение!

NetBIOS still alive

Recently I set up Remote Access Service in a Windows Server 2003 machine. After the installation (which went well) discovered that the computer is no longer visible in Network Neighbourhood of other network computers, and on that computer itself Network Neighbourhood is empty. Investigation revealed that NetBIOS over TCP/IP was disabled on the computer's NIC. Why it happenned I don't know. Enabling NetBIOS helped. And I thought NetBIOS was obsolete technology that we didn't need anymore? Apparently not.

Thursday, September 28, 2006

Getting Group Policy Editor to Work

In hopes to better administrate our Windows network at work I tried to get started with Group Policy. Discovered that attempting to edit the Group Policy from Active Directory Users and Computer or Group Policy Management result in error: "Failed to open the Group Policy Object. You may not have appropriate rights. Details: The parameter is incorrect". What a surprise. A quick Google search revealed an answer here: http://help.lockergnome.com/windows2/Failed-Open-Object-Parameter-incorrect-ftopict187780.html:

Check to see whether the path for "Default" under HKEY_CLASSES_ROOT\MSCFile\Shell\Open\Command is correct. This value should be a REG_EXPAND_SZ (not REG_SZ) and should have the value: %SystemRoot%\system32\mmc.exe "%1" %*

So, I fired up my Regedit and indeed, the type of the default value of the key in question was REG_SZ. But how do I change it to REG_EXPAND_SZ? Fiddled with Regedit for a while to no avail. You can't delete the default value to recreate it, and there's no option to change the value's type. So I ended up writing a small program in Delphi to do it. The program (with its trivial source in Delphi) is here. Just click the "Fix it" button.

Monday, September 25, 2006

Потемкинские евреи

Интересная статья из истории евреев в Российской империи: http://www.kackad.com/article.asp?article=1152. Помимо прочего, автор упоминает некоего Иошуа Цейтлина, моего однофамильца (или предка? едва ли):

Ключевую роль при потемкинском «дворе» играла личность, отмеченная исследователями давно, но значение которой, по-видимому, еще предстоит полностью оценить.

Иошуа Цейтлин, крупный купец и ученый гебраист, путешествовал с князем, управлял его имениями, строил города, заключал займы для снабжения армии, и даже управлял монетным двором в Крыму. По описаниям современников, он «расхаживал вместе с Потемкиным как его брат и друг», с гордостью сохраняя традиционную одежду, набожность, и на глазах у окружающих вел беседы с раввинами. В талмудических дискуссиях иногда участвовал и лично Светлейший. При нем, правда, находились также поп и мулла. Такое зрелище было поразительным не только для России, но и для Европы, получавшей от осведомителей отчеты о происходившем вокруг одного из самых непредсказуемых властителей.

Получив титул надворного советника, а значит, дворянское достоинство, Иошуа Цейтлин в 1791 году вступил во владение имением в Могилевской губернии. Некрещеный еврей по воле своего покровителя стал владельцем крепостных.

и дальше:

Цейтлин добивался, по возможности, реальных позитивных перемен. По протекции князя, он в 1787 году, во время поездки Екатерины на Юг, был принят ею и подал петицию о прекращении употребления в официальных документах унизительного слова «жиды». Императрица дала согласие на это, предписав использовать только слово «евреи».

Имеются подтверждения связей, установленных Цейтлиным с берлинским философом Мозесом Мендельсоном, центральной фигурой еврейского Просвещения - «Хаскалы». Была между ними духовная общность, но не могли не сказаться и различия, - как жизненных условий, так и концепций.

По-видимому, в общении с князем Таврическим И. Цейтлин сделал рискованную попытку связать «стратегические» еврейские интересы с имперским визионерством Потемкина. По мере нарастания военного превосходства над турками, Светлейший прогнозировал близкое крушение Оттоманской Порты. В этой связи он не исключал и возможности придать новый статус Иерусалиму, разместив там еврейское войско.

Начало этому войску должен был положить формировавшийся с 1786 года «Израилевский» конный полк. Есть сведения, что в местечке Кричев, входившем в одно из потемкинских имений, был образован первый эскадрон легкой кавалерии этого полка. Обучение евреев-конников велось под руководством немецкого офицера. Скоро к ним присоединился второй эскадрон, и еще новые части создавались в Польше. Хотя работа была приостановлена и не окончена при жизни Потемкина, остается фактом, что это была первая попытка иностранного государства вооружить евреев со времен, когда Тит разрушил Храм.

Также высказывается утверждение, что черта оседлости была введена не с целью обезопасить русских купцов от конкуренции, но "в пику" революционной Франции, где сразу после революции евреев уровняли в правах. Интересно.

Thursday, September 21, 2006

Fun with web page images

Open any web site, then copy the following to the address bar:

javascript:R=0; x1=.1; y1=.05; x2=.25; y2=.24; x3=1.6; y3=.24; x4=300; y4=200; x5=300; y5=200; DI=document.images; DIL=DI.length; function A(){for(i=0; i<DIL; i++){DIS=DI[ i ].style; DIS.position='absolute'; DIS.left=Math.sin(R*x1+i*x2+x3)*x4+x5; DIS.top=Math.cos(R*y1+i*y2+y3)*y4+y5}R++}setInterval('A()',5); void(0)

Make sure you copy the entire text above as one line. Enjoy the show :-)

There seems to be a lot of references to this hack on the web, mostly in blogs, but no reference to who first created it. I wonder.

Linguistic notes after visiting Catalonia

Catalan language has some unusual reading rules
  1. The letter "x" denotes a "sh" sound, e.g. "xocolate"
  2. Consequently, "tx" becomes "ch" sound
  3. The letter "j" is like in French (the "s" sound in "pleasure"; Russian "ж"). This is not so unusual.
  4. The letter combinations "tj" and "tg" become what "j" is in English. As in "Platja" (=beach) or "Viatges" (=voyages, travels)
  5. The letter combination "ig" denotes, unusually enough, "ch" sound, at least in the end of a word. As in the word "Passeig" (=avenue) or the name of the famous Catalan architect Puig i Cadafalch
  6. Double "l" denotes a soft "l" (Russian "ль") sound and is common in the beginning of words, as in the name of the town Lloret de Mar, name Llorenc or words like Lleo, Llimones, Llibertat
  7. When double "l" has to denote just a double "l" and not the special "ll" sound, it is spelled with the dot in the middle, as in words Paral.lel or Instal.lacion. This is very uniquely Catalan and looks so unusual to a foreigner.

How to configure /etc/krb5.conf for Samba

Recently I've set up a Samba server to be an AD domain member. A question came up: do I need to configure Kerberos? I am using Fedora Core 5 with MIT Kerberos. The answer can be found in Samba docs, but it is scattered around several unrelated parts of the Official Samba Howto and is not easily accessible. In my experience, the answer is as follows:
  • make sure dns_lookup_kdc = true in [libdefaults] section
  • optionally set default_realm in [libdefaults] section to the DNS name of your AD domain. I have a suspicion that this only provides a default for Kerberos command-line tools and is not important for Samba
So, have in your krb5.conf: [libdefaults] dns_lookup_kdc = true default_realm = YOUR.DOMAIN and don't change anything else.