📜 ⬆️ ⬇️

ejabberd + AD + Shared Roster

Good day.

To begin with, we have: a small network on ~ 150 machines, mainly with Windows XP, a domain raised naturally on Windows 2k3 and a normal machine (or server) on which gentoo linux is installed (optionally MySQL).

Task: Install a jabber server, make a shared roster, with groups from AD, attach an icq gate to it and put the jabber clients on the working machines.

Install ejabberd
')
Before you start to put ejabberd you need to make sure that we have everything, then he may need it, namely:



We will be collecting ejabberd from svn, as in a stable version I could not put the shared roster. To do this, we do:

user$ svn checkout svn.process-one.net/ejabberd


Putting it, just do not forget to include in the assembly parameter - enable-odbc

user$ cd ejabberd/trunk/src/
user$ ./configure --enable-odbc
user$ make
user$ sudo make install


If there are not any errors that are not popping up, we go further, the next step will probably be to assemble a module for the shared roster. The source of the module itself is still here mod_shared_roster_ldap.erl

user$ wget -c www.ejabberd.im/files/contributions/mod_shared_roster_ldap.erl
user$ erlc -I ejabberd/trunk/src/ mod_shared_roster_ldap.erl


If you get such messages, do not worry.

./mod_shared_roster_ldap.erl:19: Warning: behaviour gen_mod undefined
./mod_shared_roster_ldap.erl:289: Warning: variable 'User' is unused


Well, copy the new module in the heap to the rest

user$ sudo cp mod_shared_roster_ldap.beam /lib/ejabberd/ebin/


Ejabberd setup

“Turning” into the root ( sudo -i || su ) and crawling into / etc / ejabberd /, where we are interested in a file called ejabberd.cfg , open it with our favorite editor and begin to edit. I quote my config, with a few comments that will be escaped by %%:

override_global.
override_local.
override_acls.

{loglevel, 4}.

%% ,
, admin@domain %%
{watchdog_admins, ["admin@domain"]}.
%% , ejabberd,
cartman. hostname %%
{hosts, ["cartman"]}.
{listen,
[
%% %%
{5222, ejabberd_c2s, [
{access, c2s},
{shaper, c2s_shaper},
{max_stanza_size, 65536}
]},
%% , . SSL %%
{5223, ejabberd_c2s, [
{access, c2s},
{shaper, c2s_shaper},
%% , %%
{certfile, "/etc/ejabberd/cert/ejabberd.pem"}, tls,
{max_stanza_size, 65536}
]},
%% jabber %%
{5269, ejabberd_s2s_in, [
{shaper, s2s_shaper},
{max_stanza_size, 131072}
]},
%% , pyucq-t %%
{8888, ejabberd_service, [
{access, all},
{shaper_rule, fast},
{ip, {127, 0, 0, 1}},
%% %%
{hosts, ["icq.cartman"],
%% , pyicq-t %%
[{password, "123456"}]}
]},

%% ejabberd, %%
{5280, ejabberd_http, [
http_poll,
web_admin
]}

]}.

%% ldap %%
{auth_method, ldap}.
%% , domain.local %%
{ldap_servers, ["domain.local"]}.
{ldap_uids, [{"sAMAccountName"}]}.
{ldap_base, "dc=domain,dc=local"}.
%% , root, "" "" Users, ldap ( ?) %%
{ldap_rootdn, "cn=root,cn=Users,dc=domain,dc=local"}.
%% %%
{ldap_password, "123456"}.
%% , jabber ( ) %%
{shaper, normal, {maxrate, 10000}}.
{shaper, fast, {maxrate, 500000}}.
%% , admin %%
{acl, admin, {user, "admin", "cartman"}}.
%% , %%
{acl, admin, {user, "admin2", "cartman"}}.
{acl, local, {user_regexp, ""}}.
{access, max_user_sessions, [{10, all}]}.
{access, local, [{allow, local}]}.
%% , , jabber %%
{access, c2s, [{deny, blocked},
{allow, all}]}.
{access, c2s_shaper, [{none, admin},
{normal, all}]}.
{access, s2s_shaper, [{fast, all}]}.
{access, announce, [{allow, admin}]}.
{access, configure, [{allow, admin}]}.
{access, muc_admin, [{allow, admin}]}.
{access, muc, [{allow, all}]}.
{access, pubsub_createnode, [{allow, all}]}.
%% , AD %%
{access, register, [{deny, all}]}.

{language, "ru"}.

