Wednesday, July 18, 2007

Howto: Install and configure LDAP Server (slapd) with TLS in Gentoo

1.1. Install openldap on gentoo

# emerge openldap pam_ldap nss_ldap
# chown ldap:ldap /var/lib/openldap-ldbm /var/lib/openldap-data /var/lib/openldap-slurp

1.2. /etc/openldap/slapd.conf

include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema

### "#echo rootpw `slappasswd -h {SSHA}` >> /etc/openldap/slapd.conf" to generate a password with SSHA crypt

password-hash {SSHA}

# Define SSL and TLS properties
TLSCertificateFile /etc/ssl/ldap.pem
TLSCertificateKeyFile /etc/openldap/ssl/ldap-key.pem
TLSCACertificateFile /etc/ssl/ldap.pem

database bdb # use bdb as backend database
suffix "dc=example, dc=com"
directory /var/lib/openldap-data
rootdn "cn=Manager, dc=example, dc=com"
rootpw {SSHA}ksjdlfjsdlfjslfkjsdlfjl
checkpoint 1024 5

# index
index cn,sn,uid pres,eq,approx,sub
index objectClass eq

# then setup access rules...:
access to attrs=userPassword
by self write
by anonymous auth
by dn.base="cn=Manager,dc=example, dc=com" write
by * none
access to *
by self write
by dn.base="cn=Manager,dc=example,dc=com" write
by * read

1.3. /etc/openldap/ldap.conf

BASE         dc=example, dc=com
URI ldaps://server_host[change it to server]:636/
TLS_REQCERT allow

1.4. Genertate SSL certificate

# cd /etc/ssl
# openssl req -config /etc/ssl/openssl.cnf -new -x509 -nodes -out ldap.pem -keyout /etc/openldap/ssl/ldap-key.pem -days 999999
# chown ldap:ldap /etc/openldap/ssl/ldap.pem

1.5. Modify /etc/conf.d/slapd

OPTS="-h 'ldaps:// ldapi://%2fvar%2frun%2fopenldap%2fslapd.sock'"

1.6. Start slapd

/etc/init.d/slapd start

If success, with this command to test connection, "-d 5" is for debug:

ldapsearch -D "cn=Manager,dc=example,dc=com" -W -d 5

1.7. Autostart slapd service at Systemstart

rc-update slapd default add

1.8. Some issues

  • command "slaptest" for verify slapd.conf
  • if id3entry.bdb not found, try "slapadd"
  • recover DB: db4.3_recover -h .
  • useful log: /var/log/messages

Monday, July 16, 2007

wmctrl

The wmctrl program is a UNIX/Linux command line tool to interact with an EWMH/NetWM compatible X Window Manager.

http://sweb.cz/tripie/utils/wmctrl/

zenity - display GTK+ dialogs

zenity is a program that will display GTK+ dialogs, and return (either in the return code, or on standard output) the users input. This allows you to present information, and ask for information from the user, from all manner of shell scripts.

For example, zenity --question will return either 0 or 1, depending on whether the user pressed OK or Cancel. zenity --entry will output on standard output what the user typed into the text entry field.

Comprehensive documentation is available in the GNOME Help Browser, under GNOME/Utilities.

EXAMPLES

Display a file selector with the title Select a file to remove. The file selected is returned on standard output.


zenity --title="Select a file to remove" --file-selection

Display a text entry dialog with the title Select Host and the text Select the host you would like to flood-ping. The entered text is returned on standard output.


zenity --title "Select Host" --entry --text "Select the host you would like to flood-ping"

Display a dialog, asking Microsoft Windows has been found! Would you like to remove it?. The return code will be 0 (true in shell) if OK is selected, and 1 (false) if Cancel is selected.


zenity --question --title "Alert" --text "Microsoft Windows has been found! Would you like to remove it?"

Show the search results in a list dialog with the title Search Results and the text Finding all header files....


find . -name '*.h' | zenity --title "Search Results" --text "Finding all header files.." --column "Files"

Display a weekly shopping list in a check list dialog with Apples and Oranges pre selected


zenity --list --checklist --column "Buy" --column "Item" TRUE Apples TRUE Oranges FALSE Pears FALSE Toothpaste

Display a progress dialog while searching for all the postscript files in your home directory find `echo $HOME` '*.ps' | zenity --progress --pulsate

http://www.linuxmanpages.com/man1/zenity.1.php

devilspie

Devil’s Pie can be configured to detect windows as they are created, and match the window to a set of rules. If the window matches the rules, it can perform a series of actions on that window.

configuration files are in .devilspie folder, like firefox.ds. Code example:
(if
(is (application_name) "Firefox")
(set_workspace 2)
)
Detail description and syntax here: http://wiki.foosel.net/linux/devilspie


Tabbed rxvt

URxvt.perl-ext-common: default,tabbed
URxvt.tabbed.tab-fg: 12
URxvt.tabbed.tab-bg: 0
URxvt.tabbed.tabbar-fg: 4

Saturday, July 14, 2007

Bash tricks

bash vi keybind:
set -o vi in .bashrc

chinese locale but english console:
LANG="en_US.UTF-8"
LC_CTYPE="zh_CN.UTF-8"
in /etc/environment

custom bash prompt with color:

export TERM=xterm-color

PS1='${debian_chroot:+($debian_chroot)}\[\033[0;35m\]\d - \u@\h:\w\[\033[0;33m\] :: '

in .bashrc

Wednesday, July 11, 2007

Wednesday, July 4, 2007

Determining Current Function Name

