I ordered HP Pre3.

I orderd a HP Pre 3 Smartphone (SIM Free/Unlocked, Black). Cost is £ 249.16 body, £ 39.90 shipping, the total is £ 289.06 as about JPY 36 483. The transport takes like about two to five days. I’m looking forward.

smbclientでファイル一括取得。

滅多に使わないので忘れるので備忘として。

$ smbclient -U user //smbserver/Resouece
Enter user's password:
Domain=[HOGE_GROUP] OS=[Unix] Server=[Samba 3.0.14a-Debian]
smb: \> prompt
smb: \> recurse
smb: \> mget *
getting file \moge.txt of size 39936 as moge.txt (513.2 KiloBytes/sec) (average 513.2 KiloBytes/sec)
getting file \hoge.txt of size 43029 as hoge.txt (248.6 KiloBytes/sec) (average 330.7 KiloBytes/sec)
(snip)
smb: \>

Windowsな人たちと一緒に作業している環境だと、scpだと日本語の文字化けでアカン場合でもsmbclientでは大丈夫だったりもするので、必要悪って感じですねぇ…。

Life is short.

By the time I took care of the students had been retired in April of this year, by the summer greeting card that you know it. When I go out into the world, three years in any job and Keep, who had told me. When you change jobs and I have 10 years of that he had already retired plays to get hot breast.

phpLDAPadminでパスワード変更用U/Iを用意する。

LDAPの管理自体はコマンドラインで行えば良いのですが、LDAPで管理しているユーザ自身のパスワードの変更は、ブラウザで簡単にやらせたいですよね。なので、何か無いかなぁと探してみたら、同じようなことをphpLDAPadminでやったという ブログ見つけた のですが、細かいところは載っていなかったのでメモしておきました。

導入はいつもの通りDebianなので至極簡単で、

$ sudo apt-get install phpldapadmin

でOKです。しかもOSのユーザアカウントの認証の設定が済んでいるホストに導入すると、LDAPサーバへの問い合わせまわりの設定を自動的にやってくれます。なので、インストール後にhttp://localhost/phpldapadmin/にアクセスすると、phpLDAPadminの画面が表示され、adminユーザやその他のposixAccountでパスワード設定しているユーザでもすぐにログインできます。便利ですね。

ところが、この状態ではadminユーザだけでなく、一般ユーザでも他のユーザのオブジェクトの情報が丸見えです。LDAPサーバ側で特にアクセス制御していないからそりゃそうなんですけどね。で、別に見えるのは別に構わないのですが、やりたいことは、単に自分のパスワードの変更だけをさせることです。ユーザには余計な情報や、余計な編集用のフォームは見せる必要は無いのです。なので、オブジェクトツリーも、変更用のフォームも見えないようにしてやりました。 1

diff --git a/phpldapadmin/config.php b/phpldapadmin/config.php
index f89e5fa..075a7da 100644
--- a/phpldapadmin/config.php
+++ b/phpldapadmin/config.php
@@ -79,6 +79,7 @@
    assume UTC if you have not set PHP date.timezone. */
 // $config->custom->appearance['timezone'] = null;
 #  $config->custom->appearance['timezone'] = 'Australia/Melbourne';
+$config->custom->appearance['timezone'] = 'Asia/Tokyo';

 /*********************************************/
 /* Commands                                  */