{modules,
[
{mod_adhoc, []},
{mod_announce, [{access, announce}]}, % recommends mod_adhoc
{mod_caps, []},
{mod_configure,[]}, % requires mod_adhoc
{mod_disco, []},
{mod_echo, [{host, "echo.localhost"}]},
{mod_last, []},
{mod_muc, [
{access, muc},
{access_create, muc},
{access_persistent, muc},
{access_admin, muc_admin}
]},
%% , , , . %%
{mod_muc_log, [
{access, muc},
{access_create, muc},
{access_admin, muc_admin},
{access_log, muc},
{outdir, "/var/log/muc_log"},
{top_link, {"http://cartman/", "JABBER SERVER"}}
]},
{mod_offline, []},
{mod_privacy, []},
{mod_private, []},
{mod_pubsub, [ % requires mod_caps
{access_createnode, pubsub_createnode},
{plugins, ["default", "pep"]}
]},
{mod_register, [
{welcome_message, {"Welcome",
"Hi! Welcome to this Jabber server."}},
%% , , , , , . %%
{registration_watchers, ["admin@cartman"]},
{access, register}
]},
{mod_roster, []},
{mod_stats, []},
{mod_time, []},
%% vcard AD, %%
{mod_vcard_ldap,
[{host, "users.cartman"},
{ldap_vcard_map,
[{"NICKNAME", "%u", []},
{"GIVEN", "%s", ["givenName"]},
{"MIDDLE", "%s", ["initials"]},
{"FAMILY", "%s", ["sn"]},
{"FN", "%s", ["displayName"]},
{"EMAIL", "%s", ["mail"]},
{"ORGNAME", "%s", ["company"]},
{"ORGUNIT", "%s", ["department"]},
{"CTRY", "%s", ["c"]},
{"LOCALITY", "%s", ["l"]},
{"STREET", "%s", ["streetAddress"]},
{"REGION", "%s", ["st"]},
{"PCODE", "%s", ["postalCode"]},
{"TITLE", "%s", ["title"]},
{"URL", "%s", ["wWWHomePage"]},
{"DESC", "%s", ["description"]},
{"TEL", "%s", ["telephoneNumber"]}]},
{ldap_search_fields,
[{"User", "%u"},
{"Name", "givenName"},
{"Family Name", "sn"},
{"Email", "mail"},
{"Phone", "telephoneNumber"}
]},
{ldap_search_reported,
[{"Full Name", "FN"},
{"Nickname", "NICKNAME"},
{"Email", "EMAIL"}]}
]},
%% shared_roster. department, AD %%
{mod_shared_roster_ldap,
[{ldap_groupattr,"department"},
{ldap_groupdesc,"department"},
%% , , AD JabberUsers, "" Users. , JabberUsers %%
{ldap_rfilter, "(&(memberOf=CN=JabberUsers,CN=Users,DC=klondike,DC=local) (|(userAccountControl=66050)(userAccountControl=66048)))"},
{ldap_memberattr,"sAMAccountName"},
{ldap_userdesc,"cn"}
]
},
{mod_version, []}
]}.


In the trailer everything is ready, but let's also add ssl certificates (bang come in handy)

mkdir /etc/ejabberd/cert
cd /etc/ejabberd/cert
openssl req -new -x509 -newkey rsa:1024 -days 3650 -keyout privkey.pem -out server.pem
openssl rsa -in privkey.pem -out privkey.pem
cat privkey.pem >> ejabberd.pem
rm privkey.pem


Install and configure pyicq-t

We will not collect it from snv || svc || git, as in gentoo it is in time, and quite working (the main thing is not to forget to include USE = “webinterface”, although someone like you) just do:

user$ sudo emerge net-im/pyicq-t


Everything is just further, we govern it (its) congig, which I have located in ** / etc / jabber / pyicq-t.xml. This is what mine looks like:

<pyicqt>
<jid>icq.cartman</jid>
<spooldir>/var/spool/jabber</spooldir>
<pid>/var/run/jabber/pyicq-t.pid</pid>
<mainServer>127.0.0.1</mainServer>
<mainServerJID>cartman</mainServerJID>
<website>http://cartman/</website>
<supportJid>admin@cartman</supportJid>
<port>8888</port>
<webport>12345</webport>
<secret>123456</secret>
<lang>ru</lang>
<encoding>cp-1251</encoding>
<icqServer>login.icq.com</icqServer>
<icqPort>5190</icqPort>
<usemd5auth/>
<sessionGreeting>Welcome to icq gate of Cartman server</sessionGreeting>
<enableShutdownMessage/>
<customShutdownMessage>Sorry but icq gete will be shutdown.</customShutdownMessage>
<registerMessage>You have succsefull registed</registerMessage>
<crossChat/>
<enableAutoInvite/>
<xstatusessupport/>
<detectunicode>1</detectunicode>
<admins>
<jid>admin@cartman</jid>
</admins>
<reactor>epoll</reactor>
<!--<xdbDriver>xmlfiles</xdbDriver>-->
<xdbDriver>mysql</xdbDriver>
<xdbDriver_mysql>
<username>pyicqt</username>
<password>12345678</password>
<database>pyicqt</database>
<server>localhost</server>
<format>encrypted</format>
</xdbDriver_mysql>
<avatarsOnlyOnChat/>
</pyicqt>


