The branch, master has been updated via a23b0f36e52f8f1bf0f288179a2a0972c75c61e6 (commit) from 174a5f438ecae2dda3e95c40c4be001c7051ae1f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a23b0f36e52f8f1bf0f288179a2a0972c75c61e6 Author: Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> Date: Wed Jan 23 14:12:34 2013 +0100 support for BIRTHDAY Argument in user administration module ldap backend for x2goadminserver ----------------------------------------------------------------------- Summary of changes: debian/changelog | 5 + .../x2gouseradmingui/.kdev4/x2gouseradmingui.kdev4 | 5 - .../modules/x2gouseradmingui/x2gouseradminui.ui | 23 +- .../x2gouseradmingui/x2gouseradminwindow.cpp | 62 +- x2goadminserver/etc/x2goadminserver.conf | 13 +- x2goadminserver/lib/x2goadminserver.pm | 7 +- .../lib/x2goadminserver_backend_ldap.pm | 759 ++++++++++++++++++++ 7 files changed, 841 insertions(+), 33 deletions(-) delete mode 100644 x2goadmincenter/modules/x2gouseradmingui/.kdev4/x2gouseradmingui.kdev4 create mode 100644 x2goadminserver/lib/x2goadminserver_backend_ldap.pm The diff of changes is: diff --git a/debian/changelog b/debian/changelog index 31b69af..11f7f1c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,6 @@ x2goadmincenter (0.0.0.1-0~x2go1) UNRELEASED; urgency=low + [ Mike Gabriel ] * Initial package build for Debian/Ubuntu. * /debian/control: + Maintainer change in package: X2Go Developers <x2go-dev@lists.berlios.de>. @@ -7,4 +8,8 @@ x2goadmincenter (0.0.0.1-0~x2go1) UNRELEASED; urgency=low + x2goadminserver package is arch-indep, description fixes in control file. + Priority: optional. + [ Oleksandr Shneyder ] + * support for BIRTHDAY Argument in user administration module + ldap backend for x2goadminserver + -- Mike Gabriel <mike.gabriel@das-netzwerkteam.de> Wed, 21 Sep 2011 21:12:56 +0200 diff --git a/x2goadmincenter/modules/x2gouseradmingui/.kdev4/x2gouseradmingui.kdev4 b/x2goadmincenter/modules/x2gouseradmingui/.kdev4/x2gouseradmingui.kdev4 deleted file mode 100644 index e927c4c..0000000 --- a/x2goadmincenter/modules/x2gouseradmingui/.kdev4/x2gouseradmingui.kdev4 +++ /dev/null @@ -1,5 +0,0 @@ -[Buildset] -BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00 \x00x\x002\x00g\x00o\x00u\x00s\x00e\x00r\x00a\x00d\x00m\x00i\x00n\x00g\x00u\x00i) - -[Launch] -Launch Configurations= diff --git a/x2goadmincenter/modules/x2gouseradmingui/x2gouseradminui.ui b/x2goadmincenter/modules/x2gouseradmingui/x2gouseradminui.ui index 9ade285..290c60d 100644 --- a/x2goadmincenter/modules/x2gouseradmingui/x2gouseradminui.ui +++ b/x2goadmincenter/modules/x2gouseradmingui/x2gouseradminui.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>614</width> - <height>629</height> + <width>766</width> + <height>697</height> </rect> </property> <property name="windowTitle"> @@ -59,9 +59,6 @@ <attribute name="headerMinimumSectionSize"> <number>0</number> </attribute> - <attribute name="headerMinimumSectionSize"> - <number>0</number> - </attribute> <column> <property name="text"> <string notr="true">Userpic</string> @@ -312,7 +309,21 @@ </widget> </item> <item row="2" column="1"> - <widget class="QDateEdit" name="dateBirthday"/> + <widget class="QDateEdit" name="dateBirthday"> + <property name="maximumDate"> + <date> + <year>7999</year> + <month>12</month> + <day>31</day> + </date> + </property> + <property name="displayFormat"> + <string>dd.MM.yyyy</string> + </property> + <property name="calendarPopup"> + <bool>true</bool> + </property> + </widget> </item> </layout> </widget> diff --git a/x2goadmincenter/modules/x2gouseradmingui/x2gouseradminwindow.cpp b/x2goadmincenter/modules/x2gouseradmingui/x2gouseradminwindow.cpp index 57bc3b1..148f1b0 100644 --- a/x2goadmincenter/modules/x2gouseradmingui/x2gouseradminwindow.cpp +++ b/x2goadmincenter/modules/x2gouseradmingui/x2gouseradminwindow.cpp @@ -49,7 +49,7 @@ void X2GouserAdminWindow::installTranslator() if ( !qtTranslator->load ( filename ) ) { qDebug()<< "Can't load translator "<< - filename.toLocal8Bit().data() ; + filename.toLocal8Bit().data() ; } else { @@ -261,7 +261,7 @@ bool X2GouserAdminWindow::checkResult(const QString& result) void X2GouserAdminWindow::initUserAttr(const QString& attrString) { - for (int i=0; i< USERATTR;++i) + for (int i=0; i< USERATTR; ++i) { userAttributes[i].editable=false; userAttributes[i].supported=false; @@ -331,7 +331,7 @@ void X2GouserAdminWindow::slotChangePass() void X2GouserAdminWindow::slotSaveGroupSelection() { QStringList groups; - for (int i=0;i<lselGroup->count();++i) + for (int i=0; i<lselGroup->count(); ++i) groups<<lselGroup->item(i)->text(); QSettings* st=centerInstance->getSettings(pluginName()); st->setValue("preselectedgroups",groups); @@ -434,6 +434,7 @@ void X2GouserAdminWindow::initUserList(const QString& res) QStringList udetails=uentry.split(":",QString::SkipEmptyParts); QString detail; struct user us; + us.birthday="1970-01-01"; foreach(detail,udetails) { QStringList fields=detail.split("="); @@ -453,6 +454,8 @@ void X2GouserAdminWindow::initUserList(const QString& res) us.home=value; if (name == "SHELL") us.shell=value; + if (name == "BIRTHDAY") + us.birthday=value; } listOfUsers<<us; } @@ -489,7 +492,7 @@ void X2GouserAdminWindow::initUserList(const QString& res) int numOfItems=0; if (userAttributes[PGROUP].supported) { - for (int i=0;i<listOfUsers.count();++i) + for (int i=0; i<listOfUsers.count(); ++i) { if (listOfUsers[i].group==gid) { @@ -525,11 +528,10 @@ void X2GouserAdminWindow::initUserList(const QString& res) foreach(uentry, ulist) { QTreeWidgetItem* it=new QTreeWidgetItem ( treeWidget ); - - QStringList udetails=uentry.split(":",QString::SkipEmptyParts); QString detail; struct user us; + us.birthday="1970-01-01"; foreach(detail,udetails) { QStringList fields=detail.split("="); @@ -549,6 +551,8 @@ void X2GouserAdminWindow::initUserList(const QString& res) us.home=value; if (name == "SHELL") us.shell=value; + if (name == "BIRTHDAY") + us.birthday=value; } setUserItem(it,&us); } @@ -730,19 +734,17 @@ void X2GouserAdminWindow::slotFindUser() } if (searchlogin && (! login.contains(slogin,Qt::CaseInsensitive))) (*it)->setHidden(true); - else - if (searchname && (!name.contains(sname,Qt::CaseInsensitive))) - (*it)->setHidden(true); - else - if (cbTree->isChecked()) - (*it)->parent()->setExpanded(true); + else if (searchname && (!name.contains(sname,Qt::CaseInsensitive))) + (*it)->setHidden(true); + else if (cbTree->isChecked()) + (*it)->parent()->setExpanded(true); ++it; } } bool X2GouserAdminWindow::stringIsAscii(const QString& str) { QByteArray ba=str.toAscii(); - for (int i=0; i<ba.size();++i) + for (int i=0; i<ba.size(); ++i) if (!isascii(ba[i])) return false; return true; @@ -822,6 +824,7 @@ void X2GouserAdminWindow::slotUserSelected(QTreeWidgetItem* item , int col) return; } } + dateBirthday->setDate(QDate(1970,1,1)); if (item) { eLogin->setText(item->data(COL_LOGIN,LOGINROLE).toString()); @@ -872,6 +875,13 @@ void X2GouserAdminWindow::slotUserSelected(QTreeWidgetItem* item , int col) currentUser.pgroup=item->data(COL_LOGIN,PGROUPROLE).toString(); cbPGroup->setEnabled(userAttributes[PGROUP].editable); } + if (userAttributes[BIRTHDAY].supported) + { + dateBirthday->setDate(item->data(COL_LOGIN,BIRTHDAYROLE).toDate()); + dateBirthday->setReadOnly(!userAttributes[BIRTHDAY].editable); + currentUser.birthday=item->data(COL_LOGIN,BIRTHDAYROLE).toDate(); + } + } else { @@ -901,6 +911,11 @@ void X2GouserAdminWindow::slotUserSelected(QTreeWidgetItem* item , int col) eShell->setText("/bin/bash"); eShell->setReadOnly(false); } + if (userAttributes[BIRTHDAY].supported) + { + dateBirthday->setDate(QDate()); + eShell->setReadOnly(false); + } if (userAttributes[PGROUP].supported) { cbPGroup->setEnabled(true); @@ -948,7 +963,7 @@ void X2GouserAdminWindow::slotUserSelected(QTreeWidgetItem* item , int col) void X2GouserAdminWindow::slotAddGroup() { - for (int i=lunselGroup->count()-1;i >= 0; --i) + for (int i=lunselGroup->count()-1; i >= 0; --i) { if (lunselGroup->item(i)->isSelected()) { @@ -964,7 +979,7 @@ void X2GouserAdminWindow::slotAddGroup() void X2GouserAdminWindow::slotRemoveGroup() { - for (int i=lselGroup->count()-1;i >= 0; --i) + for (int i=lselGroup->count()-1; i >= 0; --i) { if (lselGroup->item(i)->isSelected()) { @@ -990,6 +1005,7 @@ void X2GouserAdminWindow::slotApply() //add support for other atributes QVariantList args; QString fname,lname,login,uidnumber,pgroup,homedir,shell; + QDate birthday; login=eLogin->text(); if (currentUser.newUser) @@ -1012,6 +1028,14 @@ void X2GouserAdminWindow::slotApply() args<<"fname:"+fname; } } + if (userAttributes[BIRTHDAY].supported) + { + birthday=dateBirthday->date(); + if (currentUser.birthday != birthday || currentUser.newUser) + { + args<<"birthday:"+birthday.toString("yyyy-MM-dd"); + } + } if (userAttributes[LNAME].supported) { lname=eLname->text(); @@ -1059,6 +1083,8 @@ void X2GouserAdminWindow::slotApply() } } + + if (userAttributes[PGROUP].supported) { pgroup=cbPGroup->currentText(); @@ -1098,7 +1124,7 @@ void X2GouserAdminWindow::slotApply() QStringList newGroups; QStringList selGroups; - for (int i=0;i<lselGroup->count();++i) + for (int i=0; i<lselGroup->count(); ++i) { selGroups<<lselGroup->item(i)->text(); if (!currentUser.groups.contains(lselGroup->item(i)->text())) @@ -1107,7 +1133,7 @@ void X2GouserAdminWindow::slotApply() if (newGroups.count()) args<<"newgroups:"+newGroups.join(";"); QStringList obsoleteGroups; - for (int i=0; i<currentUser.groups.count();++i) + for (int i=0; i<currentUser.groups.count(); ++i) { if (!selGroups.contains(currentUser.groups[i])) obsoleteGroups<<currentUser.groups[i]; @@ -1240,7 +1266,7 @@ void X2GouserAdminWindow::slotChangePrimaryGroup(const QString& group) { delete items[0]; } - for (int i=0;i<cbPGroup->count();++i) + for (int i=0; i<cbPGroup->count(); ++i) { QString grp=cbPGroup->itemText(i); if (grp==group) diff --git a/x2goadminserver/etc/x2goadminserver.conf b/x2goadminserver/etc/x2goadminserver.conf index 7a8b536..e7723bd 100644 --- a/x2goadminserver/etc/x2goadminserver.conf +++ b/x2goadminserver/etc/x2goadminserver.conf @@ -17,8 +17,15 @@ # Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. -backend=cipux +#backend=cipux -[cipux_backend] -url=http://localhost:8001/RPC2 +#[cipux_backend] +#url=http://localhost:8001/RPC2 +backend=x2goldap + +[x2goldap] +url=ldap://localhost +basedn="o=Gymnasium Bruckmuehl,c=de" +smbgroup=S-1-5-21-820157184-2864210838-2273796612-513 +sid=S-1-5-21-820157184-2864210838-2273796612 diff --git a/x2goadminserver/lib/x2goadminserver.pm b/x2goadminserver/lib/x2goadminserver.pm index 2829419..ec6ce77 100644 --- a/x2goadminserver/lib/x2goadminserver.pm +++ b/x2goadminserver/lib/x2goadminserver.pm @@ -26,11 +26,16 @@ $Config->read('/etc/x2go/x2goadminserver.conf' ) or die "Could not be read: /etc my $backend=$Config->param("backend"); use lib "/usr/lib/x2go"; + if($backend eq "cipux" ) { - use x2goadminserver_backend_cipux; + eval "use x2goadminserver_backend_cipux"; die $@ if $@; } +if($backend eq "x2goldap" ) +{ + eval "use x2goadminserver_backend_ldap"; die $@ if $@; +} use base 'Exporter'; our @EXPORT=('x2goadmin_getUsers','x2goadmin_getGroups', 'x2goadmin_getGroupsOfUser','x2goadmin_getGroupsWithUsers', diff --git a/x2goadminserver/lib/x2goadminserver_backend_ldap.pm b/x2goadminserver/lib/x2goadminserver_backend_ldap.pm new file mode 100644 index 0000000..2a415a9 --- /dev/null +++ b/x2goadminserver/lib/x2goadminserver_backend_ldap.pm @@ -0,0 +1,759 @@ +# Copyright (C) 2010-2011 by Oleksandr Shneyder <oleksandr.shneyder@obviously-nice.de> +# Copyright (C) 2010-2011 by Heinz-M. Graesing <heinz-m.graesing@obviously-nice.de> + +# X2go Admin Server is free software; you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# X2go Admin Server is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> +# or write to +# Free Software Foundation, Inc., +# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + + +package x2goadminserver_backend_ldap; + +use Exporter 'import'; +@EXPORT= qw(getUsers getGroups getGroupsOfUser getGroupsWithUsers modifyUser modifyGroup addUser addGroup removeUsers removeGroups); + +use strict; +use Config::Simple; +use English qw( -no_match_vars); +use Net::LDAP; +use Crypt::SaltedHash; +use Crypt::SmbHash; +use MIME::Base64; +use Data::Dumper; +use Unicode::Normalize; +use utf8; +use Frontier::RPC2; +use Encode; + +my $Config = new Config::Simple(syntax=>'ini'); +$Config->read('/etc/x2go/x2goadminserver.conf' ) or die "/etc/x2go/x2goadminserver.conf"; +my $url=$Config->param("x2goldap.url"); +my $basedn=$Config->param("x2goldap.basedn"); +my $sambagroup=$Config->param("x2goldap.smbgroup"); +my $sid=$Config->param("x2goldap.sid"); + + +my $ldap; + + + +sub normalized +{ + my $string=shift; + my $newstr; + my %umlaute = ("ä" => "ae", "Ä" => "Ae", "ü" => "ue", "Ü" => "Ue", "ö" => "oe", "Ö" => "Oe", "ß" => "ss" ); + my $umlautkeys = join ("|", keys(%umlaute)); + $string =~ s/($umlautkeys)/$umlaute{$1}/g; + my @chars = split(//,"$string"); + foreach(@chars) + { + my $decomp=NFKD($_); + $decomp=~ /^(.)/; + $newstr=$newstr.$1; + } + return $newstr; +} + + +sub getUserName +{ + my $dn=shift; + my ($cn,$sn); + my $message=$ldap->search(base => $dn, scope => 'base', filter => '(objectClass=posixAccount)'); + if($message->code) + { + return ($message->code,$message->error_desc, $cn, $sn); + } + foreach ($message->entries) + { + my $asn=$_->{'asn'}; + my $attr=$asn->{'attributes'}; + my @userdata; + foreach (@$attr) + { + my $type=$_->{'type'}; + my $vals=$_->{'vals'}; + if($type eq "givenName") + { + $cn=decode("utf-8", @$vals[0]); + } + if($type eq "sn") + { + $sn=decode("utf-8", @$vals[0]); + } + } + } + return ($message->code,$message->error_desc, $cn, $sn); +} + +sub getGid +{ + my $dn=shift; + my $gid; + my $message=$ldap->search(base => $dn, scope => 'base', filter => '(objectClass=posixGroup)'); + if($message->code) + { + return ($message->code,$message->error_desc, $gid); + } + foreach ($message->entries) + { + my $asn=$_->{'asn'}; + my $attr=$asn->{'attributes'}; + my @userdata; + foreach (@$attr) + { + my $type=$_->{'type'}; + my $vals=$_->{'vals'}; + if($type eq "gidNumber") + { + $gid=@$vals[0]; + } + } + } + return ($message->code,$message->error_desc, $gid); +} + + +sub addUserToGroup +{ + my ($dn,$user)=@_; + my $message=$ldap->modify($dn, add => {memberUid => $user}); + return ($message->code,$message->error_desc); +} + +sub removeUserFromGroup +{ + my ($dn,$user)=@_; + my $message=$ldap->modify($dn, delete => {memberUid => $user}); + return ($message->code,$message->error_desc); +} + +sub addUser +{ + return addModifyUser('add',@_); +} + +sub modifyUser +{ + return addModifyUser('modify',@_); +} + + +sub addModifyUser +{ + + my ($mode,$login,$password,$user, @args)=@_; + my $retmsg="OK"; + + my ($status,$str)=getServerInfo($login, $password); + if(!$status) + { + return $str; + } + my $modsn=0; + my $modcn=0; + my $attr={}; + my @newgrp; + my @obsgrp; + my $userUidNumber; + foreach (@args) + { + my @cmd=split(":",$_); + if(@cmd[0] eq "loginshell") + { + $attr->{'loginShell'}=@cmd[1]; + } + if(@cmd[0] eq "uidnumber") + { + $attr->{'uidNumber'}=@cmd[1]; + $userUidNumber=@cmd[1]; + } + if(@cmd[0] eq "homedirectory") + { + $attr->{'homeDirectory'}=@cmd[1]; + } + if(@cmd[0] eq "birthday") + { + $attr->{'o'}=@cmd[1]; + } + if(@cmd[0] eq "password") + { + my $csh = Crypt::SaltedHash->new(algorithm => 'SHA-1'); + $csh->add(@cmd[1]); + $attr->{'userPassword'}=$csh->generate; + my ( $lm, $nt ) = ntlmgen (@cmd[1]); + $attr->{'sambaNTPassword'}=$nt; + $attr->{'sambaLMPassword'}=$lm; + $attr->{'sambaPwdLastSet'}=time; + ###set samba passwords and flags + } + if(@cmd[0] eq "fname") + { + $attr->{'givenName'}=@cmd[1]; + $modcn=@cmd[1]; + } + if(@cmd[0] eq "lname") + { + $attr->{'sn'}=@cmd[1]; + $modsn=@cmd[1]; + } + if(@cmd[0] eq "newgroups") + { + @newgrp=split(";",@cmd[1]); + } + if(@cmd[0] eq "obsoletegroups") + { + @obsgrp=split(";",@cmd[1]); + } + if(@cmd[0] eq "primarygroup") + { + my ($code, $msg, $gid)=getGid("cn=@cmd[1],ou=Group,$basedn"); + if($code) + { + return ("CMDERR "." ".$msg); + } + $attr->{'gidNumber'}=$gid; + } + } + if($modcn || $modsn) + { + if(!($modcn && $modsn)) + { + my ($code, $msg, $cn, $sn)=getUserName("uid=$user,ou=People,$basedn"); + if($code) + { + return ("CMDERR "." ".$msg); + } + if(!$modcn) + { + $modcn=$cn; + } + if(!$modsn) + { + $modsn=$sn; + } + } + $attr->{'gecos'}=normalized($modcn." ".$modsn); + $attr->{'cn'}=$modcn." ".$modsn; + $attr->{'description'}=$modcn." ".$modsn; + $attr->{'displayName'}=$modcn." ".$modsn; + } + my $message; + if($mode eq 'modify') + { + $message=$ldap->modify("uid=$user,ou=People,$basedn", replace => $attr ); + } + else + { + my $arr; + while( my ($key, $value) = each (%$attr)) + { + push(@$arr,$key=>$value); + } + push(@$arr,uid=>$user); + + my $winmagic = 2147483647; + my $valpwdcanchange = 0; + my $valpwdmustchange = $winmagic; + my $valpwdlastset = 0; + my $valacctflags = "[UX]"; + my $userRid=2 * $userUidNumber + 1000; + + push(@$arr, sambaPwdLastSet => "$valpwdlastset"); + push(@$arr, sambaLogonTime => '0'); + push(@$arr, sambaLogoffTime => '2147483647'); + push(@$arr, sambaKickoffTime => '2147483647'); + push(@$arr, sambaPwdCanChange => "$valpwdcanchange"); + push(@$arr, sambaPwdMustChange => "$valpwdmustchange"); + push(@$arr, sambaAcctFlags => "$valacctflags"); + push(@$arr, sambaSID => "$sid-$userRid"); + push(@$arr, sambaPrimaryGroupSID => $sambagroup); + push(@$arr, sambaLMPassword => "XXX"); + push(@$arr, sambaNTPassword => "XXX"); + + push(@$arr, userPassword=>'XXX'); + push(@$arr, objectClass=>['top','inetOrgPerson','posixAccount', 'shadowAccount', 'sambaSamAccount']); + $message=$ldap->add("uid=$user,ou=People,$basedn", attr => $arr); + } + if($message->code) + { + return ("CMDERR "." ".$message->error_desc()); + } + + foreach (@newgrp) + { + my ($code, $msg)=addUserToGroup("cn=$_,ou=Group,$basedn", $user); + if($code) + { + return ("CMDERR "." ".$msg); + } + } + + foreach (@obsgrp) + { + my ($code, $msg)=removeUserFromGroup("cn=$_,ou=Group,$basedn", $user); + if($code) + { + return ("CMDERR "." ".$msg); + } + } + $ldap->unbind(); + return $retmsg; +} + + + +sub getGroupsOfUser +{ + my ($login, $password, $user) = @_; + my ($status,$str)=getServerInfo($login, $password); + + if(!$status) + { + return $str; + } + my $message=$ldap->search( + base => "ou=Group,$basedn", + filter => '(objectClass=posixGroup)' + ); + $str=""; + if($message->code) + { + return ("CMDERR "." ".$message->error_desc()); + } + foreach ($message->entries) + { + my $grp; + my $exists="0"; + my $gid="0"; + my $asn=$_->{'asn'}; + my $attr=$asn->{'attributes'}; + foreach (@$attr) + { + my $type=$_->{'type'}; + my $vals=$_->{'vals'}; + if($type eq "cn") + { + $grp=@$vals[0]; + } + if($type eq "gidNumber") + { + $gid=@$vals[0]; + } + if($type eq "memberUid") + { + if(grep { $_ eq $user} @$vals) + { + $exists="1"; + } + } + } + $str=$str."\n".$grp.":$exists:$gid"; + } + + $ldap->unbind(); + return $str; +} + + +sub getGroupsWithUsers +{ + my ($login, $password) = @_; + my ($status,$str)=getServerInfo($login, $password); + if(!$status) + { + return $str; + } + $str=userAttributes(); + + $str=$str."\nBEGIN_USERS"; + my ($code, $desc, $result)=getAllUsers($login); + if($code) + { + return ("CMDERR "." ".$desc); + } + $str=$str.$result."\nEND_USERS"; + + $str=$str."\nBEGIN_GROUPS\n"; + ($code, $desc, $result)=getAllGroupsWithUser($login); + if($code) + { + return ("CMDERR "." ".$desc); + } + $str=$str.$result."\nEND_GROUPS\n"; + $ldap->unbind(); + return $str; +} + +sub getAllGroupsWithUser +{ + my $login=shift; + my $str; + my $message=$ldap->search( + base => "ou=Group,$basedn", + filter => '(objectClass=posixGroup)' ); + + if(!$message->code) + { + foreach ($message->entries) + { + my $asn=$_->{'asn'}; + my $attr=$asn->{'attributes'}; + my ($name,$gid,$desc,$members); + foreach (@$attr) + { + my $type=$_->{'type'}; + my $vals=$_->{'vals'}; + + if($type eq "cn") + { + $name=@$vals[0]; + } + if($type eq "gidNumber") + { + $gid=@$vals[0]; + } + if($type eq "description") + { + $desc=@$vals[0]; + } + if($type eq "memberUid") + { + $members=join(";",@$vals); + } + } + $str=$str."\nNAME=".$name.":GID=".$gid.":DESC=".$desc.":MEMBERS=".$members; + } + } + return ($message->code, $message->error_desc, $str); +} + +sub getUsers +{ + my ($login, $password) = @_; + my ($status,$str)=getServerInfo($login, $password); + if(!$status) + { + return $str; + } + + $str=userAttributes(); + $str=$str."\nBEGIN_USERS"; + + my ($code, $desc, $result)=getAllUsers($login); + if($code) + { + return ("CMDERR "." ".$desc); + } + $str=$str.$result."\nEND_USERS"; + + $ldap->unbind(); + + return $str; +} + +sub getAllUsers +{ + my $login=shift; + my $message=$ldap->search( + base => "ou=People,$basedn", + filter => '(objectClass=posixAccount)' ); + + my $str; + if($message->code) + { + return ($message->code, $message->error_desc(),$str); + } + + foreach ($message->entries) + { + my $asn=$_->{'asn'}; + my $attr=$asn->{'attributes'}; + my @userdata; + foreach (@$attr) + { + my $type=$_->{'type'}; + my $vals=$_->{'vals'}; + if($type eq "givenName") + { + push(@userdata,decode("utf-8", "FNAME=@$vals[0]")); + } + if($type eq "sn") + { + push(@userdata,decode("utf-8", "LNAME=@$vals[0]")); + } + if($type eq "gidNumber") + { + push(@userdata,"GID=@$vals[0]"); + } + if($type eq "homeDirectory") + { + push(@userdata,"HOME=@$vals[0]"); + } + if($type eq "uid") + { + push(@userdata,"UID=@$vals[0]"); + } + if($type eq "uidNumber") + { + push(@userdata,"UIDNUMBER=@$vals[0]"); + } + if($type eq "loginShell") + { + push(@userdata,"SHELL=@$vals[0]"); + } + if($type eq "o") + { + push(@userdata,"BIRTHDAY=@$vals[0]"); + } + } + $str=$str."\n".join(":",@userdata); + } + return ($message->code, $message->error_desc(),$str); +} + +sub getServerInfo +{ + my ($login, $password) = @_; + $ldap=Net::LDAP->new( $url ); + if(!$ldap) + { + return (0, "SERVERDOWN URL:$url ERROR:$@"); + } + + my $message=$ldap->bind( $login, password => $password); + if($message->code) + { + return (0, "NOACCESS"." ".$message->error_desc()); + } + return (1,"OK"); +} + + +sub userAttributes +{ + return "BEGIN_USERATTR\ +uid:edit=0;unicode=0\ +uidnumber:edit=0;unicode=0\ +firstname:edit=1;unicode=1\ +lastname:edit=1;unicode=1\ +group:edit=1;unicode=0\ +home:edit=1;unicode=0\ +shell:edit=1;unicode=0\ +birthday:edit=1;unicode=0\ +END_USERATTR"; +} + +sub groupAttributes +{ + return "BEGIN_GROUPATTR\ +name:edit=0;unicode=0\ +description:edit=1;oncreate=1;unicode=0\ +members:edit=1;oncreate=1\ +gid:edit=1;oncreate=1\ +END_GROUPATTR"; +} + +sub getGroups +{ + my ($login, $password) = @_; + my ($status,$str)=getServerInfo($login, $password); + if(!$status) + { + return $str; + } + $str=groupAttributes(); + + $str=$str."\nBEGIN_USERS"; + my ($code, $desc, $result)=getAllUsers($login); + if($code) + { + return ("CMDERR "." ".$desc); + } + $str=$str.$result."\nEND_USERS"; + + $str=$str."\nBEGIN_GROUPS\n"; + ($code, $desc, $result)=getAllGroupsWithUser($login); + if($code) + { + return ("CMDERR "." ".$desc); + } + $str=$str.$result."\nEND_GROUPS\n"; + $ldap->unbind(); + return $str; +} + + +sub removeUsers +{ + my ($login, $password, $users) = @_; + my ($status,$str)=getServerInfo($login, $password); + if(!$status) + { + return $str; + } + my @ulist=split(";",$users); + my $message=$ldap->search( + base => "ou=Group,$basedn", + filter => '(objectClass=posixGroup)' ); + + if($message->code) + { + return ("CMDERR "." ".$message->error_desc()); + } + $str="OK"; + foreach ($message->entries) + { + my $asn=$_->{'asn'}; + my $attr=$asn->{'attributes'}; + foreach (@$attr) + { + my $type=$_->{'type'}; + my $vals=$_->{'vals'}; + if($type eq "cn") + { + my $grp=@$vals[0]; + my $message=$ldap->modify("cn=$grp,ou=Group,$basedn", + delete => {memberUid => \@ulist}); + } + } + } + foreach(@ulist) + { + my $message=$ldap->delete("uid=$_,ou=People,$basedn"); + if($message->code) + { + return ("CMDERR "." ".$message->error_desc()); + } + } + $ldap->unbind(); + return "$str"; +} + +sub removeGroups +{ + my ($login, $password, $groups) = @_; + my ($status,$str)=getServerInfo($login, $password); + if(!$status) + { + return $str; + } + my @glist=split(";",$groups); + foreach(@glist) + { + my $message=$ldap->delete("cn=$_,ou=Group,$basedn"); + if($message->code) + { + return ("CMDERR "." ".$message->error_desc()); + } + } + return "OK"; +} + + +sub modifyGroup +{ + return addModifyGroup('modify',@_); +} + +sub addGroup +{ + return addModifyGroup('add',@_); +} + +sub addModifyGroup +{ + my ($mode, $login,$password,$group,@args)=@_; + my ($status,$str)=getServerInfo($login, $password); + if(!$status) + { + return $str; + } + my $attr; + my $addAttr; + my $rmAttr; + my $add=0; + my $rm=0; + my $mod=0; + + foreach (@args) + { + $str=$str."\n".$_; + my @cmd=split(":",$_); + if(@cmd[0] eq "description") + { + push(@$attr,'description'=>@cmd[1]); + $mod=1; + } + if(@cmd[0] eq "gid") + { + push(@$attr,'gidNumber'=>@cmd[1]); + $mod=1; + } + if(@cmd[0] eq "newmembers") + { + my $arr; + @$arr=split(";",@cmd[1]); + push(@$addAttr,'memberUid'=>$arr); + $add=1; + } + if(@cmd[0] eq "obsoletemembers") + { + my $arr; + @$arr=split(";",@cmd[1]); + push(@$rmAttr,'memberUid'=>$arr); + $rm=1; + } + } + + my $message; + if($mode eq 'modify') + { + my $changes; + if($mod) + { + push(@$changes,'replace'=>$attr); + } + if($add) + { + push(@$changes,'add'=>$addAttr); + } + if($rm) + { + push(@$changes,'delete'=>$rmAttr); + } + $message=$ldap->modify("cn=$group,ou=Group,$basedn", + changes => $changes ); + } + else + { + push(@$attr,cn=>$group); + foreach(@$addAttr) + { + push(@$attr, $_); + } + push(@$attr,objectClass=>['top','posixGroup']); + $message=$ldap->add("cn=$group,ou=Group,$basedn", + attr => $attr); + } + if($message->code) + { + return ("CMDERR "." ".$message->error_desc()); + } + $ldap->unbind(); + return $str; +} + + +return 1; \ No newline at end of file hooks/post-receive -- x2goadmincenter.git (X2Go Administration Center) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "x2goadmincenter.git" (X2Go Administration Center).