@@ -154,10 +155,11 @@ $config->custom->commands['script'] = array(
 // $config->custom->appearance['disable_default_template'] = false;

 /* Hide the warnings for invalid objectClasses/attributes in templates. */
-// $config->custom->appearance['hide_template_warning'] = false;
+$config->custom->appearance['hide_template_warning'] = true;

 /* Configure what objects are shown in left hand tree */
 // $config->custom->appearance['tree_filter'] = '(objectclass=*)';
+$config->custom->appearance['tree_filter'] = '(ou=People)';

 /* The height and width of the tree. If these values are not set, then
    no tree scroll bars are provided. */
@@ -192,6 +194,7 @@ $config->custom->appearance['friendly_attrs'] = array(
    excluded. */
 // $config->custom->appearance['hide_attrs'] = array();
 #  $config->custom->appearance['hide_attrs'] = array('objectClass');
+$config->custom->appearance['hide_attrs'] = array('cn','mail','gidNumber','give
nName','homeDirectory','loginShell','o','objectClass','uidNumber','uid','sn','fa
csimileTelephoneNumber','telephoneNumber','jpegPhoto','street','postalCode','st'
,'mobile','l','memberUid','ou','description');

 /* Members of this list will be exempt from the hidden attributes.*/
 // $config->custom->appearance['hide_attrs_exempt'] = null;
@@ -208,6 +211,7 @@ $config->custom->appearance['friendly_attrs'] = array(
    NOTE: The user must be able to read the readonly_attrs_exempt entry to be
    excluded. */
 // $config->custom->appearance['readonly_attrs'] = array();
+$config->custom->appearance['readonly_attrs'] = array('cn','mail','gidNumber','
givenName','homeDirectory','loginShell','o','objectClass','uidNumber','uid','sn'
,'facsimileTelephoneNumber','telephoneNumber','jpegPhoto','street','postalCode',
'st','mobile','l','memberUid','ou','description');

 /* Members of this list will be exempt from the readonly attributes.*/
 // $config->custom->appearance['readonly_attrs_exempt'] = null;
@@ -303,7 +307,7 @@ $servers->setValue('login','auth_type','session');
    you specify a login_attr in conjunction with a cookie or session auth_type,
    then you can also specify the bind_id/bind_pass here for searching the
    directory for users (ie, if your LDAP server does not allow anonymous binds.
 */
-$servers->setValue('login','bind_id','cn=admin,dc=example,dc=org');
+//$servers->setValue('login','bind_id','cn=admin,dc=example,dc=org');
 #  $servers->setValue('login','bind_id','cn=Manager,dc=example,dc=com');

 /* Your LDAP password. If you specified an empty bind_id above, this MUST also
@@ -314,6 +318,9 @@ $servers->setValue('login','bind_id','cn=admin,dc=example,dc=org');
 /* Use TLS (Transport Layer Security) to connect to the LDAP server. */
 // $servers->setValue('server','tls',false);

+// custom
+$servers->setValue('login','attr','uid');
+
 /************************************
  *      SASL Authentication         *
  ************************************/
@@ -421,13 +429,14 @@ $servers->setValue('login','bind_id','cn=admin,dc=example,dc=org');
    (readonly) access to uidnumber in your ldap directory (the logged in user
    may not), so that you can be guaranteed to get a unique uidnumber for your
    directory. */
-// $servers->setValue('auto_number','dn',null);
+//$servers->setValue('auto_number','dn',null);

 /* The password for the dn above. */
 // $servers->setValue('auto_number','pass',null);
 /* Enable anonymous bind login. */
 // $servers->setValue('login','anon_bind',true);
+$servers->setValue('login','anon_bind',false);

 /* Use customized page with prefix when available. */
 #  $servers->setValue('custom','pages_prefix','custom_');

今回変更したところで、”ユーザにパスワードの変更だけをさせる”という目的に関連するところだけピックアップしておくと、

  • $config->custom->appearance[‘hide_template_warning’] をtrueにすることで、画面上で表示されるログを抑制

  • $config->custom->appearance[‘tree_filter’] = ‘(ou=People)’を追加して、左のメニューに表示されるデフォルトのオブジェクトツリーをユーザ情報(People)だけにする

  • $config->custom->appearance[‘hide_attrs’]に、表示させたくない属性を列挙

    • 非表示にした属性は以下。まぁ要は自分のパスワード以外は全部非表示に。cn, mail, gidNumber, givenName, homeDirectory, loginShell, o, objectClass, uidNumber, uid, sn, facsimileTelephoneNumber, telephoneNumber, jpegPhoto, street, postalCode, st, mobile, l, memberUid, ou, description

  • $config->custom->appearance[‘readonly_attrs’]で編集画面で、表示される属性をリードオンリーに。上と同じ属性を列挙したので、結局は表示されないのですが、念の為

  • $servers->setValue(‘login’,’bind_id’,’cn=admin,dc=example,dc=org’);をコメントアウトして、ログイン画面で自動補完されるadmin情報を無効に

  • $servers->setValue(‘login’,’attr’,’uid’);で、ログイン画面でのアカウント名の指定をuidだけでOKに

  • +$servers->setValue(‘login’,’anon_bind’,false);で匿名ユーザでのログインを無効に

以上でユーザ用のパスワード変更画面を用意できます。パスワード忘れた時の再発行はこれではユーザ自身で解決することはできませんが、それでもまぁかなり楽ですね。

1

このやり方では参考にしたブログにもある通り、検索したり、子ノードを走査すれば”見える”のですが、見えたところで別に変更できるわけではないので、そこはまぁそこまでやる必要はないので妥協。

ExcelファイルからLDIFを生成する。

Excelで管理しているユーザリストを用いて、LDIFに変換するのに、なんか良いコマンドラインのツールないかなぁと思ったら、 @ITの記事で紹介されていた ExcelからHTMLやCSVなどに変換可能なxlhtmlというツールが使えそうなので、これを使ってタブ区切りでawkでLDIFに変換するスクリプトを作ったので、それらのポイントをメモっておきました。

まず、xlhtmlはDebianならSqueezeでも含まれているので、参考にした記事とは違い、余計な外部リポジトリを使わなくてもapt-getコマンド一発で導入できます。

$ sudo apt-get install xlhtml

とりあえず、LDIFに変換するためにタブ区切りのテキストファイルにします。 1

$ xlhtml -asc -xp:0 memberlist.xls > memberlist.txt

今回のデータは1行が1ユーザの情報になっており、対象としたいユーザは特定のカラム(Y列(25列目))がフラグとして1になっています。また、氏名(B列(2列目))は、全角スペースを区切り文字として”姓 名”となっているので、ユーザ定義関数を作り、文字列の変換を行いました 2 。また、ここでは、初期パスワードを変数seedに適当な文字列とuseridを連結したものにして、system()でslappasswdで生成しています。その一行前のuserPassword:はprintfで意図的に改行させないようにしています。

# filtering with FLAG($25) is 1
# $1 : userid
# $2 : FullName
# $5 : department name
# $17: email
# $34: admin
# $35: author
# $36: moderator

# convert member LDIF
awk -F '\t' '$25 == 1 {
        seed = "initialpasswrd"
        print "dn: uid=" $1 ",ou=People,o=hoge,dc=example,dc=org"
        print "uid: " $1
        print "objectClass: inetOrgPerson"
        print "objectClass: posixAccount"
        print "objectClass: top"
        printf "userPassword: "
        system("/usr/sbin/slappasswd -h '{SHA}' -s " seed $1)
        print "loginShell: /bin/false"
        print "uidNumber: " $1
        print "gidNumber: 10005"
        print "homeDirectory: /noexistence"
        print "o: " $5
        name($2)
        print "cn: " $1
        print "mail: " $17
        print ""
}

# separate LastName, FirstName from fullname
function name(fullname){
        # Convert Zenkaku_space to hankaku_space.
        sub(" "," ",fullname)
        # extract & print last name.
        print "sn: " substr(fullname,1,index(fullname," "))
        # extract first name
        sub(/^.* /,"",fullname)
        # print first name
        print "gn: " fullname
        return
}
' temp.txt > user.ldif
ldapadd -f user.ldif -D "cn=admin,dc=example,dc=org" -W

生成したuser.ldifをldapaddコマンドで追加します。

複数グループの設定は、あらかじめ作っておいたグループに、memberUidにA列(1列目)の値を指定します。

# add other group
awk -F '\t' '
# admin
$34 == 1 {
        print "dn: cn=admin,ou=Group,o=hoge,dc=example,dc=org"
        print "changetype: modify"
        print "add: memberUid"
        print "memberUid: " $1
        print ""
}
$35 == 1 {
(snip)
}
' temp.txt > group-mod.ldif
ldapmodify -f group-mod.ldif  -D "cn=admin,dc=example,dc=org" -W

生成したgroup-mod.ldifをldapmodifyコマンドで反映します。

objectClassでposixAccountを使用する主目的であるadminグループのユーザにはシェルログインを許可するために、ユーザ情報を変更します。

awk -F '\t' '
$34 == 1 {
        print "dn: uid=U" $1 ",ou=People,o=hoge,dc=example,dc=org"
        print "changetype: modify"
        print "replace: homeDirectory"
        print "homeDirectory: /home/" $1
        print ""

        print "dn: uid=U" $1 ",ou=People,o=hoge,dc=example,dc=org"
        print "changetype: modify"
        print "replace: loginShell"
        print "loginShell: /bin/bash"
        print ""
}' temp.txt > admin.ldif
ldapmodify -f admin.ldif  -D "cn=admin,dc=example,dc=org" -W

てな感じです。今回のユーザアカウントのLDIFではsnやgn、mailを使っていますが、これはWordPressのユーザ管理もSimple LDAP Authentication プラグインを使ってLDAPで行うためです。

シェルスクリプトは、githubに置いておこうかと思ったのですが、そもそもExcelでユーザ情報を管理しているのがいかがなもんかと思うので、まぁ必要ないですよね 3

1

CSVにしないのは、変換元のデータに、,(カンマ)含まれているからです。

2

function name()のこと。

3

今回は、他の組織がExcelで管理している一次情報から、自分たちに必要な情報に加工して使用するという運用になっているので、元のデータが結局Excelから変更されないと、二次情報のデータをいくらExcelから変更しても意味ないので、Excelから変換するやりかたにしました。