I’m probably not going to comment on it, in the very config comments it’s very much
the good ones, the only thing I notice is, 8888 is
the port by which it is screwed to Jaber, by the way we are in
The jabber config file was registered, 123456 is the password for the gate to jabber to access, we remove the saving of information from the * .xml files and transfer it to MySQL, below I will show you how.

I will not tell you how to install MySQL and run it, and how to create a user and database too. In general, we already have a working MySQL with the pyicqt database, with full permissions for the user pyicqt, who log in using the password 12345678. Next, for the gentry drives, we climb into the /usr/lib/python2.5/site-packages/pyicq- folder t / tools / and do the following

user$ mysql -u pyicqt -D pyicqt -p
mysql> \. db-setup.mysql


Well, let's try to run it all? We start ejabberd first, we will do it through ejabberdctl and immediately launch pyicq-t

user$ sudo ejabberdctl start
user$ sudo /etc/init.d/pyicq-t start


And we start watching the jabber logs:

user$ sudo tail -F /var/log/ejabberd/ejabberd.log


If not some terrible error does not arise - all good. We are starting to customize clients.

Configuring and installing clients

In principle, I felt many guishny clients (I myself have been using mcabber for a long time), and
decided that the client machines that are equipped with Windows XP will
set up either PSI or Spark, since PSI is more evolving and it is only
Jabber client and Spark is the only client that has an MSI package. Which one
you will decide, decide for yourself, I personally will show how I set them, naturally through politicians in AD.

Psi

That, in principle, is not good, I used Python to kill the configs
on client machines, so it must be installed on each
(this is done easily - it has the MSI package, and put it on, through AD). Then we simply set ourselves PSI, add our account, check how everything works, how groups appeared, in which users are offline, we set up PSI. When done, just close it. Now we climb into * C: \ Documents and Settings \% USERNAME% \ PsiData \ profiles \ default \ accounts.xml and edit it, look for the line admin @ cartman (somewhere in the box) (admin is the account under which you entered jabber , and your account in AD) and replace admin with QWERTYUIOP , save, and rename it to accounts_old . The next step is to create a ball, with read permissions for everyone, I’ll assume it will be \\ server4 \ psi_install and dump C: \ Documents and Settings \% USERNAME% \ PsiData and C: \ Program Files \ Psi (read permissions should be at all). We climb into \\ server4 \ psi_install \ PsiData \ profiles \ default and copy the Python script with the name psi_settings.py there , and here it is:

  1. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  2. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  3. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  4. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  5. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  6. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  7. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  8. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  9. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  10. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  11. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  12. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  13. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  14. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  15. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()
  16. #!/usr/env/bin python
    # -*- coding: utf-8 -*-
    import os
    import re
    import sys
    username = os.getenv('USERNAME')
    find_accountname = re.compile('^\s{0,3}<jid type="QString" >(.+)@cartman</jid>$')
    change_username = re.compile('QWERTYUIOP')
    fr = open('accounts_old', 'r')
    fw = open('accounts.xml', 'w+')
    for i in fr.readlines():
    if find_accountname.search(i):
    i = change_username.sub(username, i)
    fw.write(i)
    fr.close()
    fw.close()


the script is poor, wrote in a hurry

So, as most of our users are working with limited rights, I decided that they would run PSI from their own directory which is C: \ Documents and Settings \% USERNAME% *. We climb into the snap-in in Group Policy -> User Configuration -> Windows Configuration -> Scripts (login / logout) and select Login to System. Click show files and create a file with the name * copy_psi.cmd and change its contents:

@Echo off
IF EXIST "C:\Python25\python.exe" (
IF NOT EXIST "C:\Documents and Settings\%USERNAME%\Psi\psi.exe" (
xcopy \dc\Soft\ezotrank\psi_ad\* "C:\Documents and Settings\%USERNAME%" /E /C
cd "C:\Documents and Settings\%USERNAME%\PsiData\profiles\default"
python psi_settings.py
reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v psi_run /d "C:\Documents and Settings\%USERNAME%\Psi\psi.exe"
)
)


Well, like everything, close, add to the GP and go to smoke.

Spark.

What I didn’t like right away is that it is written in Java, which loves RAM very much, but it is very focused on the corporate market segment, and probably works very well with OpenFire (in principle, and this and that is the brainchild of some people), especially with the paid version . What I liked the most is the built-in feature with a screenshot. It’s easy to install it at all with spark and set it up using AD.

Some notes:

The web muzzle of the Hedgehog will be located at cartman : 5280 / admin login
and the password is the admin which we registered in ejabberd.cfg ie admin @ cartman

Web muzzle pyicq-t cartman : 12345

Source: https://habr.com/ru/post/56916/


All Articles