# use sys._getframe() -- it returns a frame object, whose attribute
# f_code is a code object, whose attribute co_name is the name:
import sys
this_function_name = sys._getframe().f_code.co_name

# the frame and code objects also offer other useful information:
this_line_number = sys._getframe().f_lineno
this_filename = sys._getframe().f_code.co_filename

# also, by calling sys._getframe(1), you can get this information
# for the *caller* of the current function. So you can package
# this functionality up into your own handy functions:
def whoami():
import sys
return sys._getframe(1).f_code.co_name

me = whoami()

# this uses argument 1, because the call to whoami is now frame 0.
# and similarly:
def callersname():
import sys
return sys._getframe(2).f_code.co_name

him = callersname()

Tuesday, July 3, 2007

RequestContext in Template

def some_view(request):
# ...
return render_to_response('my_template.html',
my_data_dictionary,
context_instance=RequestContext(request))

Here’s what each of the default processors does:

django.core.context_processors.auth

If TEMPLATE_CONTEXT_PROCESSORS contains this processor, every RequestContext will contain these three variables:

  • user — An auth.User instance representing the currently logged-in user (or an AnonymousUser instance, if the client isn’t logged in). See the user authentication docs.

  • messages — A list of messages (as strings) for the currently logged-in user. Behind the scenes, this calls request.user.get_and_delete_messages() for every request. That method collects the user’s messages and deletes them from the database.

    Note that messages are set with user.message_set.create. See the message docs for more.

  • perms — An instance of django.core.context_processors.PermWrapper, representing the permissions that the currently logged-in user has. See the permissions docs.

django.core.context_processors.debug

If TEMPLATE_CONTEXT_PROCESSORS contains this processor, every RequestContext will contain these two variables — but only if your DEBUG setting is set to True and the request’s IP address (request.META['REMOTE_ADDR']) is in the INTERNAL_IPS setting:

  • debugTrue. You can use this in templates to test whether you’re in DEBUG mode.
  • sql_queries — A list of {'sql': ..., 'time': ...} dictionaries, representing every SQL query that has happened so far during the request and how long it took. The list is in order by query.

django.core.context_processors.i18n

If TEMPLATE_CONTEXT_PROCESSORS contains this processor, every RequestContext will contain these two variables:

See the internationalization docs for more.

django.core.context_processors.media

If TEMPLATE_CONTEXT_PROCESSORS contains this processor, every RequestContext will contain a variable MEDIA_URL, providing the value of the MEDIA_URL setting.

django.core.context_processors.request

If TEMPLATE_CONTEXT_PROCESSORS contains this processor, every RequestContext will contain a variable request, which is the current HttpRequest object. Note that this processor is not enabled by default; you’ll have to activate it.

Writing your own context processors

A context processor has a very simple interface: It’s just a Python function that takes one argument, an HttpRequest object, and returns a dictionary that gets added to the template context. Each context processor must return a dictionary.

Custom context processors can live anywhere in your code base. All Django cares about is that your custom context processors are pointed-to by your TEMPLATE_CONTEXT_PROCESSORS setting.


Mixin 和 Plugin

mixin 是统称,我又区分为Mixin和Plugin两种。

Mixin 是增加新东西或与原有的东西合并。比如向一个类增加属性或方法。
Plugin 相当于一个回调函数的扩展,它的调用入口一定是存在于某个方法中。举例来说:

class A(Mixin):
__mixinname__ = 'a'

def __init__(self):
self.initmixin()
#code
self.callplugin('plugin1', args1, args2)
#code
obj = self.execplugin('plugin2', args1, args2, args3)

上面的代码是一个slot class的例子,其中self.callplugin()和self.execplugin()是对于两种不同的Plugin的调用点。

为什么有这个东西的想法就是,我可以使用Mixin的方式将__init__方法替换掉,但可能我的处理代码为了不影响以前的东西仍然要保存许多的原始代码,这样程序看上去很乱。比如,不使用Plugin的方式,类可能为:

class A:
def __init__(self):
code1
code2

这时我发现A需要修改,那么可能需要在code1和code2之间加入一些代码,不使用mixin技术,你一定是要么直接修改A的代码,要么从A派生,不管怎能么样,__init__的代码都会为:

def __init__(self):
code1
newcode
code2

这样code1和code2就需要保留。如果再需要在code1和code2之间加入代码,你又要做这样的工作,要么修改A,要么从A派生,然后保留以前的代码。而采用mixin技术,你只需要在code1与code2之间加入一个插入点,那么A类就基本上不需要修改了。新的代码就使用一个新的Plugin来实现,再增加新的代码就再写一个Plugin就行了。能过Mixin模块将其合成一个Plugin的链。

因为Plugin是处于代码中间的,因此叫这个名字,这与插件的工作方式是一样的。而callplugin和execplugin的调用就是Plugin的接口定义。第一个参数是这个plugin接口的名字,后面是它的参数。而定义Plugin方法时需要按调用接口来定义参数,如上面的plugin1有两个参数,它的某个Plugin定义为:

def myplugin1(a, b):
print a, b
Mixin.setPlugin('a', 'plugin1', myyplugin1)

这样就通过Mixin模块的setPlugin方法将myplugin1与__mixinname__为'a'的plugin调用点为'plugin1'的接口关联起来了。

在执行callplugin和execplugin时不需要传入slot class
的__mixinname__,因为自已知道在调用Plugin时使用哪个slot class的Plugins。

Sunday, July 1, 2007

How to download a whole website?

wget -r http://address