zentyal-users-2.3.15+quantal1/0000775000000000000000000000000012017154745013047 5ustar zentyal-users-2.3.15+quantal1/COPYING0000664000000000000000000004311012017154745014101 0ustar GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. zentyal-users-2.3.15+quantal1/debian/0000775000000000000000000000000012017154745014271 5ustar zentyal-users-2.3.15+quantal1/debian/compat0000664000000000000000000000000212017154745015467 0ustar 5 zentyal-users-2.3.15+quantal1/debian/copyright0000664000000000000000000000214112017154745016222 0ustar This package was debianized by Zentyal Packaging Maintainers Fri, 20 Feb 2005 15:13:22 +0100. It was downloaded from http://www.zentyal.org/ Files: * Upstream Author: eBox Technologies S.L. Copyright (C) 2004-2012 eBox Technologies S.L. License: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL-2 file. The Debian packaging is: (C) 2004-2011, Zentyal Packaging Maintainers and is licensed under the GPL, see `/usr/share/common-licenses/GPL-2'. zentyal-users-2.3.15+quantal1/debian/control0000664000000000000000000000235112017154745015675 0ustar Source: zentyal-users Section: web Priority: optional Maintainer: Zentyal Packaging Maintainers Uploaders: Jorge Salamero Sanz Build-Depends: zbuildtools Standards-Version: 3.9.2 Homepage: http://www.zentyal.org/ Vcs-Browser: http://git.zentyal.org/zentyal.git/tree/quantal:/main/users Vcs-Git: git://git.zentyal.org/zentyal.git Package: zentyal-users Architecture: all Replaces: ebox-usersandgroups (<< 2.0.100) Depends: zentyal-core (>= 2.3), zentyal-core (<< 2.3.100), zentyal-firewall, zentyal-dns, zentyal-ntp, slapd (>= 2.4.15), ldap-utils (>= 2.4.15), ldap-auth-config, slapd-smbk5pwd, libnet-ldap-perl, adduser, quota, libquota-perl, liburi-encode-perl, heimdal-kdc, libpam-heimdal, auth-client-config, ${misc:Depends} Breaks: ebox-usersandgroups (<< 2.0.100) Description: Zentyal - Users and Groups Zentyal is a Linux small business server that can act as a Gateway, Unified Threat Manager, Office Server, Infrastructure Manager, Unified Communications Server or a combination of them. One single, easy-to-use platform to manage all your network services. . This module adds a LDAP server to your Zentyal installation, allowing you to add users and groups to be used by other Zentyal modules. zentyal-users-2.3.15+quantal1/debian/source/0000775000000000000000000000000012017154745015571 5ustar zentyal-users-2.3.15+quantal1/debian/source/format0000664000000000000000000000001512017154745017000 0ustar 3.0 (native) zentyal-users-2.3.15+quantal1/debian/ebox.slapd.upstart0000664000000000000000000000033512017154745017755 0ustar pre-start script /etc/init.d/slapd stop || true end script exec /usr/sbin/slapd -d 0 -h 'ldap://0.0.0.0:390/ ldapi://%2fvar%2frun%2fslapd%2fldapi/????x-mod=0777' -u openldap -g openldap -F /etc/ldap/slapd.d/ respawn zentyal-users-2.3.15+quantal1/debian/rules0000775000000000000000000000010612017154745015346 0ustar #!/usr/bin/make -f include /usr/share/zbuildtools/1/rules/zentyal.mk zentyal-users-2.3.15+quantal1/debian/zentyal-users.postinst0000664000000000000000000000044312017154745020724 0ustar #!/bin/bash set -e #DEBHELPER# case "$1" in configure) # initial setup /usr/share/zentyal/initial-setup --no-restart users $2 # restart module invoke-rc.d zentyal users restart || true dpkg-trigger --no-await zentyal-core ;; esac exit 0 zentyal-users-2.3.15+quantal1/debian/zentyal-users.postrm0000664000000000000000000000033212017154745020362 0ustar #!/bin/bash set -e #DEBHELPER# case "$1" in purge) # purge configuration /usr/share/zentyal/purge-module users ;; remove) dpkg-trigger --no-await zentyal-core ;; esac exit 0 zentyal-users-2.3.15+quantal1/debian/changelog0000664000000000000000000003626212017154745016154 0ustar zentyal-users (2.3.15+quantal1) quantal; urgency=low * New upstream release for Quantal -- Jorge Salamero Sanz Tue, 28 Aug 2012 16:43:51 +0200 zentyal-users (2.3.15) precise; urgency=low * New upstream release -- José A. Calvo Sat, 25 Aug 2012 19:32:47 +0200 zentyal-users (2.3.14) precise; urgency=low * New upstream release -- José A. Calvo Thu, 23 Aug 2012 03:14:44 +0200 zentyal-users (2.3.13) precise; urgency=low * New upstream release -- José A. Calvo Mon, 23 Jul 2012 17:03:58 +0200 zentyal-users (2.3.12) precise; urgency=low * New upstream release -- José A. Calvo Thu, 19 Jul 2012 02:22:16 +0200 zentyal-users (2.3.11) precise; urgency=low * New upstream release -- José A. Calvo Thu, 12 Jul 2012 10:25:31 +0200 zentyal-users (2.3.10) precise; urgency=low * New upstream release -- José A. Calvo Sat, 16 Jun 2012 17:55:01 +0200 zentyal-users (2.3.9) precise; urgency=low * New upstream release -- José A. Calvo Mon, 04 Jun 2012 11:12:46 +0200 zentyal-users (2.3.8) precise; urgency=low * New upstream release -- José A. Calvo Fri, 11 May 2012 11:09:48 -0700 zentyal-users (2.3.7) precise; urgency=low * New upstream release -- José A. Calvo Mon, 16 Apr 2012 02:50:34 +0200 zentyal-users (2.3.6) precise; urgency=low * New upstream release -- José A. Calvo Mon, 26 Mar 2012 14:08:43 +0200 zentyal-users (2.3.5) precise; urgency=low * New upstream release -- José A. Calvo Thu, 22 Mar 2012 20:37:51 +0100 zentyal-users (2.3.3) precise; urgency=low * New upstream release -- José A. Calvo Tue, 13 Mar 2012 11:26:18 +0100 zentyal-users (2.3.2) precise; urgency=low * New upstream release -- José A. Calvo Tue, 06 Mar 2012 12:00:12 +0100 zentyal-users (2.3.1-1) precise; urgency=low * Updated Standard-Versions to 3.9.2 -- José A. Calvo Wed, 08 Feb 2012 16:13:36 +0100 zentyal-users (2.3.1) precise; urgency=low * New upstream release -- José A. Calvo Wed, 08 Feb 2012 10:43:26 +0100 zentyal-users (2.3) precise; urgency=low * New upstream release -- José A. Calvo Mon, 30 Jan 2012 01:46:00 +0100 zentyal-users (2.2.5) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 07 Dec 2011 00:31:11 +0100 zentyal-users (2.2.4) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 07 Nov 2011 16:09:05 +0100 zentyal-users (2.2.3) lucid; urgency=low * New upstream release -- José A. Calvo Thu, 27 Oct 2011 01:58:40 +0200 zentyal-users (2.2.2) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 18 Oct 2011 20:53:47 +0200 zentyal-users (2.2.1) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 12 Oct 2011 18:08:42 +0200 zentyal-users (2.2) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 13 Sep 2011 04:47:43 +0200 zentyal-users (2.1.14) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 12 Sep 2011 20:34:02 +0200 zentyal-users (2.1.13) lucid; urgency=low * New upstream release -- José A. Calvo Sun, 11 Sep 2011 19:01:23 +0200 zentyal-users (2.1.12) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 07 Sep 2011 00:08:48 +0200 zentyal-users (2.1.11) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 31 Aug 2011 16:54:59 +0200 zentyal-users (2.1.10) lucid; urgency=low * New upstream release -- José A. Calvo Sat, 27 Aug 2011 16:11:51 +0200 zentyal-users (2.1.9) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 24 Aug 2011 11:55:58 +0200 zentyal-users (2.1.8) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 09 Aug 2011 10:44:15 +0200 zentyal-users (2.1.7) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 20 Jul 2011 15:23:15 +0200 zentyal-users (2.1.6) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 19 Jul 2011 14:01:26 +0200 zentyal-users (2.1.5) lucid; urgency=low * New upstream release -- José A. Calvo Thu, 14 Jul 2011 18:05:21 +0200 zentyal-users (2.1.4) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 27 Jun 2011 01:18:24 +0200 zentyal-users (2.1.3) lucid; urgency=low * New upstream release -- José A. Calvo Fri, 10 Jun 2011 16:24:02 +0200 zentyal-users (2.1.2) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 10 May 2011 22:26:19 +0200 zentyal-users (2.1.1) lucid; urgency=low * New upstream release -- José A. Calvo Thu, 17 Mar 2011 00:46:20 +0100 zentyal-users (2.1) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 22 Feb 2011 03:30:10 +0100 ebox-usersandgroups (2.0.10) lucid; urgency=low * New upstream release -- José A. Calvo Sun, 09 Jan 2011 19:28:00 +0100 ebox-usersandgroups (2.0.9) lucid; urgency=low * New upstream release -- José A. Calvo Sat, 18 Dec 2010 02:06:25 +0100 ebox-usersandgroups (2.0.8) lucid; urgency=low * New upstream release -- José A. Calvo Sat, 11 Dec 2010 15:27:16 +0100 ebox-usersandgroups (2.0.7) lucid; urgency=low * New upstream release -- José A. Calvo Sun, 07 Nov 2010 19:01:12 +0100 ebox-usersandgroups (2.0.6) lucid; urgency=low * New upstream release -- José A. Calvo Thu, 04 Nov 2010 19:44:11 +0100 ebox-usersandgroups (2.0.5) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 13 Oct 2010 00:21:00 +0200 ebox-usersandgroups (2.0.4) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 12 Oct 2010 21:54:14 +0200 ebox-usersandgroups (2.0.3) lucid; urgency=low * New upstream release -- José A. Calvo Sun, 03 Oct 2010 04:00:59 +0200 ebox-usersandgroups (2.0.2) lucid; urgency=low * New upstream release -- José A. Calvo Sat, 18 Sep 2010 15:19:11 +0200 ebox-usersandgroups (2.0.1) lucid; urgency=low * New upstream release -- José A. Calvo Fri, 03 Sep 2010 22:49:25 +0200 ebox-usersandgroups (2.0) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 30 Aug 2010 22:10:15 +0200 ebox-usersandgroups (1.5.10-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Fri, 27 Aug 2010 03:09:46 +0200 ebox-usersandgroups (1.5.9-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Thu, 26 Aug 2010 16:05:24 +0200 ebox-usersandgroups (1.5.8-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 23 Aug 2010 02:26:02 +0200 ebox-usersandgroups (1.5.7-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 18 Aug 2010 17:24:11 +0200 ebox-usersandgroups (1.5.6-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Fri, 13 Aug 2010 11:37:44 +0200 ebox-usersandgroups (1.5.5-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 10 Aug 2010 16:25:35 +0200 ebox-usersandgroups (1.5.4-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 04 Aug 2010 15:46:34 +0200 ebox-usersandgroups (1.5.3-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 19 Jul 2010 12:07:54 +0200 ebox-usersandgroups (1.5.2-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Sun, 20 Jun 2010 20:40:11 +0200 ebox-usersandgroups (1.5.1-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Thu, 13 May 2010 01:33:28 +0200 ebox-usersandgroups (1.5-0ubuntu1) lucid; urgency=low [Javier Uruen Val] * New usptream release (LP: #521811) * Drop debian/patches as upstream already ships them * Drop simple-patchsys * debian/ebox-usersandgroups.postinst - Create slapd certificate * debian/control - Bump eBox depenency - Update description -- Javier Uruen Val Sun, 07 Feb 2010 18:07:46 +0100 ebox-usersandgroups (1.3.5-0ubuntu2) karmic; urgency=low [Javier Uruen Val] * debian/patches (LP: #451510) - Add 03_check_slapd_apparmor_profile.patch - Add 04_only_listen_on_lo.patch -- Javier Uruen Val Wed, 14 Oct 2009 00:04:43 +0200 ebox-usersandgroups (1.3.5-0ubuntu1) karmic; urgency=low [Javier Uruen Val] * New upstream release [LP: 411553] * cdbs/ebox.mk - GConf schemas are not used anymore - Remove SCHEMASPATH variable - Remove schemadir variable - Fix the script that copy upstart scripts - Use new upstart directory and file naming convention * debian/control - Bump standards version - Bump eBox depenency - Remove dependency on dpatch - Add dependency on libcrypt-rijndael-perl, libcrypt-smbhash-perl - Add verioned dependency on slapd (>= 2.4.15) - Add dependency on adduser * debian/ebox-usersandgroups.postinst - Fix indentation - Do not pkill gconfd as it's not necessary anymore - Run ebox trigger - Create structure for user corner - Add set -e * debian/ebox-usersandgroups.templates (To ask LDAP password) * debian/ebox-usersandgroups.postrm - Run ebox trigger - Add set -e * debian/ebox.slapd-frontend.upstart (Added) * debian/ebox.slapd-replica.upstart (Added) * debian/ebox.slapd-translucent.upstart (Added) * debian/patches - Drop dpatch system + Drop 01_ldap_conf_backend.dpatch (Already shipped by upstream) - Use simple-patch.sys + Add 01_use_shipped_authcookie.patch to enable AuthCookie + Add 02_fix_karmic_ldap_structure.path to initialize LDAP db * debian/rules - Do not include debian/cdbs/gnome.mk - Include /usr/share/cdbs/1/rules/simple-patchsys.mk * debian/watch - Change URL -- Javier Uruen Val Wed, 05 Aug 2009 12:29:43 +0200 ebox-usersandgroups (0.12.1-0ubuntu1) jaunty; urgency=low [ Javier Uruen Val ] * New upstream release. Closes (LP: #318827) * debian/watch: - add watch file. * debian/patches/01_ldap_conf_backend.dpatch - Patch to support new configuration backend in slapd -- Mathias Gug Mon, 26 Jan 2009 22:24:19 -0500 ebox-usersandgroups (0.11.99-0ubuntu5) hardy; urgency=low * debian/pattches/06_ldap_connect_retry - Try to connect to slapd several times before giving up. (LP: #220262) -- Chuck Short Mon, 21 Apr 2008 10:56:32 -0400 ebox-usersandgroups (0.11.99-0ubuntu4) hardy; urgency=low * debian/patches/03_fix_restore_backup.dpatch - Fixes ldap backup restoring. * debian/patches/04_fix_utf8_ldap.dpatch - Disable workaround to eneable utf8 strings. * debian/patches/05_ldap_password_file_permissions.dpatch - Remove read permissions for adm group in eBox ldap password file. -- Chuck Short Mon, 07 Apr 2008 10:29:24 -0400 ebox-usersandgroups (0.11.99-0ubuntu3) hardy; urgency=low * debian/patches/03_allow_unsafe_chars_in_password.dpatch - Allow "unsafe" characters in password field. (LP: #207622) -- Chuck Short Thu, 27 Mar 2008 11:04:13 -0400 ebox-usersandgroups (0.11.99-0ubuntu2) hardy; urgency=low * debian/control, debian/patches/01_make_apparmour_aware.dpatch, debian/patches/02_fix_ebox_initialise - Added patches from upstream. -- Chuck Short Tue, 11 Mar 2008 10:52:40 -0400 ebox-usersandgroups (0.11.99-0ubuntu1) hardy; urgency=low * New upstream version. -- Chuck Short Wed, 27 Feb 2008 13:48:56 -0500 ebox-usersandgroups (0.11.99-0ubuntu1~ppa1) hardy; urgency=low * New upstream release -- Javier Uruen Val Mon, 25 Feb 2008 15:31:20 +0100 ebox-usersandgroups (0.11.99) unstable; urgency=low * New upstream release -- Enrique José Hernández Blasco Tue, 8 Jan 2008 16:14:41 +0100 ebox-usersandgroups (0.11.3-0ubuntu1~ppa1) hardy; urgency=low * New upstream release -- Javier Uruen Val Sun, 13 Jan 2008 19:14:30 +0100 ebox-usersandgroups (0.11) unstable; urgency=low * New upstream release -- Javier Uruen Val Wed, 28 Nov 2007 15:23:36 +0100 ebox-usersandgroups (0.10.99) unstable; urgency=low * New upstream release -- Javier Uruen Val Thu, 01 Nov 2007 21:38:16 +0100 ebox-usersandgroups (0.10) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 16 Oct 2007 12:07:12 +0200 ebox-usersandgroups (0.9.100) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 04 Sep 2007 14:24:57 +0200 ebox-usersandgroups (0.9.99) unstable; urgency=low * New upstream release -- Javier Amor Garcia Tue, 24 Jul 2007 13:04:49 +0200 ebox-usersandgroups (0.9.3) unstable; urgency=low * New upstream release -- Javier Uruen Val Sun, 24 Jun 2007 16:38:50 +0200 ebox-usersandgroups (0.9.2) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 12 Jun 2007 18:59:29 +0200 ebox-usersandgroups (0.9.1) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 15 May 2007 13:02:28 +0200 ebox-usersandgroups (0.9) unstable; urgency=low * New upstream release -- Javier Amor Garcia Tue, 27 Mar 2007 10:26:29 +0200 ebox-usersandgroups (0.7.1) unstable; urgency=low * New upstream release -- Daniel Baeyens Sicilia Wed, 22 Mar 2006 16:08:34 +0100 ebox-usersandgroups (0.7.0.99-rc1+0.7.1-rc1) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 17 Jan 2006 11:45:29 +0100 ebox-usersandgroups (0.5.1) unstable; urgency=low * New upstream release -- Guillermo Ontañón Mon, 14 Mar 2005 14:33:45 +0100 ebox-usersandgroups (0.5) unstable; urgency=low * New upstream release -- Isaac Clerencia Thu, 3 Mar 2005 19:56:15 +0100 ebox-usersandgroups (0.4-2) unstable; urgency=low * New upstream release -- Isaac Clerencia Sat, 4 Dec 2004 16:36:45 +0100 zentyal-users-2.3.15+quantal1/conf/0000775000000000000000000000000012017154745013774 5ustar zentyal-users-2.3.15+quantal1/conf/users.conf0000664000000000000000000000132412017154745016004 0ustar # users.conf - configuration file for zentyal-users # # This file contains the most basic settings, most other stuff is configured # using the web interface. # # Everything after a '#' character is ignored # # All whitespace is ignored # # Config keys are set this way: # # key = value # # They may contain comments at the end: # # key = value # this is ignored # supported paswords formats: sha1, md5, lm, nt, digest (base64) and realm (hex) # whether to create user homes or not mk_home = yes # default mode for home directory (umask mode) dir_umask = 0077 # enable quota support enable_quota = yes # synchronization frequency with LDAP slaves slave_time = 5 # allow multiple OUs (experts only) #multiple_ous = yes zentyal-users-2.3.15+quantal1/src/0000775000000000000000000000000012017154745013636 5ustar zentyal-users-2.3.15+quantal1/src/templates/0000775000000000000000000000000012017154745015634 5ustar zentyal-users-2.3.15+quantal1/src/templates/group.mas0000664000000000000000000000611212017154745017472 0ustar <%args> $group @groupusers @remainusers @components $slave => 1 <%init> use EBox::Gettext;

<% __('Administration of group ') %> <% $group->name() %>

% unless (@groupusers or @remainusers) {
<% __("There are no users at the moment. You need at least one to manage this group properly.")%>

% }
<% __('Comment') %>: % unless ($slave) { % }
<% __("Users in group") %> <% __("Users not in group") %>
% unless ($slave) { % }

% unless ($slave) {
% }
% foreach my $comp (@components) { <& $comp->{'path'}, 'params' => $comp->{'params'} &> % } % unless ($slave) {

<% __("Delete group") %>

<% __('This operation will cause the removal of the group and all dependent data such as shared directory, etc.') %>

% } zentyal-users-2.3.15+quantal1/src/templates/del.mas0000664000000000000000000000240212017154745017100 0ustar <%args> $object $name @data <%init> use EBox::Gettext; % if ($object eq 'user') {

<% __('Deleting user') %> <% $name->name() %>

<% __('The user you tried to delete contains data in the following modules. Please confirm you want to remove it and all its related data') %>
% } else {

<% __('Deleting group') %> <% $name->name() %>

<% __('The group you tried to delete contains data in the following modules. Please confirm you want to remove it and all its related data') %>
% } % foreach my $par (@data) {
<% $par %>
% }
zentyal-users-2.3.15+quantal1/src/templates/user.mas0000664000000000000000000001425512017154745017323 0ustar <%args> $user @usergroups @remaingroups @components $slave => 1 <%init> use EBox::Gettext; my $readOnly = $slave ? "readonly='readonly'" : "";

<% __('Administration of user') %> <% $user->name() %>

% unless ($slave) { % }
<% __('First name') %>: <& masterSlaveUserAttr, name => 'name', value=> $user->firstname(), slave => $slave, &>
<% __('Last name') %>: <& masterSlaveUserAttr, name => 'surname', value=> $user->surname(), slave => $slave, &>
<% __('Comment') %>:
<% __('Optional') %>
<& masterSlaveUserAttr, name => 'comment', value=> ($user->comment() or ''), slave => $slave, &>
<% __('User quota') %> (MB):
<% __('Password') %>:
<% __('Retype password') %>:
% unless ($slave) {
<% __("User groups") %> <% __("Other groups") %>


% } % foreach my $comp (@components) { <& $comp->{'path'}, 'params' => $comp->{'params'} &> % } % unless ($slave) {

<%__('Delete user')%>

<% __('This operation will cause the removal of the user and all dependent data such as mail accounts, user files, etc.') %>

% } <%def masterSlaveUserAttr> <%args> $name $value $slave % if ($slave) { <% $value %> % } else { %} zentyal-users-2.3.15+quantal1/src/templates/usersTableBody.mas0000664000000000000000000000332112017154745021264 0ustar <%flags> inherit => '/ajax/tableBody.mas' <%init> exists $ARGS{hasChanged} or $ARGS{hasChanged} = 1; exists $ARGS{action} or $ARGS{action} = 'view'; <& PARENT:view, %ARGS &> <%method topToolbar> <%args> $tableName $model $filter => undef <%init> my $userMod =$model->parentModule(); my $ouEnabled = $userMod->multipleOusEnabled(); % if (not $ouEnabled) { <& PARENT:topToolbar, tableName => $tableName, model => $model, filter => $filter, &> % return; % }
<& SELF:filterForm, tableName => $tableName, model => $model, filter => $filter, &> <& SELF:ouFilterForm, tableName => $tableName, model => $model, ous => $userMod->ous(), filterOU => $model->filterOU(), &>
<%method ouFilterForm> <%args> $tableName $model @ous $filterOU <%init> my $loadingId = $tableName . '_OUFilterLoading'; my @options = map { { value => $_->dn() } } @ous; unshift @options, { value => '_all', printableValue => __('All organizational units') }; defined $filterOU or $filterOU = '_all'; my $filterJS = q{var newUrl = '/UsersAndGroups/Users?filterOU=' + this.value; window.location = newUrl};
<% __('Organizational unit') %>: <& /input/select.mas, options => \@options, name => 'OUFIlter', value => $filterOU, onChange => "setLoading('$loadingId'); $filterJS; return false" &>
zentyal-users-2.3.15+quantal1/src/templates/wizard/0000775000000000000000000000000012017154745017134 5ustar zentyal-users-2.3.15+quantal1/src/templates/wizard/users.mas0000664000000000000000000000153412017154745021002 0ustar <%init> use EBox::Gettext; use EBox::Config; my $sysinfo = EBox::Global->modInstance('sysinfo'); my $hostDomain = $sysinfo->hostDomain();

<% __('Users and Groups') %>

<% __('Select the domain name of the server') %>

<% __('This will used as the Kerberos authentication realm for your users.') %>
zentyal-users-2.3.15+quantal1/src/templates/users.mas0000664000000000000000000000533612017154745017506 0ustar <%args> @users => (); @groups => (); @ous => (); $usersModel => undef <%init> use EBox::Gettext; use EBox::Global; if (not $usersModel) { $usersModel = EBox::Global->modInstance('users')->model('Users'); }

<% __('Add User') %>

<& .groupSelectorLine, groups => \@groups &> <& .ouSelectorLine, ous => \@ous &>
<% __('User name')%>:
<% __('First name')%>:
<% __('Last name')%>:
<% __('Comment') %>:
<% __('Optional') %>
<% __('Password') %>:
<% __('Retype password') %>:
<%def .groupSelectorLine> <%args> @groups <% __('Group') %>: <%def .ouSelectorLine> <%args> @ous % if (@ous > 0) { <% __('Organizational Unit') %>: % } <& '/users/usersTableBody.mas', model => $usersModel &> zentyal-users-2.3.15+quantal1/src/templates/groups.mas0000664000000000000000000000206512017154745017660 0ustar <%args> @groups => (); <%init> use EBox::Gettext; use EBox::Global; my $groupsModel = EBox::Global->modInstance('users')->model('Groups');

<% __('Add Group') %>

<% __('Group name') %>:
<% __('Comment') %>:
(<% __('Optional value') %>)
<& '/ajax/tableBody.mas', model => $groupsModel &> zentyal-users-2.3.15+quantal1/src/scripts/0000775000000000000000000000000012017154745015325 5ustar zentyal-users-2.3.15+quantal1/src/scripts/enable-quotas0000775000000000000000000000231012017154745020007 0ustar #!/usr/bin/perl # Add quota support to fstab. It's set up for "/home" if exists, # otherwise we fall back to "/". Remount partition and turn quotas on open(FD, "/etc/fstab") or die "Could not open /etc/fstab"; my @fstab = ; close(FD); my $home = undef; my $root = undef; my $num = -1; for $line (@fstab) { $num++; my @fields = split(/[\t\s]+/, $line); next if ($fields[0] =~ /^#.*/); if ($fields[1] =~ /^\/$/) { $root = $num; } elsif ($fields[1] =~ /^\/home$/){ $home = $num; } } my $line = $home ? $home : $root; my $mount; if ($line) { my @fields = split(/[\t\s]+/, $fstab[$line]); $mount = $fields[1]; if ($fstab[$line] =~ /usrquota/) { print "Fstab already set up to use quotas\n"; exit 0; } else { my $type = $fields[2]; my $t = $fields[3]; my $attrs = "usrquota,grpquota"; unless ($type eq "xfs") { $attrs .= ",acl"; } $fstab[$line] =~ s/$t/$t,$attrs/; } } else { print "Could not find / or /home mounting points"; exit 1; } open(FD, ">/etc/fstab") or die "Could not write on /etc/fstab"; print FD @fstab; close(FD); system("/bin/mount -o remount $mount"); exit 0; zentyal-users-2.3.15+quantal1/src/scripts/ldapvi0000775000000000000000000000232412017154745016533 0ustar #!/usr/bin/perl # Copyright (C) 2010-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; use EBox; use EBox::Global; unless (-x '/usr/bin/ldapvi') { print("zentyal-ldapvi: ERROR, install ldapvi package.\n"); exit(1); } EBox::init(); my $usersMod = EBox::Global->modInstance("users"); my $ldap = $usersMod->ldap(); my $ldapconf = $ldap->ldapConf(); my $dn = exists $ARGV[0] ? $ARGV[0] : $ldapconf->{'dn'}; my $bind = $ldapconf->{'rootdn'}; my $pwfile = EBox::Config->conf() . "ldap.passwd"; system("ldapvi -h localhost:390 -D $bind --bind simple -w \$(cat $pwfile) -b $dn"); 1; zentyal-users-2.3.15+quantal1/src/scripts/slave-sync0000775000000000000000000000722412017154745017344 0ustar #!/usr/bin/perl # Copyright (C) 2010-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; # for performance we check first if there are pending operations unless (grep { -d $_ } ) { exit 0; } use EBox; use EBox::Config; use EBox::Global; use EBox::Util::Lock; use File::Basename; use Error qw(:try); use constant LOCK_NAME => 'zentyal-slave-sync'; my $mode = 'run'; if (($#ARGV == 0) and ($ARGV[0] eq '-l')) { $mode = 'list'; } EBox::init(); my $users = EBox::Global->modInstance('users'); $users->configured() or exit 0; EBox::Util::Lock::lock(LOCK_NAME); my $slaves = $users->allSlaves(); try { (@{$slaves}) or exit 0; } otherwise { exit 0; }; processDir($slaves, EBox::Config::home() . 'syncjournal/'); if (EBox::Global->modExists('usercorner')) { eval 'use EBox::UserCorner'; processUserCornerDir(EBox::UserCorner::usercornerdir() . 'syncjournal/'); } EBox::Util::Lock::unlock(LOCK_NAME); exit 0; sub processSlaveDir { my ($slave, $dir) = @_; my $name = $slave->name; if ($mode eq 'list') { print "Slave: $name\n"; } my $dh; opendir($dh, $dir) or die "Can't open the journal dir: $dir\n"; my @files; while (defined(my $file = readdir($dh))) { (-d "$dir$file" and next); push(@files, $file); } closedir($dh); foreach my $file (sort(@files)) { processFile($slave, "$dir$file"); } } sub processFile { my ($slave, $file) = @_; if ($mode eq 'run') { print "Syncing $file...\n"; $slave->syncFromFile($file); } elsif ($mode eq 'list') { my $name = basename($file); print " * $name\n"; } } sub processDir { my ($slaves, $journaldir) = @_; unless (-d $journaldir) { print "Dir does not exist: $journaldir\n"; return; } my $jdir; opendir($jdir, $journaldir) or die "Can't open the journal dir: $journaldir\n"; foreach my $slave (@{$slaves}) { my $name = $slave->name(); my $slavedir = "$journaldir/$name/"; processSlaveDir($slave, $slavedir); } closedir($jdir); } sub processUserCornerDir { my ($dir) = @_; my $dh; opendir($dh, $dir) or die "Can't open the journal dir: $dir\n"; my @files; while (defined(my $file = readdir($dh))) { (-d "$dir$file" and next); push (@files, $file); } closedir($dh); foreach my $file (sort(@files)) { processUserCornerFile("$dir$file"); } } sub processUserCornerFile { my ($file) = @_; EBox::Sudo::root("chown ebox:ebox $file") unless (-r $file); my $action = EBox::UsersAndGroups::Slave->readActionInfo($file); if ($mode eq 'run') { foreach my $slave (@{$slaves}) { my $name = $slave->name(); print "Syncing $file to $name...\n"; $slave->sync($action->{signal}, $action->{args}); } EBox::Sudo::root("rm $file"); } elsif ($mode eq 'list') { my $name = basename($file); print " * $name\n"; } } 1; zentyal-users-2.3.15+quantal1/src/scripts/check-ldap-password0000775000000000000000000000123112017154745021103 0ustar #!/usr/bin/perl use EBox::Ldap; use Error qw(:try); sub baseDn { my ($ldap) = @_; my $result = $ldap->search( 'base' => '', 'scope' => 'base', 'filter' => '(objectclass=*)', 'attrs' => ['namingContexts'] ); my $entry = ($result->entries)[0]; my $attr = ($entry->attributes)[0]; return $entry->get_value($attr); } my $ldap; try { $ldap = EBox::Ldap->safeConnect('127.0.0.1'); } catch Error with { exit 1; }; my $rootdn = 'cn=admin,' . baseDn($ldap); my $rootpass = $ARGV[0]; my $res = $ldap->bind($rootdn, password => $rootpass); if ($res->{resultCode} eq 0) { exit 0; } else { exit 1; } zentyal-users-2.3.15+quantal1/src/scripts/schemas2ldif0000775000000000000000000000362412017154745017624 0ustar #!/usr/bin/perl # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; use Carp; use Cwd qw(abs_path); use File::Basename; use File::Temp qw(:mktemp); use File::Path qw(rmtree); use File::Slurp qw(read_file); my $tmpfile = mktemp('/tmp/slaptest-XXXX'); my $tmpdir = mkdtemp('/tmp/ldap-XXXX'); my $ldapconf= <$tmpfile"; print LDAPCONF $ldapconf; close LDAPCONF; system("slaptest -f $tmpfile -F $tmpdir"); foreach my $schema (@ARGV) { my $schema_name = $schema; $schema_name =~ s/\.schema$//; my $ldif = (glob("$tmpdir/cn=config/cn=schema/cn={*}$schema_name.ldif"))[0]; my $ldif_contents = read_file($ldif); $ldif_contents =~ s/{\d*}//g; $ldif_contents =~ s/structuralObjectClass.*//s; my $dest = abs_path($schema); $dest =~ s/\.schema$/.ldif/; open LDIF, ">$dest"; print LDIF $ldif_contents; close LDIF; } unlink($tmpfile); rmtree($tmpdir); zentyal-users-2.3.15+quantal1/src/scripts/cloud-sync0000775000000000000000000001177012017154745017341 0ustar #!/usr/bin/perl # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; use EBox; use EBox::Config; use EBox::Global; use MIME::Base64; use Error qw(:try); use constant IGNORE => ['zentyal-cloud']; EBox::init(); my $users = EBox::Global->modInstance('users'); if ($users->master() ne 'cloud') { return; } # Cloud syncing enabled EBox::debug("Syncing users with Zentyal Cloud!"); my $rs = EBox::Global->modInstance('remoteservices'); my $rest = $rs->REST(); EBox::debug("Asking for user list"); my $res = $rest->GET('/v1/users/users/'); # local and remote user list my $lusers = $users->users(); my $rusers = $res->data(); my $rusernames; EBox::debug('Local users: ' . @$lusers . ' users'); EBox::debug('Remote users: ' . @$rusers . ' users'); for my $ruser (@{$rusers}) { # add it to rusernames dict $rusernames->{$ruser->{name}} = 1; # Convert passwords my @pass = map { decode_base64($_) } @{$ruser->{passwords}}; $ruser->{passwords} = \@pass; my $luser; try { try { $luser = $users->user($ruser->{name}); $luser->setIgnoredSlaves(IGNORE); # User exists, update fields: $luser->set('givenname', $ruser->{firstname}, 1); $luser->set('sn', $ruser->{lastname}, 1); $luser->set('gidNumber', $ruser->{gid}, 1); $luser->set('uidNumber', $ruser->{uid}, 1); if ($ruser->{description}) { $luser->set('comment', $ruser->{description}, 1); } else { $luser->delete('comment', 1); } $luser->save(); # Update passwords $luser->setPasswordFromHashes($ruser->{passwords}); } catch EBox::Exceptions::DataNotFound with { EBox::info('Local user "' . $ruser->{name} . '" does not exist, creating...'); my $user; $user->{user} = $ruser->{name}; $user->{name} = $ruser->{firstname}; $user->{surname} = $ruser->{lastname}; if ($user->{name}) { $user->{fullname} = $user->{name} . ' ' . $user->{surname}; $user->{givenname} = $user->{name}; } else { $user->{fullname} = $user->{surname}; $user->{givenname} = ''; } $user->{passwords} = $ruser->{passwords}; $user->{comment} = $ruser->{description}; EBox::UsersAndGroups::User->create($user, 0, ignoreSlaves => IGNORE); }; } otherwise { EBox::error('Failed to sync remote user ' . $ruser->{name}); }; } for my $user (@{$lusers}) { my $name = $user->name(); if (not $rusernames->{$name}) { EBox::info("Local user $name not present in remote, removing..."); $user->setIgnoredSlaves(IGNORE); $user->deleteObject(); } } EBox::debug("Asking for group list"); $res = $rest->GET('/v1/users/groups/'); # local and remote user list my $lgroups = $users->groups(); my $rgroups = $res->data(); my $rgroupnames; EBox::debug('Local groups: ' . @$lgroups . ' groups'); EBox::debug('Remote groups: ' . @$rgroups . ' groups'); for my $rgroup (@{$rgroups}) { # add it to rgroupames dict $rgroupnames->{$rgroup->{name}} = 1; my $lgroup; try { try { $lgroup = $users->group($rgroup->{name}); } catch EBox::Exceptions::DataNotFound with { EBox::info('Local group "' . $rgroup->{name} . '" does not exist, creating...'); $rgroup->{description} = ($rgroup->{description} or ''); $lgroup = EBox::UsersAndGroups::Group->create($rgroup->{name}, $rgroup->{description}, ignoreSlaves => IGNORE); } otherwise { EBox::error('Failed to sync remote group ' . $rgroup->{name}); }; # Update group info $lgroup->setIgnoredSlaves(IGNORE); $lgroup->removeAllMembers(1); foreach my $user (@{$rgroup->{members}}) { $lgroup->addMember($users->user($user), 1); } $lgroup->save(); } otherwise { EBox::error('Failed to sync remote group ' . $rgroup->{name}); }; } for my $group (@{$lgroups}) { my $name = $group->name(); if (not $rgroupnames->{$name}) { EBox::info("Local group $name not present in remote, removing..."); $group->setIgnoredSlaves(IGNORE); $group->deleteObject(); } } EBox::info("Synchronization done"); zentyal-users-2.3.15+quantal1/src/scripts/user-quota0000775000000000000000000000312312017154745017357 0ustar #!/usr/bin/perl # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # This is a external tool to set/get user quotas. It's a separated script # as we use the libquota-perl module. In order to use an API that must be run # as root and not as ebox user # # It's meant to be run by Zentyal. # # Parameters are: # # -q uid | -s uid quota # # -q: query # -s: set # uid: user uid # quota: quota size in KB use Quota; sub currentQuota { my ($uid) = @_; my @quotaValues = Quota::query( Quota::getqcarg('/home'), $uid); if (@quotaValues) { return $quotaValues[1]; } else { return -1; } } sub setCurrentQuota { my ($uid, $quota) = @_; my $ok = Quota::setqlim(Quota::getqcarg('/home'), $uid, $quota, $quota, 0, 0); if (not defined $ok) { my $err = Quota::strerr(); die $err; } } if ($ARGV[0] eq '-s') { setCurrentQuota($ARGV[1], $ARGV[2]); } else { print currentQuota($ARGV[1]); } exit 0; zentyal-users-2.3.15+quantal1/src/scripts/slapd.backup0000775000000000000000000000064312017154745017625 0ustar #!/bin/bash # # Backup LDAP directories # umask 077 BACKUPDIR="/var/backups/slapd" # Check if there is a directory slapd, otherwise create it. if [ ! -d "$BACKUPDIR" ]; then mkdir -p -m 0700 "$BACKUPDIR" fi date=$(date +%C%y%m%d-%H%M%S) DESTDIR="$BACKUPDIR/slapd-preebox-$date" mkdir -p -m 0700 $DESTDIR slapcat > "$DESTDIR/ldap.db" test -d /etc/ldap/slapd.d && cp -a /etc/ldap/slapd.d "$DESTDIR/slapd.d" exit 0 zentyal-users-2.3.15+quantal1/src/scripts/initial-setup0000775000000000000000000000064312017154745020045 0ustar #!/bin/bash set -e # Create slapd certificate /usr/share/zentyal/create-certificate /etc/ldap/ssl > /dev/null 2>&1 chown -R openldap:openldap /etc/ldap/ssl chmod 700 /var/lib/zentyal/conf/ssl USERS_CONF=/var/lib/zentyal/conf/users mkdir -p $USERS_CONF chown ebox:ebox $USERS_CONF chmod 700 $USERS_CONF # FIXME: Enable quotas where users module was already enabled # FIXME: Add systemQuotas class to existing users zentyal-users-2.3.15+quantal1/src/scripts/enable-module0000775000000000000000000000040512017154745017763 0ustar #!/bin/bash # copy ldap.secret cp /var/lib/zentyal/conf/ebox-ldap.passwd /etc/ldap.secret chmod 600 /etc/ldap.secret # enable quotas /usr/share/zentyal-users/enable-quotas # This might fail if the fs does not support quotas invoke-rc.d quota restart exit 0 zentyal-users-2.3.15+quantal1/src/scripts/reinstall0000775000000000000000000000165212017154745017254 0ustar #!/bin/bash echo "WARNING!!" echo "All your LDAP data and the Zentyal modules depending on it are going to be erased." echo "Press Control-C now if you are not sure of what you are doing." read invoke-rc.d zentyal users stop INSTALLED_MODULES=`dpkg -l | grep 'zentyal-' | grep ^ii | cut -d' ' -f3| xargs` UNCONFIGURE_MODULES="asterisk egroupware ftp jabber mail samba squid webmail zarafa captiveportal users" for mod in $UNCONFIGURE_MODULES do (echo $INSTALLED_MODULES | grep -q $mod) || continue echo "Unconfiguring module $mod..." sudo /usr/share/zentyal/unconfigure-module $mod done sudo apt-get -y --force-yes remove --purge slapd sudo rm -rf /var/lib/ldap* /etc/ldap* echo "Removal complete. Reinstalling the removed Zentyal modules..." sudo apt-get update sudo apt-get -y --force-yes install $INSTALLED_MODULES || exit 1 echo "Done." echo "Now you can go to 'Users and Groups -> Mode' and configure it again." zentyal-users-2.3.15+quantal1/src/EBox/0000775000000000000000000000000012017154745014473 5ustar zentyal-users-2.3.15+quantal1/src/EBox/rootTests/0000775000000000000000000000000012017154745016501 5ustar zentyal-users-2.3.15+quantal1/src/EBox/rootTests/PauseAndExecute.t0000664000000000000000000000063412017154745021714 0ustar use strict; use warnings; use constant TESTS => 10; use Test::More tests => TESTS; use lib '..'; use EBox::Ldap; use EBox::Sudo; use EBox; EBox::init(); my $ldap = EBox::Ldap->instance(); ok $ldap->ldapCon, 'test conexion before restarting ldap'; foreach (2 .. TESTS) { $ldap->_pauseAndExecute(cmds => ["ls /"]); ok $ldap->ldapCon, 'test conexion after calling _pauseAndExecute thus restarting ldap'; } zentyal-users-2.3.15+quantal1/src/EBox/rootTests/BackupUsersAndGroups.t0000664000000000000000000000352512017154745022745 0ustar use strict; use warnings; use Test::More tests => 10; use Test::Exception; use Error qw(:try); use EBox::Sudo; use lib '../..'; use Readonly; Readonly::Scalar my $TEST_DIR => '/tmp/ebox.usersandgroups.itest'; Readonly::Scalar my $BACKUP_DIR => "$TEST_DIR/backup"; Readonly::Scalar my $EXTENDED_BACKUP_DIR => "$TEST_DIR/extended"; Readonly::Scalar my $CANARY_USER => 'canary'; system "rm -rf $TEST_DIR"; use EBox; EBox::init(); foreach my $dir ($TEST_DIR, $BACKUP_DIR, $EXTENDED_BACKUP_DIR) { mkdir $dir or die "Can not create directory $dir"; } use_ok('EBox::UsersAndGroups'); _cleanUsers(); try { _backupCanaryTest(); } finally { _cleanUsers(); }; sub _backupCanaryTest { my $usersAndGroups = EBox::Global->modInstance('users'); lives_ok { $usersAndGroups->makeBackup($BACKUP_DIR, fullBackup => 0) } "Configuration backup tried in $BACKUP_DIR"; checkLdap($usersAndGroups); lives_ok { $usersAndGroups->makeBackup($EXTENDED_BACKUP_DIR, fullBackup => 1) } "Configuration backup tried in $EXTENDED_BACKUP_DIR"; checkLdap($usersAndGroups); $usersAndGroups->addUser ({user => $CANARY_USER, fullname => 'ea', password => 'ea', comment => 'ea'}, 0); ok $usersAndGroups->userExists($CANARY_USER), 'Checking that canary was added'; lives_ok { $usersAndGroups->restoreBackup($BACKUP_DIR, fullRestore => 0) } "Configuration restore"; ok !$usersAndGroups->userExists($CANARY_USER), 'Checking that canary is not here'; } sub checkLdap { my ($usersAndGroups) = @_; system 'pgrep slapd'; ok ($? == 0), 'Checking that slapd is active'; lives_ok { $usersAndGroups->users() } 'Checking that we can get user list from ldap via users and groups'; } sub _cleanUsers { my $usersAndGroups = EBox::Global->modInstance('users'); if ($usersAndGroups->userExists($CANARY_USER)) { $usersAndGroups->delUser($CANARY_USER); } } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/0000775000000000000000000000000012017154745015075 5ustar zentyal-users-2.3.15+quantal1/src/EBox/CGI/Group.pm0000664000000000000000000000414212017154745016530 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::Group; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups; use EBox::UsersAndGroups::Group; use EBox::Gettext; sub new { my $class = shift; my $self = $class->SUPER::new('title' => __('Edit group'), 'template' => '/users/group.mas', @_); bless($self, $class); return $self; } sub _process { my ($self) = @_; my $usersandgroups = EBox::Global->modInstance('users'); my @args = (); $self->_requireParam('group', __('group')); my $group = $self->unsafeParam('group'); $group = new EBox::UsersAndGroups::Group(dn => $group); my $grpusers = $group->users(); my $remainusers = $group->usersNotIn(); my $components = $usersandgroups->allGroupAddOns($group); my $editable = $usersandgroups->editableMode(); push(@args, 'group' => $group); push(@args, 'groupusers' => $grpusers); push(@args, 'remainusers' => $remainusers); push(@args, 'components' => $components); push(@args, 'slave' => not $editable); if ($editable) { $self->{crumbs} = [ { title => __('Groups'), link => '/UsersAndGroups/Groups' }, { title => $group->name(), link => undef, }, ]; } $self->{params} = \@args; } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/Wizard/0000775000000000000000000000000012017154745016335 5ustar zentyal-users-2.3.15+quantal1/src/EBox/CGI/Wizard/Users.pm0000664000000000000000000000271712017154745020003 0ustar # Copyright (C) 2010-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::Wizard::Users; use strict; use warnings; use base 'EBox::CGI::WizardPage'; use EBox::Global; use EBox::Gettext; use EBox::Validate; use Error qw(:try); sub new { my $class = shift; my $self = $class->SUPER::new('template' => 'users/wizard/users.mas', @_); bless ($self, $class); return $self; } sub _processWizard { my ($self) = @_; my $domain = $self->param('domain'); if ($domain) { EBox::info('Setting the host domain'); # Write the domain to sysinfo model my $sysinfo = EBox::Global->modInstance('sysinfo'); my $domainModel = $sysinfo->model('HostName'); my $row = $domainModel->row(); $row->elementByName('hostdomain')->setValue($domain); $row->store(); } } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/ModifyUser.pm0000664000000000000000000000563212017154745017527 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::ModifyUser; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups; use EBox::UsersAndGroups::User; use EBox::Gettext; use EBox::Exceptions::External; sub new { my $class = shift; my $self = $class->SUPER::new('title' => 'Users and Groups', @_); $self->{errorchain} = "UsersAndGroups/Users"; bless($self, $class); return $self; } sub _process($) { my $self = shift; my $users = EBox::Global->modInstance('users'); $self->_requireParam('user', __('user name')); $self->_requireParamAllowEmpty('quota', __('quota')); # retrieve user object my $user = $self->unsafeParam('user'); $user = new EBox::UsersAndGroups::User(dn => $user); $self->{errorchain} = "UsersAndGroups/User"; $self->keepParam('user'); $user->set('quota', $self->param('quota'), 1); unless ($users->mode() eq 'slave') { $self->_requireParam('surname', __('last name')); $self->_requireParamAllowEmpty('comment', __('comment')); $self->_requireParamAllowEmpty('password', __('password')); $self->_requireParamAllowEmpty('repassword', __('confirm password')); my $givenName = $self->param('name'); my $surname = $self->param('surname'); my $fullname; if ($givenName) { $fullname = "$givenName $surname"; } else { $fullname = $surname; } my $comment = $self->param('comment'); if (length ($comment)) { $user->set('description', $comment, 1); } else { $user->delete('description', 1); } $user->set('givenname', $givenName, 1); $user->set('sn', $surname, 1); $user->set('cn', $fullname, 1); # Change password if not empty my $password = $self->unsafeParam('password'); if ($password) { my $repassword = $self->unsafeParam('repassword'); if ($password ne $repassword){ throw EBox::Exceptions::External(__('Passwords do not match.')); } $user->changePassword($password, 1); } } $user->save(); $self->{redirect} = 'UsersAndGroups/User?user=' . $user->dn(); } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/AddUserToGroup.pm0000664000000000000000000000312312017154745020301 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::AddUserToGroup; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups::Group; use EBox::Gettext; sub new { my $class = shift; my $self = $class->SUPER::new('title' => 'Users and Groups', @_); bless($self, $class); return $self; } sub _process { my $self = shift; my @args = (); $self->_requireParam('group' , __('group')); my $group = $self->unsafeParam('group'); $self->{errorchain} = "UsersAndGroups/Group"; $self->keepParam('group'); $self->_requireParam('adduser', __('user')); my @users = $self->unsafeParam('adduser'); $group = new EBox::UsersAndGroups::Group(dn => $group); foreach my $us (@users){ $group->addMember(new EBox::UsersAndGroups::User(dn => $us)); } $self->{redirect} = 'UsersAndGroups/Group?group=' . $group->dn(); } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/Del.pm0000664000000000000000000000614112017154745016141 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::Del; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups; use EBox::UsersAndGroups::User; use EBox::UsersAndGroups::Group; use EBox::Gettext; use EBox::Exceptions::External; sub new { my $class = shift; my $self = $class->SUPER::new('title' => 'Users and Groups', @_); bless($self, $class); return $self; } sub _warnUser { my ($self, $object, $ldapObject) = @_; my $usersandgroups = EBox::Global->modInstance('users'); my $warns = $usersandgroups->allWarnings($object, $ldapObject); if (@{$warns}) { # If any module wants to warn user $self->{template} = 'users/del.mas'; $self->{redirect} = undef; my @array = (); push(@array, 'object' => $object); push(@array, 'name' => $ldapObject); push(@array, 'data' => $warns); $self->{params} = \@array; return 1; } return undef; } sub _process { my $self = shift; $self->_requireParam('objectname', __('object name')); my $name = $self->unsafeParam('objectname'); my ($deluser, $delgroup); if ($self->param('cancel')) { $self->_requireParam('object', __('object type')); my $object = $self->param('object'); if ($object eq 'user') { $self->{redirect} = "UsersAndGroups/User?user=$name"; } else { $self->{redirect} = "UsersAndGroups/Group?group=$name"; } } elsif ($self->param('deluserforce')) { # Delete user $deluser = 1; } elsif ($self->param('delgroupforce')) { $delgroup = 1; } elsif ($self->unsafeParam('deluser')) { my $user = new EBox::UsersAndGroups::User(dn => $name); $deluser = not $self->_warnUser('user', $user); } elsif ($self->unsafeParam('delgroup')) { my $group = new EBox::UsersAndGroups::Group(dn => $name); $delgroup = not $self->_warnUser('group', $group); } if ($deluser) { my $user = new EBox::UsersAndGroups::User(dn => $name); $user->deleteObject(); $self->{chain} = "UsersAndGroups/Users"; $self->{msg} = __('User removed successfully'); } elsif ($delgroup) { my $group = new EBox::UsersAndGroups::Group(dn => $name); $group->deleteObject(); $self->{chain} = "UsersAndGroups/Groups"; $self->{msg} = __('Group removed successfully'); } } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/User.pm0000664000000000000000000000403312017154745016351 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::User; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups; use EBox::Gettext; sub new { my $class = shift; my $self = $class->SUPER::new('template' => '/users/user.mas', @_); bless($self, $class); return $self; } sub _process { my ($self) = @_; my $usersandgroups = EBox::Global->modInstance('users'); $self->{'title'} = __('Users'); my @args = (); $self->_requireParam("user", __('username')); my $dn = $self->unsafeParam('user'); my $user = new EBox::UsersAndGroups::User(dn => $dn); my $components = $usersandgroups->allUserAddOns($user); my $usergroups = $user->groups(); my $remaingroups = $user->groupsNotIn(); my $editable = $usersandgroups->editableMode(); push(@args, 'user' => $user); push(@args, 'usergroups' => $usergroups); push(@args, 'remaingroups' => $remaingroups); push(@args, 'components' => $components); push(@args, 'slave' => not $editable); if ($editable) { $self->{crumbs} = [ { title => __('Users'), link => '/UsersAndGroups/Users' }, { title => $user->name(), link => undef, }, ]; } $self->{params} = \@args; } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/AddUser.pm0000664000000000000000000000533612017154745016771 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::AddUser; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups; use EBox::Gettext; use EBox::Exceptions::External; sub new { my $class = shift; my $self = $class->SUPER::new('title' => 'Users and Groups', @_); bless($self, $class); $self->{errorchain} = 'UsersAndGroups/Users'; return $self; } sub _process { my $self = shift; my @args = (); $self->_requireParam('username', __('user name')); $self->_requireParam('surname', __('last name')); $self->_requireParamAllowEmpty('comment', __('comment')); my $user; $user->{'user'} = $self->param('username'); $user->{'name'} = $self->param('name'); $user->{'surname'} = $self->param('surname'); if ($user->{'name'}) { $user->{'fullname'} = $user->{'name'} . ' ' . $user->{'surname'}; $user->{'givenname'} = $user->{'name'}; } else { $user->{'fullname'} = $user->{'surname'}; $user->{'givenname'} = ''; } $user->{'password'} = $self->unsafeParam('password'); $user->{'repassword'} = $self->unsafeParam('repassword'); $user->{'group'} = $self->unsafeParam('group'); $user->{'comment'} = $self->param('comment'); for my $field (qw/password repassword/) { unless (defined($user->{$field}) and $user->{$field} ne "") { throw EBox::Exceptions::DataMissing('data' => __($field)); } } if ($user->{'password'} ne $user->{'repassword'}){ throw EBox::Exceptions::External(__('Passwords do not match.')); } if (EBox::Config::configkey('multiple_ous')) { $user->{ou} = $self->unsafeParam('ou'); } my $newUser = EBox::UsersAndGroups::User->create($user, 0); if ($user->{'group'}) { $newUser->addGroup(new EBox::UsersAndGroups::Group(dn => $user->{'group'})); } if ($self->param('addAndEdit')) { $self->{redirect} = "UsersAndGroups/User?user=" . $newUser->dn(); } else { $self->{redirect} = "UsersAndGroups/Users"; } } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/AddGroupToUser.pm0000664000000000000000000000322012017154745020277 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::AddGroupToUser; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups; use EBox::UsersAndGroups::User; use EBox::UsersAndGroups::Group; use EBox::Gettext; sub new { my $class = shift; my $self = $class->SUPER::new('title' => 'Users and Groups', @_); bless($self, $class); return $self; } sub _process { my ($self) = @_; $self->_requireParam('user' , __('user')); my $user = $self->unsafeParam('user'); $user = new EBox::UsersAndGroups::User(dn => $user); $self->{errorchain} = "UsersAndGroups/User"; $self->keepParam('user'); $self->_requireParam('addgroup', __('group')); my @groups = $self->unsafeParam('addgroup'); foreach my $dn (@groups){ my $group = new EBox::UsersAndGroups::Group(dn => $dn); $user->addGroup($group); } $self->{redirect} = 'UsersAndGroups/User?user=' . $user->dn(); } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/DelGroupFromUser.pm0000664000000000000000000000322712017154745020643 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::DelGroupFromUser; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups; use EBox::UsersAndGroups::User; use EBox::UsersAndGroups::Group; use EBox::Gettext; sub new { my $class = shift; my $self = $class->SUPER::new('title' => 'Users and Groups', @_); bless($self, $class); return $self; } sub _process { my ($self) = @_; $self->_requireParam('user' , __('user')); my $user = $self->unsafeParam('user'); $user = new EBox::UsersAndGroups::User(dn => $user); $self->{errorchain} = "UsersAndGroups/User"; $self->keepParam('user'); $self->_requireParam('delgroup', __('group')); my @groups = $self->unsafeParam('delgroup'); foreach my $dn (@groups){ my $group = new EBox::UsersAndGroups::Group(dn => $dn); $user->removeGroup($group); } $self->{redirect} = 'UsersAndGroups/User?user=' . $user->dn(); } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/Users.pm0000664000000000000000000000356612017154745016546 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; package EBox::CGI::UsersAndGroups::Users; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups; use EBox::Gettext; sub new { my $class = shift; my $self = $class->SUPER::new('title' => __('Users'), 'template' => '/users/users.mas', @_); bless($self, $class); return $self; } sub _process($) { my ($self) = @_; my $users = EBox::Global->modInstance('users'); my @args = (); if ($users->configured()) { push(@args, 'groups' => $users->groups()); push(@args, 'users' => $users->users()); if ($users->multipleOusEnabled) { push(@args, 'ous' => $users->ous()); my $ou = $self->unsafeParam('filterOU'); if ((defined $ou) and ($ou eq '_all')) { $ou = undef; } EBox::debug("setOUFilterAction: $ou"); my $usersModel = $users->model('Users'); $usersModel->setFilterOU($ou); push @args, (usersModel => $usersModel); } } else { $self->setTemplate('/notConfigured.mas'); push(@args, 'module' => __('Users')); } $self->{params} = \@args; } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/ModifyGroup.pm0000664000000000000000000000334612017154745017705 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::ModifyGroup; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups; use EBox::UsersAndGroups::Group; use EBox::Gettext; use EBox::Exceptions::External; sub new { my $class = shift; my $self = $class->SUPER::new('title' => 'Users and Groups', @_); bless($self, $class); return $self; } sub _process { my $self = shift; $self->_requireParam('groupname', __('group name')); my $group = $self->unsafeParam('groupname'); $self->{errorchain} = "UsersAndGroups/Group"; $self->cgi()->param(-name=>'group', -value=>$group); $self->keepParam('group'); my $group = new EBox::UsersAndGroups::Group(dn => $group); $self->_requireParamAllowEmpty('comment', __('comment')); my $comment = $self->param('comment'); if (length ($comment)) { $group->set('description', $comment); } else { $group->delete('description'); } $self->{redirect} = 'UsersAndGroups/Group?group=' . $group->dn(); } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/DelUserFromGroup.pm0000664000000000000000000000310412017154745020635 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::DelUserFromGroup; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups::Group; use EBox::Gettext; sub new { my $class = shift; my $self = $class->SUPER::new('title' => 'Users and Groups', @_); bless($self, $class); return $self; } sub _process { my $self = shift; my @args = (); $self->_requireParam('group' , __('group')); my $group = $self->unsafeParam('group'); $self->{errorchain} = "UsersAndGroups/Group"; $self->keepParam('group'); $self->_requireParam('deluser', __('user')); my @users = $self->unsafeParam('deluser'); $group = new EBox::UsersAndGroups::Group(dn => $group); foreach my $us (@users){ $group->removeMember(new EBox::UsersAndGroups::User(dn => $us)); } $self->{redirect} = 'UsersAndGroups/Group?group=' . $group->dn(); } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/AddGroup.pm0000664000000000000000000000304512017154745017142 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::AddGroup; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups; use EBox::UsersAndGroups::Group; use EBox::Gettext; sub new { my $class = shift; my $self = $class->SUPER::new('title' => 'Users and Groups', @_); bless($self, $class); $self->{errorchain} = 'UsersAndGroups/Groups'; return $self; } sub _process($) { my $self = shift; my @args = (); $self->_requireParam('groupname', __('group name')); my $groupname = $self->param('groupname'); my $comment = $self->param('comment'); my $group = EBox::UsersAndGroups::Group->create($groupname, $comment); if ($self->param('addAndEdit')) { $self->{redirect} = 'UsersAndGroups/Group?group=' . $group->dn(); } else { $self->{redirect} = "UsersAndGroups/Groups"; } } 1; zentyal-users-2.3.15+quantal1/src/EBox/CGI/Groups.pm0000664000000000000000000000261612017154745016717 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::UsersAndGroups::Groups; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::UsersAndGroups; use EBox::Gettext; sub new { my $class = shift; my $self = $class->SUPER::new( 'template' => '/users/groups.mas', @_); bless($self, $class); return $self; } sub _process($) { my $self = shift; my $usersandgroups = EBox::Global->modInstance('users'); $self->{'title'} = __('Groups'); my @args = (); if ($usersandgroups->configured()) { my @groups = $usersandgroups->groups(); push(@args, 'groups' => \@groups); } else { $self->setTemplate('/notConfigured.mas'); push(@args, 'module' => __('Users')); } $self->{params} = \@args; } 1; zentyal-users-2.3.15+quantal1/src/EBox/LdapModule.pm0000664000000000000000000001424712017154745017067 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::LdapModule; use strict; use warnings; use EBox::Gettext; use EBox::Global; use EBox::Exceptions::NotImplemented; use EBox::Ldap; use Error qw(:try); sub new { my $class = shift; my $self = {}; bless($self, $class); return $self; } # Method: _ldapModImplementation # # All modules using any of the functions in LdapUserBase.pm # should override this method to return the implementation # of that interface. # # Returns: # # An object implementing EBox::LdapUserBase sub _ldapModImplementation { throw EBox::Exceptions::NotImplemented(); } # Method: ldap # # Provides an EBox::Ldap object with the proper configuration for the # LDAP setup of this ebox sub ldap { my ($self) = @_; my $users = EBox::Global->modInstance('users'); unless(defined($self->{ldap})) { $self->{ldap} = EBox::Ldap->instance(); } return $self->{ldap}; } sub masterLdap { my ($self) = @_; $self->ldap->ldapCon(); return $self->ldap->{ldap}; } # Method: _loadSchema # # loads an LDAP schema from an LDIF file # # Parameters: # file - LDIF file # sub _loadSchema { my ($self, $ldiffile) = @_; $self->ldap->ldapCon(); my $ldap = $self->ldap->{ldap}; $self->_loadSchemaDirectory($ldap, $ldiffile); } sub _loadSchemaDirectory { my ($self, $ldap, $ldiffile) = @_; my $ldif = Net::LDAP::LDIF->new($ldiffile, "r", onerror => 'undef' ); defined($ldif) or throw EBox::Exceptions::Internal( "Can't load LDIF file: " . $ldiffile); while(not $ldif->eof()) { my $entry = $ldif->read_entry(); if ($ldif->error()) { throw EBox::Exceptions::Internal( "Can't load LDIF file: " . $ldiffile); } my $dn = $entry->dn(); $dn =~ m/^cn=(.*?),cn=schema,cn=config$/; my $schemaname = $1; my %args = ( 'base' => 'cn=schema,cn=config', 'scope' => 'subtree', 'filter' => "(cn={*}$schemaname)", 'attrs' => ['objectClass'] ); my $result = $ldap->search(%args); if ($result->entries() == 0) { $result = $ldap->add($entry); if ($result->is_error()) { EBox::error($result->error()); } } } $ldif->done(); } # Method: _loadACL # # loads an ACL # # Parameters: # acl - string with the ACL (it has to start with 'to') # sub _loadACL { my ($self, $acl) = @_; $self->ldap->ldapCon(); my $ldap = $self->ldap->{ldap}; $self->_loadACLDirectory($ldap, $acl); } sub _loadACLDirectory { my ($self, $ldap, $acl) = @_; my $dn = 'olcDatabase={1}hdb,cn=config'; my %args = ( 'base' => $dn, 'scope' => 'base', 'filter' => "(objectClass=*)", 'attrs' => ['olcAccess'] ); my $result = $ldap->search(%args); my $entry = ($result->entries)[0]; if ($result->count() == 0) { throw EBox::Exceptions::Internal("LDAP object not found: $dn") } my $attr = ($entry->attributes)[0]; my $found = undef; my @rules = $entry->get_value($attr); for my $access (@rules) { if($access =~ m/^{\d+}\Q$acl\E$/) { $found = 1; last; } } if (not $found) { # place the new rule *before* the last 'catch-all' one my $last = pop(@rules); $last =~ s/^{\d+}//; push(@rules, $acl); push(@rules, $last); my %args = ( 'replace' => [ 'olcAccess' => \@rules ] ); try { $ldap->modify($dn, %args); } otherwise { throw EBox::Exceptions::Internal("Invalid ACL: $acl"); }; } } # Method: _addIndex # # Create indexes in LDAP for an attribute # # Parameters: # attribute - string with the attribute to be indexed in LDAP # sub _addIndex { my ($self, $attribute) = @_; $self->ldap->ldapCon(); my $ldap = $self->ldap->{ldap}; $self->_addIndexDirectory($ldap, $attribute); } sub _addIndexDirectory { my ($self, $ldap, $attribute) = @_; my $index = "$attribute eq"; my $dn = 'olcDatabase={1}hdb,cn=config'; my %args = ( 'base' => $dn, 'scope' => 'base', 'filter' => "(objectClass=*)", 'attrs' => ['olcDbIndex'] ); my $result = $ldap->search(%args); my $entry = ($result->entries)[0]; my $attr = ($entry->attributes)[0]; my $found = undef; my @indexes = $entry->get_value($attr); for my $dbindex (@indexes) { if($dbindex eq $index) { $found = 1; last; } } if(not $found) { push(@indexes, $index); my %args = ( 'replace' => [ 'olcDbIndex' => \@indexes ] ); try { $ldap->modify($dn, %args); } otherwise { throw EBox::Exceptions::Internal("Invalid index: $index"); }; } } # Method: performLDAPActions # # adds the schemas, acls and local attributes specified in the # LdapUserImplementation # # Parameters: # attribute - string with the attribute name # sub performLDAPActions { my ($self) = @_; my $ldapuser = $self->_ldapModImplementation(); my @schemas = @{ $ldapuser->schemas() }; for my $schema (@schemas) { $self->_loadSchema($schema); } my @acls = @{ $ldapuser->acls() }; for my $acl (@acls) { $self->_loadACL($acl); } my @indexes = @{ $ldapuser->indexes() }; for my $index (@indexes) { $self->_addIndex($index); } } 1; zentyal-users-2.3.15+quantal1/src/EBox/CloudSync/0000775000000000000000000000000012017154745016376 5ustar zentyal-users-2.3.15+quantal1/src/EBox/CloudSync/Slave.pm0000664000000000000000000001003312017154745020003 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CloudSync::Slave; use strict; use warnings; use base 'EBox::UsersAndGroups::Slave'; use EBox::Global; use EBox::Exceptions::External; use Error qw(:try); use MIME::Base64; sub new { my ($class, $host, $port, $cert) = @_; my $self = $class->SUPER::new(name => 'zentyal-cloud'); bless($self, $class); return $self; } sub _addUser { my ($self, $user, $pass) = @_; my $users = EBox::Global->modInstance('users'); return if ($user->baseDn() ne $users->usersDn()); # refresh user info to avoid cache problems with passwords: $user = $users->user($user->name()); my @passwords = map { encode_base64($_) } @{$user->passwordHashes()}; my $userinfo = { name => $user->get('uid'), firstname => $user->get('givenName'), lastname => $user->get('sn'), description => ($user->get('description') or ''), uid => $user->get('uidNumber'), gid => $user->get('gidNumber'), passwords => \@passwords, }; my $uid = $user->get('uid'); $self->RESTClient->POST("/v1/users/users/$uid", $userinfo); return 0; } sub _modifyUser { my ($self, $user, $pass) = @_; my $users = EBox::Global->modInstance('users'); return if ($user->baseDn() ne $users->usersDn()); # refresh user info to avoid cache problems with passwords: $user = $users->user($user->name()); my @passwords = map { encode_base64($_) } @{$user->passwordHashes()}; my $userinfo = { firstname => $user->get('givenName'), lastname => $user->get('sn'), description => ($user->get('description') or ''), passwords => \@passwords, }; my $uid = $user->get('uid'); $self->RESTClient->PUT("/v1/users/users/$uid", $userinfo); return 0; } sub _delUser { my ($self, $user) = @_; my $users = EBox::Global->modInstance('users'); return if ($user->baseDn() ne $users->usersDn()); my $uid = $user->get('uid'); $self->RESTClient->DELETE("/v1/users/users/$uid"); return 0; } sub _addGroup { my ($self, $group) = @_; my $users = EBox::Global->modInstance('users'); return if ($group->baseDn() ne $users->groupsDn()); my $groupinfo = { name => $group->name(), gid => $group->get('gidNumber'), description => ($group->get('description') or ''), }; my $name = $group->name(); $self->RESTClient->POST("/v1/users/groups/$name", $groupinfo); return 0; } sub _modifyGroup { my ($self, $group) = @_; my $users = EBox::Global->modInstance('users'); return if ($group->baseDn() ne $users->groupsDn()); my @members = map { $_->name() } @{$group->users()}; my $groupinfo = { name => $group->name(), gid => $group->get('gidNumber'), description => ($group->get('description') or ''), members => \@members, }; my $name = $group->get('cn'); $self->RESTClient->PUT("/v1/users/groups/$name", $groupinfo); return 0; } sub _delGroup { my ($self, $group) = @_; my $users = EBox::Global->modInstance('users'); return if ($users->baseDn() ne $users->groupsDn()); my $name = $group->get('cn'); $self->RESTClient->DELETE("/v1/users/groups/$name"); return 0; } sub RESTClient { my $rs = new EBox::Global->modInstance('remoteservices'); return $rs->REST(); } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/0000775000000000000000000000000012017154745017417 5ustar zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Group.pm0000664000000000000000000002503212017154745021053 0ustar #!/usr/bin/perl -w # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::Group # # Zentyal group, stored in LDAP # package EBox::UsersAndGroups::Group; use strict; use warnings; use EBox::Config; use EBox::Global; use EBox::Gettext; use EBox::UsersAndGroups; use EBox::UsersAndGroups::User; use EBox::Exceptions::External; use EBox::Exceptions::MissingArgument; use EBox::Exceptions::InvalidData; use constant SYSMINGID => 1900; use constant MINUID => 2000; use constant MINGID => 2000; use constant MAXGROUPLENGTH => 128; use constant CORE_ATTRS => ('member', 'description'); use Perl6::Junction qw(any); use base 'EBox::UsersAndGroups::LdapObject'; sub new { my $class = shift; my %opts = @_; my $self = {}; if (defined $opts{gid}) { $self->{gid} = $opts{gid}; } else { $self = $class->SUPER::new(@_); } bless ($self, $class); return $self; } # Method: _entry # # Return Net::LDAP::Entry entry for the group # sub _entry { my ($self) = @_; unless ($self->{entry}) { if (defined $self->{gid}) { my $result = undef; my $attrs = { base => $self->_ldap->dn(), filter => "(cn=$self->{gid})", scope => 'sub', }; $result = $self->_ldap->search($attrs); if ($result->count() > 1) { throw EBox::Exceptions::Internal( __x('Found {count} results for, expected only one.', count => $result->count())); } $self->{entry} = $result->entry(0); } else { $self->SUPER::_entry(); } } return $self->{entry}; } # Method: name # # Return group name # sub name { my ($self) = @_; return $self->get('cn'); } # Method: removeAllMembers # # Remove all members in the group # sub removeAllMembers { my ($self, $lazy) = @_; $self->set('member', [], $lazy); } # Method: addMember # # Adds the given user as a member # # Parameters: # # user - User object # sub addMember { my ($self, $user, $lazy) = @_; my @members = $self->get('member'); # return if user already in the group foreach my $dn (@members) { if (lc ($dn) eq lc ($user->dn())) { return; } } push (@members, $user->dn()); $self->set('member', \@members, $lazy); } # Method: removeMember # # Removes the given user as a member # # Parameters: # # user - User object # sub removeMember { my ($self, $user, $lazy) = @_; my @members; foreach my $dn ($self->get('member')) { push (@members, $dn) if (lc ($dn) ne lc ($user->dn())); } $self->set('member', \@members, $lazy); } # Method: users # # Return the list of members for this group # # Returns: # # arrary ref of members (EBox::UsersAndGroups::User) # sub users { my ($self, $system) = @_; my @members = $self->get('member'); @members = map { new EBox::UsersAndGroups::User(dn => $_) } @members; unless ($system) { @members = grep { not $_->system() } @members; } return \@members; } # Method: usersNotIn # # Users that don't belong to this group # # Returns: # # array ref of EBox::UsersAndGroups::Group objects # sub usersNotIn { my ($self, $system) = @_; my %attrs = ( base => $self->_ldap->dn(), filter => "(&(objectclass=posixAccount)(!(memberof=$self->{dn})))", scope => 'sub', ); my $result = $self->_ldap->search(\%attrs); my @users; if ($result->count > 0) { foreach my $entry ($result->sorted('uid')) { push (@users, new EBox::UsersAndGroups::User(entry => $entry)); } } unless ($system) { @users = grep { not $_->system() } @users; } return \@users; } # Catch some of the set ops which need special actions sub set { my ($self, $attr, $value) = @_; # remember changes in core attributes (notify LDAP user base modules) if ($attr eq any CORE_ATTRS) { $self->{core_changed} = 1; } shift @_; $self->SUPER::set(@_); } # Catch some of the set ops which need special actions sub delete { my ($self, $attr, $value) = @_; # remember changes in core attributes (notify LDAP user base modules) if ($attr eq any CORE_ATTRS) { $self->{core_changed} = 1; } shift @_; $self->SUPER::delete(@_); } # Method: deleteObject # # Delete the user # sub deleteObject { my ($self) = @_; # Notify group deletion to modules my $users = EBox::Global->modInstance('users'); $users->notifyModsLdapUserBase('delGroup', $self, $self->{ignoreMods}, $self->{ignoreSlaves}); # Call super implementation shift @_; $self->SUPER::deleteObject(@_); } sub save { my ($self, $ignore_mods) = @_; shift @_; $self->SUPER::save(@_); if ($self->{core_changed}) { delete $self->{core_changed}; my $users = EBox::Global->modInstance('users'); $users->notifyModsLdapUserBase('modifyGroup', [$self], $self->{ignoreMods}, $self->{ignoreSlaves}); } } # Method: setIgnoredModules # # Set the modules that should not be notified of the changes # made to this object # # Parameters: # # mods - Array reference cotaining module names # sub setIgnoredModules { my ($self, $mods) = @_; if (defined $mods) { $self->{ignoreMods} = $mods; } } # Method: setIgnoredSlaves # # Set the slaves that should not be notified of the changes # made to this object # # Parameters: # # mods - Array reference cotaining slave names # sub setIgnoredSlaves { my ($self, $slaves) = @_; $self->{ignoreSlaves} = $slaves; } # GROUP CREATION METHODS # Method: create # # Adds a new group # # Parameters: # # group - group name # comment - comment's group # system - boolan: if true it adds the group as system group, # otherwise as normal group # ignoreMods - ldap modules to be ignored on addUser notify # ignoreSlaves - slaves to be ignored on addUser notify # sub create { my ($self, $group, $comment, $system, %params) = @_; my $users = EBox::Global->modInstance('users'); my $dn = $users->groupDn($group); if (length($group) > MAXGROUPLENGTH) { throw EBox::Exceptions::External( __x("Groupname must not be longer than {maxGroupLength} characters", maxGroupLength => MAXGROUPLENGTH)); } unless (_checkGroupName($group)) { my $advice = __('To avoid problems, the group name should consist only of letters, digits, underscores, spaces, periods, dashs and not start with a dash. They could not contain only number, spaces and dots.'); throw EBox::Exceptions::InvalidData( 'data' => __('group name'), 'value' => $group, 'advice' => $advice ); } # Verify group exists if (new EBox::UsersAndGroups::Group(dn => $dn)->exists()) { throw EBox::Exceptions::DataExists( 'data' => __('group'), 'value' => $group); } my $gid = exists $params{gidNumber} ? $params{gidNumber} : $self->_gidForNewGroup($system); $self->_checkGid($gid, $system); my %args = ( attr => [ 'cn' => $group, 'gidNumber' => $gid, 'objectclass' => ['posixGroup', 'zentyalGroup'], ] ); push (@{$args{attr}}, 'description' => $comment) if ($comment); my $r = $self->_ldap->add($dn, \%args); my $res = new EBox::UsersAndGroups::Group(dn => $dn); unless ($system) { # Call modules initialization $users->notifyModsLdapUserBase('addGroup', $res, $params{ignoreMods}, $params{ignoreSlaves}); } return $res; } sub _checkGroupName { my ($name)= @_; if (not EBox::UsersAndGroups::checkNameLimitations($name)) { return undef; } # windows group names could not be only numbers, spaces and dots if ($name =~ m/^[[:space:]0-9\.]+$/) { return undef; } return 1; } sub system { my ($self) = @_; return ($self->get('gidNumber') < MINGID); } sub _gidForNewGroup { my ($self, $system) = @_; my $gid; if ($system) { $gid = $self->lastGid(1) + 1; if ($gid == MINGID) { throw EBox::Exceptions::Internal( __('Maximum number of groups reached')); } } else { $gid = $self->lastGid + 1; } return $gid; } # Method: lastGid # # Returns the last gid used. # # Parameters: # # system - boolan: if true, it returns the last gid for system groups, # otherwise the last gid for normal groups # # Returns: # # string - last gid # sub lastGid { my ($self, $system) = @_; my $lastGid = -1; my $users = EBox::Global->modInstance('users'); foreach my $group (@{$users->groups($system)}) { my $gid = $group->get('gidNumber'); if ($system) { last if ($gid >= MINGID); } else { next if ($gid < MINGID); } if ($gid > $lastGid) { $lastGid = $gid; } } if ($system) { return ($lastGid < SYSMINGID ? SYSMINGID : $lastGid); } else { return ($lastGid < MINGID ? MINGID : $lastGid); } } sub _checkGid { my ($self, $gid, $system) = @_; if ($gid < MINGID) { if (not $system) { throw EBox::Exceptions::External( __x('Incorrect GID {gid} for a group . GID must be equal or greater than {min}', gid => $gid, min => MINGID, ) ); } } else { if ($system) { throw EBox::Exceptions::External( __x('Incorrect GID {gid} for a system group . GID must be lesser than {max}', gid => $gid, max => MINGID, ) ); } } } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Composite/0000775000000000000000000000000012017154745021361 5ustar zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Composite/Settings.pm0000664000000000000000000000255112017154745023522 0ustar # Copyright (C) 2010-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::Composite::Settings package EBox::UsersAndGroups::Composite::Settings; use base 'EBox::Model::Composite'; use strict; use warnings; use EBox::Gettext; use EBox::Global; # Group: Protected methods # Method: _description # # Overrides: # # # sub _description { my $users = EBox::Global->modInstance('users'); my $description = { layout => 'top-bottom', name => 'Settings', compositeDomain => 'Users', #help => __('') }; return $description; } sub pageTitle { return __('LDAP Settings'); } sub menuFolder { return 'UsersAndGroups'; } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Composite/UserTemplate.pm0000664000000000000000000000344712017154745024341 0ustar # Copyright (C) 2010-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::Composite::UserTemplate package EBox::UsersAndGroups::Composite::UserTemplate; use base 'EBox::Model::Composite'; use strict; use warnings; use EBox::Gettext; use EBox::Global; # Group: Protected methods # Method: _description # # Overrides: # # # sub _description { my $users = EBox::Global->modInstance('users'); my $description = { layout => 'top-bottom', name => 'UserTemplate', compositeDomain => 'Users', help => __('These configuration options are used when a new user ' . 'account is created.') }; return $description; } # Method: componentNames # # Overrides: # # # sub componentNames { my $users = EBox::Global->modInstance('users'); my @models; if ($users->mode() eq 'master') { push (@models, 'AccountSettings'); } push (@models, @{$users->defaultUserModels()}); return \@models; } sub pageTitle { return __('User Template'); } sub menuFolder { return 'UsersAndGroups'; } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Composite/Sync.pm0000664000000000000000000000367212017154745022643 0ustar # Copyright (C) 2010-2011 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::Composite::Sync; package EBox::UsersAndGroups::Composite::Sync; use base 'EBox::Model::Composite'; use strict; use warnings; use EBox::Gettext; use EBox::Global; # Group: Protected methods # Method: _description # # Overrides: # # # sub _description { my $users = EBox::Global->modInstance('users'); my $description = { layout => 'top-bottom', name => 'Sync', compositeDomain => 'Users', #help => __('') }; return $description; } sub pageTitle { return __('Users synchronization'); } sub menuFolder { return 'UsersAndGroups'; } # Method: precondition # # Check if the module is configured # # Overrides: # # sub precondition { my ($self) = @_; my $usersMod = EBox::Global->modInstance('users'); unless ($usersMod->configured()) { return undef; } return 1; } # Method: preconditionFailMsg # # Check if the module is configured # # Overrides: # # sub preconditionFailMsg { my ($self) = @_; return __('You must enable the module Users in the module ' . 'status section in order to use it.'); } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/OU.pm0000664000000000000000000000274012017154745020303 0ustar #!/usr/bin/perl -w # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::OU # # Organizational Unit, stored in LDAP # package EBox::UsersAndGroups::OU; use strict; use warnings; use EBox::Global; use EBox::UsersAndGroups; use EBox::Exceptions::External; use EBox::Exceptions::MissingArgument; use EBox::Exceptions::InvalidData; use base 'EBox::UsersAndGroups::LdapObject'; sub new { my $class = shift; my %opts = @_; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub create { my ($self, $dn) = @_; my $users = EBox::Global->modInstance('users'); my %args = ( attr => [ 'objectclass' => ['organizationalUnit'], ] ); my $r = $self->_ldap->add($dn, \%args); my $res = new EBox::UsersAndGroups::OU(dn => $dn); return $res; } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Types/0000775000000000000000000000000012017154745020523 5ustar zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Types/KrbRealm.pm0000664000000000000000000000474112017154745022566 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::Types::KrbRealm # # A specialised text type to represent a kerberos realm # package EBox::Types::KrbRealm; use strict; use warnings; use base 'EBox::Types::DomainName'; use EBox::Validate; use EBox::Gettext; # Group: Public methods # Constructor: new # # The constructor for the # # Returns: # # The created object # sub new { my $class = shift; my $self = $class->SUPER::new(@_); $self->{'type'} = 'krbrealm'; bless ($self, $class); return $self; } # Group: Protected methods # Method: _paramIsValid # # Check if the params has a correct kerberos realm # # Overrides: # # # # Parameters: # # params - The HTTP parameters with contained the type # # Returns: # # true - if the parameter is a correct kerberos realm # # Exceptions: # # - throw if it's not a correct # kerberos realm # sub _paramIsValid { my ($self, $params) = @_; my $value = $params->{$self->fieldName()}; if (defined ($value)) { EBox::Validate::checkDomainName($value, $self->printableName()); my $seemsIp = EBox::Validate::checkIP($value); if ($seemsIp) { throw EBox::Exceptions::InvalidData( data => $self->printableName(), value => $value, advice => __('IP addresses are not allowed')); } unless ($value =~ /^[A-Z0-9]+([\.][A-Z0-9]+)+$/) { throw EBox::Exceptions::InvalidData( data => $self->printableName(), value => $value, advice => __('Invalid realm name. Often, the realm is the uppercase version of the local DNS domain.')); } } return 1; } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Types/Password.pm0000664000000000000000000000262512017154745022670 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::Types::Password; # # TODO # package EBox::UsersAndGroups::Types::Password; use strict; use warnings; use base 'EBox::Types::Password'; use EBox::Exceptions::MissingArgument; sub new { my $class = shift; my %opts = @_; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } # Method: restoreFromHash # # Overrides # # We don't need to restore anything from disk so we leave this method empty # sub restoreFromHash { } # Method: storeInHash # # Overrides # # Following the same reasoning as restoreFromHash, we don't need to store # anything in hash. # sub storeInHash { } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/User.pm0000664000000000000000000005166212017154745020705 0ustar #!/usr/bin/perl -w # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::User # # Zentyal user, stored in LDAP # package EBox::UsersAndGroups::User; use strict; use warnings; use EBox::Config; use EBox::Global; use EBox::Gettext; use EBox::UsersAndGroups; use EBox::UsersAndGroups::Group; use EBox::Exceptions::External; use EBox::Exceptions::MissingArgument; use EBox::Exceptions::InvalidData; use Perl6::Junction qw(any); use Convert::ASN1; use constant MAXUSERLENGTH => 128; use constant MAXPWDLENGTH => 512; use constant SYSMINUID => 1900; use constant MINUID => 2000; use constant HOMEPATH => '/home'; use constant QUOTA_PROGRAM => EBox::Config::scripts('users') . 'user-quota'; use constant QUOTA_LIMIT => 2097151; use constant CORE_ATTRS => ( 'cn', 'uid', 'sn', 'givenName', 'loginShell', 'uidNumber', 'gidNumber', 'homeDirectory', 'quota', 'userPassword', 'description'); use base 'EBox::UsersAndGroups::LdapObject'; sub new { my $class = shift; my %opts = @_; my $self = {}; if (defined $opts{uid}) { $self->{uid} = $opts{uid}; } else { $self = $class->SUPER::new(@_); } bless ($self, $class); return $self; } # Method: _entry # # Return Net::LDAP::Entry entry for the user # sub _entry { my ($self) = @_; unless ($self->{entry}) { if (defined $self->{uid}) { my $result = undef; my $attrs = { base => $self->_ldap->dn(), filter => "(uid=$self->{uid})", scope => 'sub', }; $result = $self->_ldap->search($attrs); if ($result->count() > 1) { throw EBox::Exceptions::Internal( __x('Found {count} results for, expected only one.', count => $result->count())); } $self->{entry} = $result->entry(0); } else { $self->SUPER::_entry(); } } return $self->{entry}; } # Method: name # # Return user name # sub name { my ($self) = @_; return $self->get('uid'); } sub fullname { my ($self) = @_; return $self->get('cn'); } sub firstname { my ($self) = @_; return $self->get('givenName'); } sub surname { my ($self) = @_; return $self->get('sn'); } sub home { my ($self) = @_; return $self->get('homeDirectory'); } sub quota { my ($self) = @_; return $self->get('quota'); } sub comment { my ($self) = @_; return $self->get('description'); } # Catch some of the set ops which need special actions sub set { my ($self, $attr, $value) = @_; # remember changes in core attributes (notify LDAP user base modules) if ($attr eq any CORE_ATTRS) { $self->{core_changed} = 1; } if ($attr eq 'quota') { if ($self->_checkQuota($value)) { throw EBox::Exceptions::InvalidData('data' => __('user quota'), 'value' => $value, 'advice' => __('User quota must be an integer. To set an unlimited quota, enter zero.'), ); } # set quota on save $self->{set_quota} = 1; } shift @_; $self->SUPER::set(@_); } # Catch some of the delete ops which need special actions sub delete { my ($self, $attr, $value) = @_; # remember changes in core attributes (notify LDAP user base modules) if ($attr eq any CORE_ATTRS) { $self->{core_changed} = 1; } shift @_; $self->SUPER::delete(@_); } sub save { my ($self) = @_; my $changetype = $self->_entry->changetype(); if ($self->{set_quota}) { my $quota = $self->get('quota'); $self->_checkQuota($quota); $self->_setFilesystemQuota($quota); delete $self->{set_quota}; } my $passwd = delete $self->{core_changed_password}; if (defined $passwd) { $self->_ldap->changeUserPassword($self->dn(), $passwd); } shift @_; $self->SUPER::save(@_); if ($changetype ne 'delete') { if ($self->{core_changed} or defined $passwd) { delete $self->{core_changed}; my $users = EBox::Global->modInstance('users'); $users->notifyModsLdapUserBase('modifyUser', [ $self, $passwd ], $self->{ignoreMods}, $self->{ignoreSlaves}); } } } # Method: setIgnoredModules # # Set the modules that should not be notified of the changes # made to this object # # Parameters: # # mods - Array reference cotaining module names # sub setIgnoredModules { my ($self, $mods) = @_; $self->{ignoreMods} = $mods; } # Method: setIgnoredSlaves # # Set the slaves that should not be notified of the changes # made to this object # # Parameters: # # mods - Array reference cotaining slave names # sub setIgnoredSlaves { my ($self, $slaves) = @_; $self->{ignoreSlaves} = $slaves; } # Method: addGroup # # Add this user to the given group # # Parameters: # # group - Group object # sub addGroup { my ($self, $group) = @_; $group->addMember($self); } # Method: removeGroup # # Removes this user from the given group # # Parameters: # # group - Group object # sub removeGroup { my ($self, $group) = @_; $group->removeMember($self); } # Method: groups # # Groups this user belongs to # # Parameters: # # system - return also system groups (default: false) *optional* # # Returns: # # array ref of EBox::UsersAndGroups::Group objects # sub groups { my ($self, $system) = @_; return $self->_groups($system); } # Method: groupsNotIn # # Groups this user does not belong to # # Parameters: # # system - return also system groups (default: false) *optional* # # Returns: # # array ref of EBox::UsersAndGroups::Group objects # sub groupsNotIn { my ($self, $system) = @_; return $self->_groups($system, 1); } sub _groups { my ($self, $system, $invert) = @_; my $filter; my $dn = $self->dn(); if ($invert) { $filter = "(&(objectclass=zentyalGroup)(!(member=$dn)))"; } else { $filter = "(&(objectclass=zentyalGroup)(member=$dn))"; } my %attrs = ( base => $self->_ldap->dn(), filter => $filter, scope => 'sub', ); my $result = $self->_ldap->search(\%attrs); my @groups; if ($result->count > 0) { foreach my $entry ($result->sorted('cn')) { if (not $system) { next if ($entry->get_value('gidNumber') < EBox::UsersAndGroups::Group->MINGID); } push (@groups, new EBox::UsersAndGroups::Group(entry => $entry)); } } return \@groups; } # Method: system # # Return 1 if this is a system user, 0 if not # sub system { my ($self) = @_; return ($self->get('uidNumber') < MINUID); } sub _checkQuota { my ($self, $quota) = @_; my $integer = $quota -~ m/^\d+$/; if (not $integer) { throw EBox::Exceptions::InvalidData('data' => __('user quota'), 'value' => $quota, 'advice' => __( 'User quota must be a positive integer. To set an unlimited quota, enter zero.' ), ); } if ($quota > QUOTA_LIMIT) { throw EBox::Exceptions::InvalidData( data => __('user quota'), value => $quota, advice => __x('The maximum value is {max} MB', max => QUOTA_LIMIT), ); } } sub _setFilesystemQuota { my ($self, $userQuota) = @_; my $uid = $self->get('uidNumber'); my $quota = $userQuota * 1024; EBox::Sudo::root(QUOTA_PROGRAM . " -s $uid $quota"); # check if quota has been really set my $output = EBox::Sudo::root(QUOTA_PROGRAM . " -q $uid"); my ($afterQuota) = $output->[0] =~ m/(\d+)/; if ((not defined $afterQuota) or ($quota != $afterQuota)) { EBox::error( __x('Cannot set quota for uid {uid} to {userQuota}. Maybe your file system does not support quota?', uid => $uid, userQuota => $userQuota) ); } } # Method: changePassword # # Configure a new password for the user # sub changePassword { my ($self, $passwd, $lazy) = @_; $self->_checkPwdLength($passwd); # The password will be changed on save, save it also to # notify LDAP user base mods $self->{core_changed_password} = $passwd; $self->save() unless $lazy; } # Method: setPasswordFromHashes # # Configure user password directly from its kerberos hashes # # Parameters: # # passwords - array ref of krb5keys # sub setPasswordFromHashes { my ($self, $passwords) = @_; $self->set('userPassword', '{K5KEY}'); $self->set('krb5Key', $passwords); $self->set('krb5KeyVersionNumber', 1); } # Method: deleteObject # # Delete the user # sub deleteObject { my ($self) = @_; # remove this user from all its grups foreach my $group (@{$self->groups()}) { $self->removeGroup($group); } # Notify users deletion to modules my $users = EBox::Global->modInstance('users'); $users->notifyModsLdapUserBase('delUser', $self, $self->{ignoreMods}, $self->{ignoreSlaves}); # Mark as changed to process save $self->{core_changed} = 1; # Call super implementation shift @_; $self->SUPER::deleteObject(@_); } # Method: passwordHashes # # Return an array ref to all krb hashed passwords as: # # [ hash, hash, ... ] # sub passwordHashes { my ($self) = @_; my @keys = $self->get('krb5Key'); return \@keys; } # USER CREATION: # Method: create # # Adds a new user # # Parameters: # # user - hash ref containing: 'user'(user name), 'fullname', 'givenname', # 'surname' and 'comment' # system - boolean: if true it adds the user as system user, otherwise as # normal user # params hash (all optional): # uidNumber - user UID numberer # ou (multiple_ous enabled only) # ignoreMods - modules that should not be notified about the user creation # ignoreSlaves - slaves that should not be notified about the user creation # # Returns: # # Returns the new create user object # sub create { my ($self, $user, $system, %params) = @_; my $users = EBox::Global->modInstance('users'); unless (_checkUserName($user->{'user'})) { my $advice = __('To avoid problems, the username should consist only of letters, digits, underscores, spaces, periods, dashs, not start with a dash and not end with dot'); throw EBox::Exceptions::InvalidData('data' => __('user name'), 'value' => $user->{'user'}, 'advice' => $advice ); } # Is the user added to the default OU? my $isDefaultOU = 1; my $dn; if (EBox::Config::configkey('multiple_ous') and $user->{ou}) { $dn = 'uid=' . $user->{user} . ',' . $user->{ou}; $isDefaultOU = ($user->{ou} eq $users->usersDn()); } else { $dn = $users->userDn($user->{'user'}); } if (length($user->{'user'}) > MAXUSERLENGTH) { throw EBox::Exceptions::External( __x("Username must not be longer than {maxuserlength} characters", maxuserlength => MAXUSERLENGTH)); } # Verify user exists if (new EBox::UsersAndGroups::User(dn => $dn)->exists()) { throw EBox::Exceptions::DataExists('data' => __('user name'), 'value' => $user->{'user'}); } my @userPwAttrs = getpwnam($user->{'user'}); if (@userPwAttrs) { throw EBox::Exceptions::External( __("Username already exists on the system") ); } my $homedir = _homeDirectory($user->{'user'}); if (-e $homedir) { throw EBox::Exceptions::External( __x('Cannot create user because the home directory {dir} already exists. Please move or remove it before creating this user', dir => $homedir) ); } # Check the password length if specified my $passwd = $user->{'password'}; if (defined $passwd) { $self->_checkPwdLength($passwd); } my $uid = exists $params{uidNumber} ? $params{uidNumber} : $self->_newUserUidNumber($system); $self->_checkUid($uid, $system); my $defaultGroupDN = $users->groupDn(EBox::UsersAndGroups->DEFAULTGROUP); my $group = new EBox::UsersAndGroups::Group(dn => $defaultGroupDN); my $gid = $group->get('gidNumber'); # If fullname is not specified we build it with # givenname and surname unless (defined $user->{'fullname'}) { $user->{'fullname'} = ''; if ($user->{'givenname'}) { $user->{'fullname'} = $user->{'givenname'} . ' '; } $user->{'fullname'} .= $user->{'surname'}; } my $realm = $users->kerberosRealm(); my $quota = $self->defaultQuota(); my @attr = ( 'cn' => $user->{fullname}, 'uid' => $user->{user}, 'sn' => $user->{surname}, 'givenName' => $user->{givenname}, 'loginShell' => $self->_loginShell(), 'uidNumber' => $uid, 'gidNumber' => $gid, 'homeDirectory' => $homedir, 'quota' => $quota, 'objectclass' => [ 'inetOrgPerson', 'posixAccount', 'passwordHolder', 'systemQuotas', 'krb5Principal', 'krb5KDCEntry' ], 'krb5PrincipalName' => $user->{user} . '@' . $realm, 'krb5KeyVersionNumber' => 0, 'krb5MaxLife' => 86400, # TODO 'krb5MaxRenew' => 604800, # TODO 'krb5KDCFlags' => 126, # TODO ); push (@attr, 'description' => $user->{comment}) if ($user->{comment}); my %args = ( attr => \@attr ); my $r = $self->_ldap->add($dn, \%args); my $res = new EBox::UsersAndGroups::User(dn => $dn); # Set the user password and kerberos keys if (defined $passwd) { $self->_checkPwdLength($passwd); $res->_ldap->changeUserPassword($res->dn(), $passwd); } elsif (defined($user->{passwords})) { $res->setPasswordFromHashes($user->{passwords}); } # Init user unless ($system) { # only default OU users are initializated if ($isDefaultOU) { $users->reloadNSCD(); $users->initUser($res, $passwd); $res->_setFilesystemQuota($quota); } # Call modules initialization $users->notifyModsLdapUserBase('addUser', [ $res, $passwd ], $params{ignoreMods}, $params{ignoreSlaves}); } if ($res->{core_changed}) { # save() will be take also of saving password if it is changed $res->save(); } # Return the new created user return $res; } sub _checkName { my ($name) = @_; if ($name =~ /^([a-zA-Z\d\s_-]+\.)*[a-zA-Z\d\s_-]+$/) { return 1; } else { return undef; } } sub _checkUserName { my ($name) = @_; if (not EBox::UsersAndGroups::checkNameLimitations($name)) { return undef; } # windows user names cannot end with a period if ($name =~ m/\.$/) { return undef; } return 1; } sub _homeDirectory { my ($username) = @_; my $home = HOMEPATH . '/' . $username; return $home; } # Method: lastUid # # Returns the last uid used. # # Parameters: # # system - boolean: if true, it returns the last uid for system users, # otherwise the last uid for normal users # # Returns: # # string - last uid # sub lastUid { my ($self, $system) = @_; my $lastUid = -1; my $users = EBox::Global->modInstance('users'); foreach my $user (@{$users->users($system)}) { my $uid = $user->get('uidNumber'); if ($system) { last if ($uid >= MINUID); } else { next if ($uid < MINUID); } if ($uid > $lastUid) { $lastUid = $uid; } } if ($system) { return ($lastUid < SYSMINUID ? SYSMINUID : $lastUid); } else { return ($lastUid < MINUID ? MINUID : $lastUid); } } sub _newUserUidNumber { my ($self, $systemUser) = @_; my $uid; if ($systemUser) { $uid = $self->lastUid(1) + 1; if ($uid == MINUID) { throw EBox::Exceptions::Internal( __('Maximum number of system users reached')); } } else { $uid = $self->lastUid + 1; } return $uid; } sub _checkUid { my ($self, $uid, $system) = @_; if ($uid < MINUID) { if (not $system) { throw EBox::Exceptions::External( __x('Incorrect UID {uid} for a user . UID must be equal or greater than {min}', uid => $uid, min => MINUID, ) ); } } else { if ($system) { throw EBox::Exceptions::External( __x('Incorrect UID {uid} for a system user . UID must be lesser than {max}', uid => $uid, max => MINUID, ) ); } } } sub _checkPwdLength { my ($self, $pwd) = @_; # Is hashed? if ($pwd =~ /^\{[0-9A-Z]+\}/) { return; } if (length($pwd) > MAXPWDLENGTH) { throw EBox::Exceptions::External( __x("Password must not be longer than {maxPwdLength} characters", maxPwdLength => MAXPWDLENGTH)); } } sub _loginShell { my ($self) = @_; my $users = EBox::Global->modInstance('users'); return $users->model('PAM')->login_shellValue(); } sub defaultQuota { my ($self) = @_; my $users = EBox::Global->modInstance('users'); my $model = $users->model('AccountSettings'); my $value = $model->defaultQuotaValue(); if ($value eq 'defaultQuota_disabled') { $value = 0; } return $value; } sub kerberosKeys { my ($self) = @_; my $keys = []; my $syntaxFile = EBox::Config::scripts('users') . 'krb5Key.asn'; my $asn = Convert::ASN1->new(); $asn->prepare_file($syntaxFile) or throw EBox::Exceptions::Internal($asn->error()); my $asn_key = $asn->find('Key') or throw EBox::Exceptions::Internal($asn->error()); my @aux = $self->get('krb5Key'); foreach my $blob (@aux) { my $key = $asn_key->decode($blob) or throw EBox::Exceptions::Internal($asn_key->error()); push @{$keys}, { type => $key->{key}->{value}->{keytype}->{value}, value => $key->{key}->{value}->{keyvalue}->{value}, salt => $key->{salt}->{value}->{salt}->{value} }; } return $keys; } sub setKerberosKeys { my ($self, $keys) = @_; unless (defined $keys) { throw EBox::Exceptions::MissingArgument('keys'); } my $syntaxFile = EBox::Config::scripts('users') . 'krb5Key.asn'; my $asn = Convert::ASN1->new(); $asn->prepare_file($syntaxFile) or throw EBox::Exceptions::Internal($asn->error()); my $asn_key = $asn->find('Key') or throw EBox::Exceptions::Internal($asn->error()); my $blobs = []; foreach my $key (@{$keys}) { my $salt = undef; if (defined $key->{salt}) { $salt = { value => { type => { value => 3 }, salt => { value => $key->{salt} }, opaque => { value => '', }, }, }; } my $blob = $asn_key->encode( mkvno => { value => 0 }, salt => $salt, key => { value => { keytype => { value => $key->{type} }, keyvalue => { value => $key->{value} } } }) or throw EBox::Exceptions::Internal($asn_key->error()); push (@{$blobs}, $blob); } $self->set('krb5Key', $blobs); } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Slave.pm0000664000000000000000000001043712017154745021034 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::Slave # # These methods will be called when a user or group is added, # modified or deleted. They can be implemented in order to sync # that changes to other machines (master provider). # package EBox::UsersAndGroups::Slave; use strict; use warnings; use base 'EBox::LdapUserBase'; use EBox::Exceptions::Internal; use EBox::Exceptions::NotImplemented; use Error qw(:try); use File::Temp qw/tempfile/; use Time::HiRes qw(gettimeofday); use JSON::XS; use File::Slurp; use EBox::UsersAndGroups::LdapObject; use EBox::UsersAndGroups::Group; use EBox::UsersAndGroups::User; # Method: new # # Create a new slave instance, choosen name should # be unique between all the slaves # sub new { my $class = shift; my %opts = @_; my $self = {}; $self->{name} = delete $opts{name}; unless (defined($self->{name})) { throw EBox::Exceptions::Internal('No name provided'); } bless($self, $class); return $self; } # Method: sync # # Synchronize an action to the slave. # If something fails (for example connectivity) the action # will be saved for later, and synchronized by slaves-sync daemon # sub sync { my ($self, $signal, $args) = @_; try { my $method = '_' . $signal; $self->$method(@{$args}); } otherwise { # Sync failed, save pending action my $name = $self->name(); EBox::error("Error notifying $name for $signal"); $self->savePendingSync($signal, $args); }; } # method: savePendingSync # # Save a sync operaction which failed, later slaves-sync should # retry it by using syncFromFile # sub savePendingSync { my ($self, $signal, $args) = @_; my $users = EBox::Global->modInstance('users'); my $dir = $users->syncJournalDir($self); my $time = join('', gettimeofday()); my ($fh, $filename) = tempfile("$time-$signal-XXXX", DIR => $dir); $self->writeActionInfo($fh, $signal, $args); $fh->close(); } sub writeActionInfo { my ($self, $fh, $signal, $args) = @_; my @params; foreach my $arg (@{$args}) { if (ref($arg) =~ /::/) { if ($arg->isa('EBox::UsersAndGroups::LdapObject')) { my @lines = split(/\n/, $arg->as_ldif()); $arg = { class => ref($arg), ldif => \@lines, }; } } push (@params, $arg); } # JSON encode args my $action = { signal => $signal, args => \@params, }; print $fh encode_json($action); } # method: syncFromFile # # Try to sync a saved action from a previous failed sync # sub syncFromFile { my ($self, $file) = @_; my $action = $self->readActionInfo($file); my $method = '_' . $action->{signal}; my $args = $action->{args}; try { $self->$method(@{$args}); unlink ($file); } otherwise { my $name = $self->name(); EBox::error("Error notifying $name for $method"); }; } sub readActionInfo { my ($self, $file) = @_; my $action = decode_json(read_file($file)); my $signal = $action->{signal}; my $args = $action->{args}; my @params; foreach my $arg (@{$args}) { if (ref($arg) eq 'HASH') { # Import LDIF my ($fh, $ldif) = tempfile(UNLINK => 1); print $fh join("\n", @{$arg->{ldif}}); $fh->close(); my $class = $arg->{class}; $arg = $class->new(ldif => $ldif); } push (@params, $arg); } $action->{args} = \@params; return $action; } sub name { my ($self) = @_; return $self->{name}; } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/LdapObject.pm0000664000000000000000000001372712017154745021776 0ustar #!/usr/bin/perl -w # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::UsersAndGroups::LdapObject; use strict; use warnings; use EBox::Config; use EBox::Global; use EBox::UsersAndGroups; use EBox::Gettext; use EBox::Exceptions::External; use EBox::Exceptions::MissingArgument; use EBox::Exceptions::InvalidData; use Net::LDAP::LDIF; use Net::LDAP::Constant qw(LDAP_LOCAL_ERROR); use Perl6::Junction qw(any); # Method: new # # Instance an object readed from LDAP. # # Parameters: # # dn - Full dn for the user # or # ldif - Reads the entry from LDIF # or # entry - Net::LDAP entry for the user # sub new { my ($class, %params) = @_; my $self = {}; bless ($self, $class); unless ($params{entry} or $params{dn} or $params{ldif}) { throw EBox::Exceptions::MissingArgument('entry|dn|ldif'); } if ($params{entry}) { $self->{entry} = $params{entry}; } elsif ($params{ldif}) { my $ldif = Net::LDAP::LDIF->new($params{ldif}, "r"); $self->{entry} = $ldif->read_entry(); } elsif ($params{dn}) { $self->{dn} = $params{dn}; } return $self; } # Method: exists # # Returns 1 if the object exist, 0 if not # sub exists { my ($self) = @_; # User exists if we already have its entry return 1 if ($self->{entry}); $self->{entry} = $self->_entry(); return (defined $self->{entry}); } # Method: get # # Read an user attribute # # Parameters: # # attribute - Attribute name to read # sub get { my ($self, $attr) = @_; return $self->_entry->get_value($attr); } # Method: set # # Set an user attribute. # # Parameters: # # attribute - Attribute name to read # value - Value to set (scalar or array ref) # lazy - Do not update the entry in LDAP # sub set { my ($self, $attr, $value, $lazy) = @_; $self->_entry->replace($attr => $value); $self->save() unless $lazy; } # Method: add # # Adds a value to an attribute without removing previous ones (if any) # # Parameters: # # attribute - Attribute name to read # value - Value to set (scalar or array ref) # lazy - Do not update the entry in LDAP # sub add { my ($self, $attr, $value, $lazy) = @_; $self->_entry->add($attr => $value); $self->save() unless $lazy; } # Method: delete # # Deletes an attribute from the object if given # # Parameters (for attribute deletion): # # attribute - Attribute name to read # lazy - Do not update the entry in LDAP # sub delete { my ($self, $attr, $lazy) = @_; if ($attr eq any $self->_entry->attributes) { $self->_entry->delete($attr); $self->save() unless $lazy; } } # Method: deleteObject # # Deletes this object from the LDAP # sub deleteObject { my ($self, $attr, $lazy) = @_; $self->_entry->delete(); $self->save(); } # Method: remove # # Remove a value from the given attribute, or the whole # attribute if no values left # # If an array ref is received as value, all the values will be # deleted at the same time # # Parameters: # # attribute - Attribute name # value(s) - Value(s) to remove (value or array ref to values) # lazy - Do not update the entry in LDAP # sub remove { my ($self, $attr, $value, $lazy) = @_; # Delete attribute only if it exists if ($attr eq any $self->_entry->attributes) { if (ref ($value) ne 'ARRAY') { $value = [ $value ]; } $self->_entry->delete($attr, $value); $self->save() unless $lazy; } } # Method: save # # Store all pending lazy operations (if any) # # This method is only needed if some operation # was used using lazy flag # sub save { my ($self) = @_; my $result = $self->_entry->update($self->_ldap->{ldap}); if ($result->is_error()) { unless ($result->code == LDAP_LOCAL_ERROR and $result->error eq 'No attributes to update') { throw EBox::Exceptions::External(__('There was an error updating LDAP: ') . $result->error()); } } } # Method: dn # # Return DN for this object # sub dn { my ($self) = @_; return $self->_entry->dn(); } # Method: baseDn # # Return base DN for this object # sub baseDn { my ($self) = @_; my ($trash, $basedn) = split(/,/, $self->dn(), 2); return $basedn; } # Method: _entry # # Return Net::LDAP::Entry entry for the user # sub _entry { my ($self) = @_; unless ($self->{entry}) { my $result = undef; if (defined $self->{dn}) { my ($filter, $basedn) = split(/,/, $self->{dn}, 2); my $attrs = { base => $basedn, filter => $filter, scope => 'one', }; $result = $self->_ldap->search($attrs); } return undef unless defined $result; if ($result->count() > 1) { throw EBox::Exceptions::Internal( __x('Found {count} results for, expected only one.', count => $result->count())); } $self->{entry} = $result->entry(0); } return $self->{entry}; } sub _ldap { my ($self) = @_; return EBox::Global->modInstance('users')->ldap(); } # Method: as_ldif # # Returns a string containing the LDAP entry as LDIF # sub as_ldif { my ($self) = @_; return $self->_entry->ldif(change => 0); } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/SyncProvider.pm0000664000000000000000000000306612017154745022411 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::SyncProvider # # This is an abstract class for user synchronization providers. # Each provider can act as master, slave or both. # # "slaves" method should return a list of slaves for this provider # # To act as master, common methods (create, modify and delete) should # be used on users and group objects. # package EBox::UsersAndGroups::SyncProvider; use strict; use warnings; use EBox::Exceptions::NotImplemented; # Method: slaves # # Return a list of instances implementing EBox::UsersSync::Base # # Returns: # # array ref - UserSynchronizer instances for this module # sub slaves { throw EBox::Exceptions::NotImplemented(); } # Method: allowUserChanges # # Return 1 if the user should be allowed to make changes # to the users. 0 if not (usually slave machines) # sub allowUserChanges { throw EBox::Exceptions::NotImplemented(); } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Model/0000775000000000000000000000000012017154745020457 5ustar zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Model/Mode.pm0000664000000000000000000000666612017154745021717 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::Model::Mode # # This class contains the options needed to enable the usersandgroups module. package EBox::UsersAndGroups::Model::Mode; use base 'EBox::Model::DataForm'; use EBox::Gettext; use EBox::Types::Text; use EBox::Types::KrbRealm; use EBox::Exceptions::InvalidData; use strict; use warnings; # Group: Public methods # Constructor: new # # Create a data form # # Overrides: # # # sub new { my ($class, %params) = @_; my $self = $class->SUPER::new(%params); bless( $self, $class ); return $self; } # Method: validateTypedRow # # Check the kerberos realm and LDAP base DN # # Overrides: # # # sub validateTypedRow { my ($self, $action, $changedFields) = @_; if (exists $changedFields->{dn}) { my $dn = $changedFields->{dn}->value(); $self->_validateDN($dn); } } # Method: _table # # Overrides 'dn', printableName => __('LDAP DN'), editable => 1, allowUnsafeChars => 1, size => 36, defaultValue => \&_dnFromHostname, help => __('This will be the DN suffix in LDAP tree') ), # new EBox::Types::KrbRealm ( # fieldName => 'defaultRealm', # printableName => __('Default authentication realm'), # editable => 1, # allowUnsafeChars => 0, # size => 36, # defaultValue => \&_realmFromHostname, # help => __('This will be the users authentication realm.') # ), ); my $dataForm = { tableName => 'Mode', printableTableName => __('Configuration'), pageTitle => __('Zentyal Users'), defaultActions => [ 'editField', 'changeView' ], tableDescription => \@tableDesc, modelDomain => 'Users', }; return $dataForm; } sub _dnFromHostname { my $sysinfo = EBox::Global->modInstance('sysinfo'); my $domain = $sysinfo->hostDomain(); $domain =~ s/[^A-Za-z0-9\.]/-/g; my $dn = join(',', map("dc=$_", split(/\./, $domain))); return $dn; } #sub _realmFromHostname #{ # my $sysinfo = EBox::Global->modInstance('sysinfo'); # my $domain = $sysinfo->hostDomain(); # $domain =~ s/[^A-Za-z0-9\.]/-/g; # $domain = uc ($domain); # return $domain; #} # TODO: Move this to EBox::Validate or even create a new DN type sub _validateDN { my ($self, $dn) = @_; unless ($dn =~ /^dc=[^,=]+(,dc=[^,=]+)*$/) { throw EBox::Exceptions::InvalidData(data => __('LDAP DN'), value => $dn); } } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Model/Master.pm0000664000000000000000000001316112017154745022252 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::Model::Master # # From to configure a Zentyal master to provide users to this server package EBox::UsersAndGroups::Model::Master; use base 'EBox::Model::DataForm'; use EBox::Gettext; use EBox::Types::Select; use EBox::Types::Host; use EBox::Types::Port; use EBox::Types::Boolean; use EBox::Types::Password; use EBox::Exceptions::DataInUse; use EBox::View::Customizer; use strict; use warnings; use constant VIEW_CUSTOMIZER => { none => { hide => [ 'host', 'port', 'password' ] }, zentyal => { show => [ 'host', 'port', 'password' ] }, cloud => { hide => [ 'host', 'port', 'password' ] }, }; # Group: Public methods # Constructor: new # # Create a data form # # Overrides: # # # sub new { my ($class, %params) = @_; my $self = $class->SUPER::new(%params); bless( $self, $class ); return $self; } # Method: _table # # Overrides 'none', printableValue => __('None') }, { value => 'zentyal', printableValue => __('Other Zentyal Server') }, ]; # TODO - check cloud permissions for this feature if (EBox::Global->modExists('remoteservices')) { push ($master_options, { value => 'cloud', printableValue => __('Zentyal Cloud') } ); } my @tableDesc = ( new EBox::Types::Select ( fieldName => 'master', printableName => __('Sync users from'), options => $master_options, help => __('Sync users from the chosen source'), editable => 1, ), new EBox::Types::Host ( fieldName => 'host', printableName => __('Master host'), editable => \&_unlocked, help => __('Hostname or IP of the master'), ), new EBox::Types::Port ( fieldName => 'port', printableName => __('Master port'), defaultValue => 443, editable => \&_unlocked, help => __('Master port for Zentyal Administration (default: 443)'), ), new EBox::Types::Password ( fieldName => 'password', printableName => __('Slave password'), editable => \&_unlocked, hidden => \&_locked, help => __('Password for new slave connection'), ), ); my $dataForm = { tableName => 'Master', printableTableName => __('Sync users from a master server'), defaultActions => [ 'editField', 'changeView' ], tableDescription => \@tableDesc, modelDomain => 'Users', help => __('Configure this parameters to synchronize users from a master server'), }; return $dataForm; } # Method: viewCustomizer # # Hide/show master options if Zentyal as master is configured # # Overrides: # # # sub viewCustomizer { my ($self) = @_; my $customizer = new EBox::View::Customizer(); $customizer->setModel($self); $customizer->setOnChangeActions( { master => VIEW_CUSTOMIZER } ); return $customizer; } sub _locked { my $users = EBox::Global->modInstance('users'); my $master = $users->get_hash('Master/keys/form'); return (defined($master) and $master->{master} eq 'zentyal'); } sub _unlocked { return (not _locked()); } sub validateTypedRow { my ($self, $action, $changedParams, $allParams, $force) = @_; my $master = exists $allParams->{master} ? $allParams->{master}->value() : $changedParams->{master}->value(); my $enabled = ($master ne 'none'); # do not check if disabled return unless ($enabled); my $users = EBox::Global->modInstance('users'); if ($master eq 'zentyal') { # Check master is accesible my $host = exists $allParams->{host} ? $allParams->{host}->value() : $changedParams->{host}->value(); my $port = exists $allParams->{port} ? $allParams->{port}->value() : $changedParams->{port}->value(); my $password = exists $allParams->{password} ? $allParams->{password}->value() : $changedParams->{password}->value(); $users->masterConf->checkMaster($host, $port, $password); } unless ($force) { my $nUsers = scalar @{$users->users()}; if ($nUsers > 0) { throw EBox::Exceptions::DataInUse(__('CAUTION: this will delete all defined users and import master ones.')); } } # set apache as changed my $apache = EBox::Global->modInstance('apache'); $apache->setAsChanged(); } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Model/LdapInfo.pm0000664000000000000000000000556612017154745022525 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::Model::Mode # # This class contains the options needed to enable the usersandgroups module. package EBox::UsersAndGroups::Model::LdapInfo; use base 'EBox::Model::DataForm::ReadOnly'; use EBox::Global; use EBox::Gettext; use EBox::Types::Text; use strict; use warnings; # Method: _table # # Overrides 'dn', printableName => __('Base DN'), ), new EBox::Types::Text ( fieldName => 'rootDn', printableName => __('Root DN'), ), new EBox::Types::Text ( fieldName => 'password', printableName => __('Password'), ), new EBox::Types::Text ( fieldName => 'usersDn', printableName => __('Users DN'), ), new EBox::Types::Text ( fieldName => 'groupsDn', printableName => __('Groups DN'), ), ); my $dataForm = { tableName => 'LdapInfo', printableTableName => __('LDAP information'), defaultActions => [ 'editField', 'changeView' ], tableDescription => \@tableDesc, modelDomain => 'Users', }; return $dataForm; } sub menuFolder { return 'UsersAndGroups'; } # Method: _content # # Overrides: # # # sub _content { my ($self) = @_; my $users = $self->parentModule(); return { dn => $users->ldap()->dn(), rootDn => $users->ldap()->rootDn(), password => $users->ldap()->getPassword(), usersDn => $users->usersDn(), groupsDn => $users->groupsDn(), } } # Method: precondition # # Check if usersandgroups is enabled. # # Overrides: # # # sub precondition { my ($self) = @_; return $self->parentModule()->isEnabled(); } # Method: preconditionFailMsg # # Returns message to be shown on precondition fail # sub preconditionFailMsg { return __('You must enable the Users and Groups module to access the LDAP information.'); } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Model/Users.pm0000664000000000000000000001353112017154745022121 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::UsersAndGroups::Model::Users; # Class: EBox::UsersAndGroups::Model::Users # # This a class used as a proxy for the users stored in LDAP. # It is meant to improve the user experience when managing users, # but it's just an interim solution. An integral approach needs to # be done. # use EBox::Global; use EBox::Gettext; use EBox::Validate qw(:all); use EBox::Model::Row; use EBox::Exceptions::External; use EBox::Exceptions::Internal; use EBox::Types::Text; use EBox::Types::Link; use strict; use warnings; use base 'EBox::Model::DataTable'; sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub _table { my @tableHead = ( new EBox::Types::Text( 'fieldName' => 'name', 'printableName' => __('Name'), 'size' => '12', ), new EBox::Types::Text( 'fieldName' => 'fullname', 'printableName' => __('Full name'), 'size' => '12', ), new EBox::Types::Link( 'fieldName' => 'edit', 'printableName' => __('Edit'), ), ); my $dataTable = { 'tableName' => 'Users', 'printableTableName' => __('Users'), 'defaultController' => '/Users/Controller/Users', 'defaultActions' => ['changeView'], 'tableDescription' => \@tableHead, 'menuNamespace' => 'UsersAndGroups/Users', 'printableRowName' => __('user'), 'sortedBy' => 'name', 'withoutActions' => 1, }; return $dataTable; } sub Viewer { return '/users/usersTableBody.mas'; } # Method: precondition # # Check if the module is configured # # Overrides: # # sub precondition { my ($self) = @_; my $users = EBox::Global->modInstance('users'); unless ($users->configured()) { $self->{preconFail} = 'notConfigured'; return undef; } unless (@{$self->ids()}) { $self->{preconFail} = 'noUsers'; return undef; } return 1; } # Method: preconditionFailMsg # # Check if the module is configured # # Overrides: # # sub preconditionFailMsg { my ($self) = @_; if ($self->{preconFail} eq 'notConfigured') { return __('You must enable the module Users in the module ' . 'status section in order to use it.'); } else { my $users = $self->parentModule(); my $mode = $users->mode(); if ($mode eq 'master') { return $self->noUsersMsg(); } elsif ($mode eq 'slave') { my $master = $users->model('Mode')->remoteValue(); return __x('Zentyal is configured as slave and there are no users at the moment. You may want to add some in the {openhref}master{closehref}.', openhref => "", closehref => ''); } elsif ($mode eq 'ad-slave') { return __('Zentyal is configured as Windows AD slave and there are no users at the moment. If there are users in your Domain Controller, maybe the synchronization process has failed or has not finished yet.'); } } } sub noUsersMsg { my ($self) = @_; my $filterOU = $self->filterOU(); EBox::debug("noDataMsg $filterOU"); if (not $filterOU) { return __x('There are no users at the moment'); } return __x('There are no users for the organizational unit: {ou}

{ao}See users for all organizational units{ac}', ou => $filterOU, ao => q{}, ac => q{} ); } # Method: ids # # Override to return rows identifiers # based on the users stored in LDAP # sub ids { my ($self) = @_; my $users = EBox::Global->modInstance('users'); unless ($users->configured()) { return []; } my @list = map { $_->dn() } @{$users->users()}; my $filterOU = $self->filterOU(); if ($filterOU) { my $filterRe = qr/,$filterOU$/; @list = grep { $_ =~ m/$filterRe/; } @list; } return \@list; } # Method: row # # Override to build and return a # row dependening on the user uid which is the id passwd. # sub row { my ($self, $id) = @_; my $user = new EBox::UsersAndGroups::User(dn => $id); if ($user->exists()) { my $full = $user->get('cn'); my $userName = $user->get('uid'); my $link = "/UsersAndGroups/User?user=$id"; my $row = $self->_setValueRow( name => $userName, fullname => $full, edit => $link, ); $row->setId($id); $row->setReadOnly(1); return $row; } else { throw EBox::Exceptions::Internal("user $id does not exist"); } } sub setFilterOU { my ($self, $filter) = @_; $self->{filterOU} = $filter; } sub filterOU { my ($self) = @_; if (not $self->parentModule()->multipleOusEnabled()) { return undef; } return $self->{filterOU}; } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Model/Groups.pm0000664000000000000000000001164512017154745022303 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::UsersAndGroups::Model::Groups; # Class: EBox::UsersAndGroups::Model::Groups # # This a class used as a proxy for the groups stored in LDAP. # It is meant to improve the user experience when managing groups, # but it's just an interim solution. An integral approach needs to # be done. # use EBox::Global; use EBox::Gettext; use EBox::Validate qw(:all); use EBox::Model::Row; use EBox::Exceptions::External; use EBox::UsersAndGroups::Group; use EBox::Types::Text; use EBox::Types::Link; use strict; use warnings; use base 'EBox::Model::DataTable'; sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub _table { my @tableHead = ( new EBox::Types::Text( 'fieldName' => 'name', 'printableName' => __('Name'), 'size' => '12', ), new EBox::Types::Text( 'fieldName' => 'description', 'printableName' => __('Description'), 'size' => '30', ), new EBox::Types::Link( 'fieldName' => 'edit', 'printableName' => __('Edit'), ), ); my $dataTable = { 'tableName' => 'Groups', 'printableTableName' => __('Groups'), 'defaultController' => '/Users/Controller/Groups', 'defaultActions' => ['changeView'], 'tableDescription' => \@tableHead, 'menuNamespace' => 'UsersAndGroups/Groups', 'help' => '', 'printableRowName' => __('group'), 'sortedBy' => 'name', 'withoutActions' => 1, }; return $dataTable; } # Method: precondition # # Check if the module is configured # # Overrides: # # sub precondition { my ($self) = @_; my $usersMod = EBox::Global->modInstance('users'); unless ($usersMod->configured()) { $self->{preconFail} = 'notConfigured'; return undef; } unless (@{$usersMod->groups()}) { $self->{preconFail} = 'noGroups'; return undef; } return 1; } # Method: preconditionFailMsg # # Check if the module is configured # # Overrides: # # sub preconditionFailMsg { my ($self) = @_; if ($self->{preconFail} eq 'notConfigured') { return __('You must enable the module Users in the module ' . 'status section in order to use it.'); } else { my $users = $self->parentModule(); my $mode = $users->mode(); if ($mode eq 'master') { return __x('There are no groups at the moment'); } elsif ($mode eq 'slave') { my $master = $users->model('Mode')->remoteValue(); return __x('Zentyal is configured as slave and there are no groups at the moment. You may want to add some in the {openhref}master{closehref}.', openhref => "", closehref => ''); } elsif ($mode eq 'ad-slave') { return __('Zentyal is configured as Windows AD slave and there are no groups at the moment. If there are groups in your Domain Controller, maybe the synchronization process has failed or has not finished yet.'); } } } # Method: ids # # Override to return rows identifiers # based on the groups stored in LDAP # sub ids { my ($self) = @_; my $users = EBox::Global->modInstance('users'); unless ($users->configured()) { return []; } my @list = map { $_->dn() } @{$users->groups()}; return \@list; } # Method: row # # Override to build and return a # row dependening on the user gid which is the id passwd. # sub row { my ($self, $id) = @_; my $group = new EBox::UsersAndGroups::Group(dn => $id); my $desc = $group->get('description'); my $name = $group->get('cn'); my $link = "/UsersAndGroups/Group?group=" . $group->dn(); my $row = $self->_setValueRow( name => $name, description => defined($desc) ? $desc : '-', edit => $link); $row->setId($id); $row->setReadOnly(1); return $row; } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Model/Password.pm0000664000000000000000000000516512017154745022626 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Class: EBox::UsersAndGroups::Model::Password # # TODO: Document class # package EBox::UsersAndGroups::Model::Password; use EBox::Gettext; use EBox::Validate qw(:all); use EBox::UsersAndGroups::Types::Password; use Apache2::RequestUtil; use File::Temp qw/tempfile/; use strict; use warnings; use base 'EBox::Model::DataForm'; sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub pageTitle { return __('Password management'); } sub _table { my @tableHead = ( new EBox::UsersAndGroups::Types::Password( 'fieldName' => 'pass1', 'printableName' => __('New password'), 'size' => '8', 'unique' => 1, 'editable' => 1 ), new EBox::UsersAndGroups::Types::Password( 'fieldName' => 'pass2', 'printableName' => __('Re-type new password'), 'size' => '8', 'unique' => 1, 'editable' => 1 ), ); my $dataTable = { 'tableName' => 'Password', 'printableTableName' => __('Password'), 'modelDomain' => 'Users', 'defaultActions' => ['add', 'del', 'editField', 'changeView' ], 'tableDescription' => \@tableHead, 'help' => '', # FIXME }; return $dataTable; } sub setTypedRow { my ($self, $id, $paramsRef, %optParams) = @_; my $pass1 = $paramsRef->{'pass1'}; my $pass2 = $paramsRef->{'pass2'}; my $r = Apache2::RequestUtil->request; my $user = $r->user; $user = new EBox::UsersAndGroups::User(uid => $user); if ($pass1->cmp($pass2) != 0) { throw EBox::Exceptions::External(__('Passwords do not match.')); } $user->changePassword($pass1->value()); eval 'use EBox::UserCorner::Auth'; EBox::UserCorner::Auth->updatePassword($user, $pass1->value()); $self->setMessage(__('Password successfully updated')); } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Model/SlavePassword.pm0000664000000000000000000000313612017154745023615 0ustar # Copyright (C) 2009-2011 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Class: EBox::UsersAndGroups::Model::SlavePassword # # Next password to use on slave registering # package EBox::UsersAndGroups::Model::SlavePassword; use EBox::Gettext; use EBox::Types::Text; use strict; use warnings; use base 'EBox::Model::DataForm'; sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub _table { my @tableHead = ( new EBox::Types::Text( 'fieldName' => 'password', 'printableName' => __('Slave connection password'), 'unique' => 1, ), ); my $dataTable = { 'tableName' => 'SlavePassword', 'printableTableName' => __('Password'), 'modelDomain' => 'Users', 'tableDescription' => \@tableHead, 'help' => __('Use this password when connecting a new slave to this server.'), }; return $dataTable; } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Model/OUs.pm0000664000000000000000000001033412017154745021524 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::UsersAndGroups::Model::OUs; # Class: EBox::UsersAndGroups::Model::OUs # # This a class used as a proxy for the OUs present in LDAP. # use EBox::Global; use EBox::Gettext; use EBox::Validate qw(:all); use EBox::Model::Row; use EBox::Exceptions::External; use EBox::Exceptions::Internal; use EBox::Types::Text; use EBox::UsersAndGroups::OU; use strict; use warnings; use base 'EBox::Model::DataTable'; sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub _table { my @tableHead = ( new EBox::Types::Text( 'fieldName' => 'dn', 'printableName' => __('DN'), 'size' => '12', 'editable' => 1, 'allowUnsafeChars' => 1, ), ); my $dataTable = { 'tableName' => 'OUs', 'printableTableName' => __('Organizational Units'), 'defaultActions' => ['changeView', 'add', 'del'], 'modelDomain' => 'Users', 'tableDescription' => \@tableHead, 'printableRowName' => __('organizational unit'), 'sortedBy' => 'dn', }; return $dataTable; } # Method: precondition # # Check if the module is configured # # Overrides: # # sub precondition { my ($self) = @_; my $users = EBox::Global->modInstance('users'); unless ($users->configured()) { $self->{preconFail} = 'notConfigured'; return undef; } return 1; } # Method: preconditionFailMsg # # Check if the module is configured # # Overrides: # # sub preconditionFailMsg { my ($self) = @_; if ($self->{preconFail} eq 'notConfigured') { return __('You must enable the module Users in the module ' . 'status section in order to use it.'); } else { my $users = $self->parentModule(); my $mode = $users->mode(); if ($mode eq 'master') { return __x('There are no users at the moment'); } } } # Method: ids # # Override to return rows identifiers # based on the users stored in LDAP # sub ids { my ($self) = @_; my $users = EBox::Global->modInstance('users'); unless ($users->configured()) { return []; } my @ous = map { $_->dn() } @{$users->ous()}; return \@ous; } # Method: row # # Override to build and return a # row dependening on the user uid which is the id passwd. # sub row { my ($self, $id) = @_; my $row = $self->_setValueRow(dn => $id); $row->setId($id); return $row; } sub removeRow { my ($self, $id, $force) = @_; unless (defined($id)) { throw EBox::Exceptions::MissingArgument( "Missing row identifier to remove") } my $row = $self->row($id); if (not defined $row) { throw EBox::Exceptions::Internal( "Row with id $id does not exist, so it cannot be removed" ); } new EBox::UsersAndGroups::OU(dn => $id)->deleteObject(); $self->setMessage(__x('OU {ou} removed', ou => $id)); } # Method: addTypedRow # # Overrides: # # # sub addTypedRow { my ($self, $params_r, %optParams) = @_; # Check compulsory fields $self->_checkCompulsoryFields($params_r); EBox::UsersAndGroups::OU->create($params_r->{dn}->value()); $self->setMessage(__('OU added')); # this is the last row account added and id == pos return length($self->ids()); } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Model/Slaves.pm0000664000000000000000000000377112017154745022262 0ustar # Copyright (C) 2008-2011 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::UsersAndGroups::Model::Slaves; # Class: EBox::UsersAndGroups::Model::Slaves # # This a class holds the list of registered slave machines # use EBox::Global; use EBox::Gettext; use EBox::Validate qw(:all); use EBox::Model::Row; use EBox::Exceptions::External; use EBox::UsersAndGroups::Group; use EBox::Types::Host; use EBox::Types::Port; use strict; use warnings; use base 'EBox::Model::DataTable'; sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub _table { my @tableHead = ( new EBox::Types::Host( 'fieldName' => 'host', 'printableName' => __('Slave'), 'editable' => 1, ), new EBox::Types::Port( 'fieldName' => 'port', 'printableName' => __('Port'), 'editable' => 1, ), ); my $dataTable = { 'tableName' => 'Slaves', 'printableTableName' => __('Slaves'), 'defaultActions' => ['changeView', 'editField', 'del'], 'defaultController' => '/Users/Controller/Slaves', 'tableDescription' => \@tableHead, 'help' => __('List of slave servers for users and groups synchronization.'), 'printableRowName' => __('slave'), }; return $dataTable; } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Model/AccountSettings.pm0000664000000000000000000000547012017154745024140 0ustar # Copyright (C) 2011-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::Model::AccountSettings # # This model is used to configure the default settings of the user accounts # package EBox::UsersAndGroups::Model::AccountSettings; use base 'EBox::Model::DataForm'; use EBox::Gettext; use EBox::Global; use EBox::Types::Int; use EBox::Types::Select; use EBox::Types::Union; use EBox::Types::Union::Text; use strict; use warnings; use constant DEFAULTQUOTA => 100; sub new { my ($class, %params) = @_; my $self = $class->SUPER::new(%params); bless($self, $class); return $self; } sub _table { my @tableDescription = ( new EBox::Types::Union( 'fieldName' => 'defaultQuota', 'printableName' => __('Default user quota'), 'subtypes' => [ new EBox::Types::Int( 'fieldName' => 'defaultQuota_size', 'printableName' => __('Limited to'), 'defaultValue' => 100, 'trailingText' => __('Mb'), 'size' => 7, 'editable' => 1, ), new EBox::Types::Union::Text( 'fieldName' => 'defaultQuota_disabled', 'printableName' => __('Disabled'), ), ], ), ); my $dataTable = { 'tableName' => 'AccountSettings', 'printableTableName' => __('Default account settings'), 'modelDomain' => 'Users', # FIXME: what default actions should be used? 'defaultActions' => [ 'editField', 'changeView' ], 'tableDescription' => \@tableDescription, 'help' => __('On this page you can configure the default settings ' . 'for user accounts'), }; return $dataTable; } sub formSubmitted { my ($self) = @_; my $row = $self->row(); my $defaultQuota = $row->elementByName('defaultQuota'); if ($defaultQuota->selectedType() eq 'defaultQuota_size') { my $value = $defaultQuota->value(); if ($value == 0) { $self->setMessage( __('Setting default quota to zero is equivalent to disable it') ); } } } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups/Model/PAM.pm0000664000000000000000000000756012017154745021442 0ustar # Copyright (C) 2010-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::UsersAndGroups::Model::PAM # package EBox::UsersAndGroups::Model::PAM; use base 'EBox::Model::DataForm'; use EBox::Gettext; use EBox::Types::Boolean; use EBox::Types::Select; use File::Basename; use strict; use warnings; use constant DEFAULT_SHELL => '/bin/bash'; # Group: Public methods # Constructor: new # # Create a data form # # Overrides: # # # sub new { my ($class, %params) = @_; my $self = $class->SUPER::new(%params); bless( $self, $class ); return $self; } # Method: validateTypedRow # # Check if mail services are disabled. # # Overrides: # # # sub validateTypedRow { my ($self, $action, $changedParams, $allParams) = @_; # Check for incompatibility between PDC and PAM # only on slave servers my $mode = $self->parentModule()->mode(); return unless $mode eq 'slave'; return unless EBox::Global->modExists('samba'); my $samba = EBox::Global->modInstance('samba'); my $pam = exists $allParams->{enable_pam} ? $allParams->{enable_pam}->value() : $changedParams->{enable_pam}->value(); my $pdc = $samba->pdc(); if ($pam and $pdc) { throw EBox::Exceptions::External(__x('PAM can not be enabled on slave servers while acting as PDC. You can disable the PDC functionality at {ohref}File sharing options{chref}.', ohref => q{}, chref => q{})); } } sub validShells { my @shells; push (@shells, { value => DEFAULT_SHELL, printableValue => basename(DEFAULT_SHELL) }); open (my $FH, '<', '/etc/shells') or return \@shells; foreach my $line (<$FH>) { next if $line =~ /^#/; next if $line eq DEFAULT_SHELL; chomp ($line); push (@shells, { value => $line, printableValue => basename($line) }); } close ($FH); return \@shells; } # Method: _table # # Overrides parentModule(); my @tableDesc = (); push (@tableDesc, new EBox::Types::Boolean( fieldName => 'enable_pam', printableName => __('Enable PAM'), defaultValue => 0, editable => 1, help => __('Make LDAP users have system account.') ) ); unless ( $users->mode eq 'slave' ) { push(@tableDesc, new EBox::Types::Select( fieldName => 'login_shell', printableName => __('Default login shell'), disableCache => 1, populate => \&validShells, editable => 1, help => __('This will apply only to new users from now on.') ) ); } my $dataForm = { tableName => 'PAM', printableTableName => __('PAM settings'), defaultActions => [ 'editField', 'changeView' ], tableDescription => \@tableDesc, modelDomain => 'Users', }; return $dataForm; } 1; zentyal-users-2.3.15+quantal1/src/EBox/LdapUserBase.pm0000664000000000000000000001137012017154745017345 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::LdapUserBase; use strict; use warnings; use EBox::Gettext; sub new { my $class = shift; my $self = {}; bless($self, $class); return $self; } # Method: _addUser # # When a new user is created this method is called # # Parameters: # # user - created user sub _addUser { } # Method: _delUser # # When a user is deleted this method is called # # Parameters: # # user - deleted user sub _delUser { } # Method: _modifyUser # # When a user is modified this method is called # # Parameters: # # user - modified user sub _modifyUser { } # Method: _delUserWarning # # When a user is to be deleted, modules should warn the sort of data # (if any) is going to be removed # # Parameters: # # user - user # # Returns: # # array - Each element must be a string describing the sort of data # is going to be removed if the user is deleted. If nothing is going to # removed you must not return anything sub _delUserWarning { } # Method: _addGroup # # When a new user is created this method is called # # Parameters: # # user - created group sub _addGroup { } # Method: _modifyGroup # # When a group is modified this method is called # # Parameters: # # group - modified group sub _modifyGroup { } # Method: _delGroup # # When a group is deleted this method is called # # Parameters: # # group - deleted group sub _delGroup { } # Method: _delGroupWarning # # When a group is to be deleted, modules should warn the sort of data # (if any) is going to be removed # # Parameters: # # group - group # # Returns: # # array - Each element must be a string describing the sort of data # is going to be removed if the group is deleted. If nothing is going to # removed you must not return anything sub _delGroupWarning { } # Method: _userAddOns # # When a user is to be edited, this method is called to get customized # mason components from modules depending on users stored in LDAP. # Thus, these components will be showed below the basic user data # The method has to return a hash ref containing: # 'path' => MASON_COMPONENT_PATH_TO_BE_ADDED # 'params' => PARAMETERS_FOR_MASON_COMPONENT # # The method can also return undef to sigmnal there is not add on for the # module # # Parameters: # # user - user # # Returns: # # A hash ref containing: # # path - mason component which is going to be added # params - parameters for the mason component # # - or - # # undef if there is not component to add sub _userAddOns { } # Method: _groupAddOns # # When a group is to be edited, this method is called to get customized # mason components from modules depending on groups stored in LDAP. # Thus, these components will be showed below the basic group data # The method has to return a hash ref containing: # 'path' => MASON_COMPONENT_PATH_TO_BE_ADDED # 'params' => PARAMETERS_FOR_MASON_COMPONENT # # Parameters: # # group - group to be edited # # Returns: # # A hash ref containing: # # path - mason component which is going to be added # params - parameters for the mason component # sub _groupAddOns { } # Method: schemas # # Returns the paths for the LDIF schemas that need to be loaded # # Returns: # # array ref - Each element must be a string with a path to an LDIF schema # sub schemas { return []; } # Method: acls # # Returns the ACLs that need to be loaded into the LDAP configuration # # Returns: # # array ref - Each element must be a string with an ACL # sub acls { return []; } # Method: indexes # # Returns the attributes that need to be indexed in a translucent LDAP # # Returns: # # array ref - Each element must be a string with an attribute name to inex # sub indexes { return []; } # Method: defaultUserModel # # Returns the name of model that is used to compose a default template for # new user # # Returns: # # string - model name # sub defaultUserModel { return undef; } # Method: multipleOUSupport # # Returns 1 if this module supports users in multiple OU's, # 0 otherwise # sub multipleOUSupport { return 0; } 1; zentyal-users-2.3.15+quantal1/src/EBox/LdapUserImplementation.pm0000664000000000000000000000305112017154745021455 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::LdapUserImplementation; use strict; use warnings; use base qw(EBox::LdapUserBase); use EBox::Global; use EBox::Gettext; sub _create { my $class = shift; my $self = {}; bless($self, $class); return $self; } sub _delGroupWarning { my ($self, $group) = @_; if (@{$group->users()}) { return (__('This group contains users')); } return undef; } sub schemas { return [ EBox::Config::share() . '/zentyal-users/passwords.ldif', EBox::Config::share() . '/zentyal-users/quota.ldif', ]; } sub acls { my $users = EBox::Global->modInstance('users'); return [ "to attrs=userPassword by dn=\"" . $users->ldap()->rootDn() . "\" write by self write " . "by * none" ]; } sub indexes { return [ 'uid', 'uidNumber', 'memberUid', 'cn', 'gidNumber', 'uniqueMember', 'krb5PrincipalName', ]; } 1; zentyal-users-2.3.15+quantal1/src/EBox/Ldap.pm0000664000000000000000000005267212017154745015725 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::Ldap; use strict; use warnings; use EBox::Exceptions::DataExists; use EBox::Exceptions::Internal; use EBox::Exceptions::DataNotFound; use EBox::Exceptions::Internal; use EBox::Gettext; use Net::LDAP; use Net::LDAP::Constant; use Net::LDAP::Message; use Net::LDAP::Search; use Net::LDAP::LDIF; use Net::LDAP qw(LDAP_SUCCESS); use Net::LDAP::Util qw(ldap_error_name); use Data::Dumper; use Encode qw( :all ); use Error qw(:try); use File::Slurp qw(read_file write_file); use Apache2::RequestUtil; use POSIX; use constant LDAPI => "ldapi://%2fvar%2frun%2fslapd%2fldapi"; use constant LDAP => "ldap://127.0.0.1"; use constant CONF_DIR => '/etc/ldap/slapd.d'; use constant DATA_DIR => '/var/lib/ldap'; use constant LDAP_USER => 'openldap'; use constant LDAP_GROUP => 'openldap'; # Singleton variable my $_instance = undef; sub _new_instance { my $class = shift; my $self = {}; $self->{ldap} = undef; bless($self, $class); return $self; } # Method: instance # # Return a singleton instance of class # # Returns: # # object of class sub instance { my ($self, %opts) = @_; unless(defined($_instance)) { $_instance = EBox::Ldap->_new_instance(); } return $_instance; } # Method: ldapCon # # Returns the Net::LDAP connection used by the module # # Returns: # # An object of class Net::LDAP whose connection has already bound # # Exceptions: # # Internal - If connection can't be created sub ldapCon { my ($self) = @_; # Workaround to detect if connection is broken and force reconnection my $reconnect; if ($self->{ldap}) { my $mesg = $self->{ldap}->search( base => '', scope => 'base', filter => "(cn=*)", ); if (ldap_error_name($mesg) ne 'LDAP_SUCCESS' ) { $self->{ldap}->unbind; $reconnect = 1; } } if ((not defined $self->{ldap}) or $reconnect) { $self->{ldap} = $self->anonymousLdapCon(); my ($dn, $pass); my $auth_type = undef; try { my $r = Apache2::RequestUtil->request(); $auth_type = $r->auth_type; } catch Error with {}; if (defined $auth_type and $auth_type eq 'EBox::UserCorner::Auth') { eval "use EBox::UserCorner::Auth"; if ($@) { throw EBox::Exceptions::Internal("Error loading class EBox::UserCorner::Auth: $@") } my $credentials = EBox::UserCorner::Auth->credentials(); my $users = EBox::Global->modInstance('users'); $dn = $users->userDn($credentials->{'user'}); $pass = $credentials->{'pass'}; } else { $dn = $self->rootDn(); $pass = $self->getPassword(); } safeBind($self->{ldap}, $dn, $pass); } return $self->{ldap}; } # Method: anonymousLdapCon # # returns a LDAP connection without any binding # # Returns: # # An object of class Net::LDAP # # Exceptions: # # Internal - If connection can't be created sub anonymousLdapCon { my ($self) = @_; my $ldap = EBox::Ldap::safeConnect(LDAPI); return $ldap; } # Method: getPassword # # Returns the password used to connect to the LDAP directory # # Returns: # # string - password # # Exceptions: # # External - If password can't be read sub getPassword { my ($self) = @_; unless (defined($self->{password})) { my $path = EBox::Config->conf() . "ldap.passwd"; open(PASSWD, $path) or throw EBox::Exceptions::External('Could not get LDAP password'); my $pwd = ; close(PASSWD); $pwd =~ s/[\n\r]//g; $self->{password} = $pwd; } return $self->{password}; } # Method: getRoPassword # # Returns the password of the read only privileged user # used to connect to the LDAP directory with read only # permissions # # Returns: # # string - password # # Exceptions: # # External - If password can't be read # sub getRoPassword { my ($self) = @_; unless (defined($self->{roPassword})) { my $path = EBox::Config::conf() . 'ldap_ro.passwd'; open(PASSWD, $path) or throw EBox::Exceptions::External('Could not get LDAP password'); my $pwd = ; close(PASSWD); $pwd =~ s/[\n\r]//g; $self->{roPassword} = $pwd; } return $self->{roPassword}; } # Method: dn # # Returns the base DN (Distinguished Name) # # Returns: # # string - DN # sub dn { my ($self) = @_; if(!defined($self->{dn})) { my $ldap = $self->anonymousLdapCon(); $ldap->bind(); my %args = ( 'base' => '', 'scope' => 'base', 'filter' => '(objectclass=*)', 'attrs' => ['namingContexts'] ); my $result = $ldap->search(%args); my $entry = ($result->entries)[0]; my $attr = ($entry->attributes)[0]; $self->{dn} = $entry->get_value($attr); } return defined ($self->{dn}) ? $self->{dn} : ''; } # Method: clearConn # # Closes LDAP connection and clears DN cached value # sub clearConn { my ($self) = @_; delete $self->{dn}; delete $self->{ldap}; delete $self->{password}; } # Method: rootDn # # Returns the dn of the priviliged user # # Returns: # # string - eboxdn # sub rootDn { my ($self, $dn) = @_; unless(defined($dn)) { $dn = $self->dn(); } return 'cn=zentyal,' . $dn; } # Method: roRootDn # # Returns the dn of the read only priviliged user # # Returns: # # string - the Dn # sub roRootDn { my ($self, $dn) = @_; unless(defined($dn)) { $dn = $self->dn(); } return 'cn=zentyalro,' . $dn; } # Method: ldapConf # # Returns the current configuration for LDAP: 'dn', 'ldapi', 'rootdn' # # Returns: # # hash ref - holding the keys 'dn', 'ldapi', 'ldap', and 'rootdn' # sub ldapConf { my ($self) = @_; my $conf = { 'dn' => $self->dn(), 'ldapi' => LDAPI, 'ldap' => LDAP, 'port' => 390, 'rootdn' => $self->rootDn(), }; return $conf; } # Method: search # # Performs a search in the LDAP directory using Net::LDAP. # # Parameters: # # args - arguments to pass to Net::LDAP->search() # # Exceptions: # # Internal - If there is an error during the search sub search # (args) { my ($self, $args) = @_; $self->ldapCon; #FIXME: this was added to deal with a problem where an object wouldn't be #returned if attributes were required but objectclass wasn't required too #it's apparently working now, so it's commented, remove it if it works # if (exists $args->{attrs}) { # my %attrs = map { $_ => 1 } @{$args->{attrs}}; # unless (exists $attrs{objectClass}) { # push (@{$args->{attrs}}, 'objectClass'); # } # } my $result = $self->{ldap}->search(%{$args}); _errorOnLdap($result, $args); return $result; } # Method: modify # # Performs a modification in the LDAP directory using Net::LDAP. # # Parameters: # # dn - dn where to perform the modification # args - parameters to pass to Net::LDAP->modify() # # Exceptions: # # Internal - If there is an error during the search sub modify { my ($self, $dn, $args) = @_; $self->ldapCon; my $result = $self->{ldap}->modify($dn, %{$args}); _errorOnLdap($result, $args); return $result; } # Method: delete # # Performs a deletion in the LDAP directory using Net::LDAP. # # Parameters: # # dn - dn to delete # # Exceptions: # # Internal - If there is an error during the search sub delete { my ($self, $dn) = @_; $self->ldapCon; my $result = $self->{ldap}->delete($dn); _errorOnLdap($result, $dn); return $result; } # Method: add # # Adds an object or attributes in the LDAP directory using Net::LDAP. # # Parameters: # # dn - dn to add # args - parameters to pass to Net::LDAP->add() # # Exceptions: # # Internal - If there is an error during the search sub add # (dn, args) { my ($self, $dn, $args) = @_; $self->ldapCon; my $result = $self->{ldap}->add($dn, %{$args}); _errorOnLdap($result, $args); return $result; } # Method: delObjectclass # # Remove an objectclass from an object an all its associated attributes # # Parameters: # # dn - object's dn # objectclass - objectclass # # Exceptions: # # Internal - If there is an error during the search sub delObjectclass # (dn, objectclass); { my ($self, $dn, $objectclass) = @_; my $schema = $self->ldapCon->schema(); my $msg = $self->search( { base => $dn, scope => 'base', filter => "(objectclass=$objectclass)" }); _errorOnLdap($msg); return unless ($msg->entries > 0); my %attrexist = map {$_ => 1} $msg->pop_entry->attributes; $msg = $self->search( { base => $dn, scope => 'base', attrs => ['objectClass'], filter => '(objectclass=*)' }); _errorOnLdap($msg); my %attrs; for my $oc (grep(!/^$objectclass$/, $msg->entry->get_value('objectclass'))){ # get objectclass attributes my @ocattrs = map { $_->{name} } ($schema->must($oc), $schema->may($oc)); # mark objectclass attributes as seen foreach (@ocattrs) { $attrs{$_ } = 1; } } # get the attributes of the object class which will be deleted my @objectAttrs = map { $_->{name} } ($schema->must($objectclass), $schema->may($objectclass)); my %attr2del; for my $attr (@objectAttrs) { # Skip if the attribute belongs to another objectclass next if (exists $attrs{$attr}); # Skip if the attribute is not stored in the object next unless (exists $attrexist{$attr}); $attr2del{$attr} = []; } my $result; if (%attr2del) { $result = $self->modify($dn, { changes => [delete =>[ objectclass => $objectclass, %attr2del ] ] }); _errorOnLdap($msg); } else { $result = $self->modify($dn, { changes => [delete =>[ objectclass => $objectclass ] ] }); _errorOnLdap($msg); } return $result; } # Method: modifyAttribute # # Modify an attribute from a given dn # # Parameters: # # dn - object's dn # attribute - attribute to change # value - new value # # Exceptions: # # Internal - If there is an error during the modification # sub modifyAttribute # (dn, attribute, value); { my ($self, $dn, $attribute, $value) = @_; my %attrs = ( changes => [ replace => [ $attribute => $value ] ]); $self->modify($dn, \%attrs ); } # Method: setAttribute # # Modify the value of an attribute from a given dn if it exists # Add the attribute with the given value if it doesn't exist # # Parameters: # # dn - object's dn # attribute - attribute to add/change # value - new value # # Exceptions: # # Internal - If there is an error during the modification # sub setAttribute # (dn, attribute, value); { my ($self, $dn, $attribute, $value) = @_; my %args = (base => $dn, filter => "$attribute=*"); my $result = $self->search(\%args); my $action = $result->count > 0 ? 'replace' : 'add'; my %attrs = ( changes => [ $action => [ $attribute => $value ] ]); $self->modify($dn, \%attrs); } # Method: delAttribute # # Delete an attribute from a given dn if it exists # # Parameters: # # dn - object's dn # attribute - attribute to delete # # Exceptions: # # Internal - If there is an error during the modification # sub delAttribute # (dn, attribute); { my ($self, $dn, $attribute, $value) = @_; my %args = (base => $dn, filter => "$attribute=*"); my $result = $self->search(\%args); if ($result->count > 0) { my %attrs = ( changes => [ delete => [ $attribute => [] ] ]); $self->modify($dn, \%attrs); } } # Method: getAttribute # # Get the value for the given attribute. # If there are more than one, the first is returned. # # Parameters: # # dn - object's dn # attribute - attribute to get its value # # Returns: # string - attribute value if present # undef - if attribute not present # # Exceptions: # # Internal - If there is an error during the modification # sub getAttribute # (dn, attribute); { my ($self, $dn, $attribute) = @_; my %args = (base => $dn, filter => "$attribute=*"); my $result = $self->search(\%args); return undef unless ($result->count > 0); return $result->entry(0)->get_value($attribute); } # Method: isObjectClass # # check if a object is member of a given objectclass # # Parameters: # dn - the object's dn # objectclass - the name of the objectclass # # Returns: # boolean - wether the object is member of the objectclass or not sub isObjectClass { my ($self, $dn, $objectClass) = @_; my %attrs = ( base => $dn, filter => "(objectclass=$objectClass)", attrs => [ 'objectClass'], scope => 'base' ); my $result = $self->search(\%attrs); if ($result->count == 1) { return 1; } return undef; } # Method: objectClasses # # return the object classes of an object # # Parameters: # dn - the object's dn # # Returns: # array - containing the object classes sub objectClasses { my ($self, $dn) = @_; my %attrs = ( base => $dn, filter => "(objectclass=*)", attrs => [ 'objectClass'], scope => 'base' ); my $result = $self->search(\%attrs); return [ $result->pop_entry()->get_value('objectClass') ]; } # Method: lastModificationTime # # Get the last modification time for the directory # # Parameters: # # fromTimestamp - String from timestamp to start the query from to # speed up the query. If the value is greater than # the LDAP last modification time, then it returns zero # *Optional* Default value: undef # # Returns: # # Int - the timestamp in seconds since epoch # # Example: # # $ldap->lastModificationTime('20091204132422Z') => 1259955547 # sub lastModificationTime { my ($self, $fromTimestamp) = @_; my $filter = '(objectclass=*)'; if (defined($fromTimestamp)) { $filter = "(&(objectclass=*)(modifyTimestamp>=$fromTimestamp))"; } my $res = $self->search({base => $self->dn(), attrs => [ 'modifyTimestamp' ], filter => $filter }); # Order alphanumerically and the latest is the one whose timestamp # is the last one my @sortedEntries = $res->sorted('modifyTimestamp'); if ( scalar(@sortedEntries) == 0) { # fromTimestamp given is greater than the current time, so we return 0 return 0; } my $lastStamp = $sortedEntries[-1]->get_value('modifyTimestamp'); # Convert to seconds since epoch my ($year, $month, $day, $h, $m, $s) = $lastStamp =~ /([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})Z/; return POSIX::mktime( $s, $m, $h, $day, $month -1, $year - 1900 ); } sub _errorOnLdap { my ($result, $args) = @_; my @frames = caller (2); if ($result->is_error){ if ($args) { use Data::Dumper; EBox::error( Dumper($args) ); } throw EBox::Exceptions::Internal("Unknown error at " . $frames[3] . " " . $result->error); } } # Workaround to mark strings returned from ldap as utf8 strings sub _utf8Attrs # (result) { my ($result) = @_; my @entries = $result->entries; foreach my $attr (@{$entries[0]->{'asn'}->{'attributes'}}) { my @vals = @{$attr->{vals}}; next unless (@vals); my @utfvals; foreach my $val (@vals) { _utf8_on($val); push @utfvals, $val; } $attr->{vals} = \@utfvals; } return $result; } sub stop { my ($self) = @_; my $users = EBox::Global->modInstance('users'); $users->_manageService('stop'); return $self->refreshLdap(); } sub start { my ($self) = @_; my $users = EBox::Global->modInstance('users'); $users->_manageService('start'); return $self->refreshLdap(); } sub refreshLdap { my ($self) = @_; $self->{ldap} = undef; return $self; } sub ldifFile { my ($self, $dir, $base) = @_; return "$dir/$base.ldif"; } # Method: dumpLdap # # dump the LDAP contents to a LDIF file in the given directory. The exact file # path can be retrevied using the method ldifFile # # Parameters: # dir - directory in which put the LDIF file sub _dumpLdap { my ($self, $dir, $type) = @_; my $user = EBox::Config::user(); my $group = EBox::Config::group(); my $ldifFile = $self->ldifFile($dir, $type); my $slapcatCommand = $self->_slapcatCmd($ldifFile, $type); my $chownCommand = "/bin/chown $user:$group $ldifFile"; $self->_execute(1, # With pause cmds => [$slapcatCommand, $chownCommand]); } sub dumpLdapData { my ($self, $dir) = @_; $self->_dumpLdap($dir, 'data'); } sub dumpLdapConfig { my ($self, $dir) = @_; $self->_dumpLdap($dir, 'config'); } sub usersInBackup { my ($self, $dir) = @_; my @users; my $ldifFile = $self->ldifFile($dir, 'data'); my $ldif = Net::LDAP::LDIF->new($ldifFile, 'r', onerror => 'undef'); my $usersDn; while (not $ldif->eof()) { my $entry = $ldif->read_entry ( ); if ($ldif->error()) { EBox::error("Error reading LDIOF file $ldifFile: " . $ldif->error() . '. Error lines: ' . $ldif->error_lines()); } else { my $dn = $entry->dn(); if (not defined $usersDn) { # first entry, use it to fetch the DN $usersDn = 'ou=Users,' . $dn; next; } # in zentyal users are identified by DN, not by objectclass if ($dn =~ /$usersDn$/) { push @users, $entry->get_value('uid'); } } } $ldif->done(); return \@users; } sub _slapcatCmd { my ($self, $ldifFile, $type) = @_; my $base; if ($type eq 'config') { $base = 'cn=config'; } else { $base = $self->dn(); } return "/usr/sbin/slapcat -F " . CONF_DIR . " -b '$base' > $ldifFile"; } sub _execute { my ($self, $pause, %params) = @_; my @cmds = @{ $params{cmds} }; my $onError = $params{onError}; if ($pause) { $self->stop(); } try { EBox::Sudo::root(@cmds); } otherwise { my $ex = shift; if ($onError) { $onError->($self); } throw $ex; } finally { if ($pause) { $self->start(); } }; } sub safeConnect { my ($ldapurl) = @_; my $retries = 4; my $ldap; local $SIG{PIPE}; $SIG{PIPE} = sub { EBox::warn('SIGPIPE received connecting to LDAP'); }; while (not $ldap = Net::LDAP->new($ldapurl) and $retries--) { my $users = EBox::Global->modInstance('users'); $users->_manageService('start'); EBox::error("Couldn't connect to LDAP server $ldapurl, retrying"); sleep(1); } unless ($ldap) { throw EBox::Exceptions::External( "FATAL: Couldn't connect to LDAP server: $ldapurl"); } if ($retries < 3) { EBox::info('LDAP reconnect successful'); } return $ldap; } sub safeBind { my ($ldap, $dn, $password) = @_; my $bind = $ldap->bind($dn, password => $password); unless ($bind->{resultCode} == 0) { throw EBox::Exceptions::External( 'Couldn\'t bind to LDAP server, result code: ' . $bind->{resultCode}); } return $bind; } sub changeUserPassword { my ($self, $dn, $newPasswd, $oldPasswd) = @_; $self->ldapCon(); my $rootdse = $self->{ldap}->root_dse(); if ($rootdse->supported_extension('1.3.6.1.4.1.4203.1.11.1')) { # Update the password using the LDAP extension will update the kerberos keys also # if the smbk5pwd module and its overlay are loaded require Net::LDAP::Extension::SetPassword; my $mesg = $self->{ldap}->set_password(user => $dn, oldpasswd => $oldPasswd, newpasswd => $newPasswd); _errorOnLdap($mesg); } else { my $mesg = $self->{ldap}->modify( $dn, changes => [ delete => [ userPassword => $oldPasswd ], add => [ userPassword => $newPasswd ] ]); _errorOnLdap($mesg); } } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersAndGroups.pm0000664000000000000000000011566712017154745017775 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::UsersAndGroups; use strict; use warnings; use base qw(EBox::Module::Service EBox::LdapModule EBox::UserCorner::Provider EBox::UsersAndGroups::SyncProvider); use EBox::Global; use EBox::Util::Random; use EBox::Ldap; use EBox::Gettext; use EBox::Menu::Folder; use EBox::Menu::Item; use EBox::Sudo; use EBox::FileSystem; use EBox::LdapUserImplementation; use EBox::Config; use EBox::UsersAndGroups::Slave; use EBox::UsersAndGroups::User; use EBox::UsersAndGroups::Group; use EBox::UsersAndGroups::OU; use EBox::UsersSync::Master; use EBox::UsersSync::Slave; use EBox::CloudSync::Slave; use Digest::SHA; use Digest::MD5; use Sys::Hostname; use Error qw(:try); use File::Copy; use File::Slurp; use File::Temp qw/tempfile/; use Perl6::Junction qw(any); use String::ShellQuote; use Fcntl qw(:flock); use constant USERSDN => 'ou=Users'; use constant GROUPSDN => 'ou=Groups'; use constant COMPUTERSDN => 'ou=Computers'; use constant LIBNSS_LDAPFILE => '/etc/ldap.conf'; use constant LIBNSS_SECRETFILE => '/etc/ldap.secret'; use constant DEFAULTGROUP => '__USERS__'; use constant JOURNAL_DIR => EBox::Config::home() . 'syncjournal/'; use constant AUTHCONFIGTMPL => '/etc/auth-client-config/profile.d/acc-zentyal'; use constant MAX_SB_USERS => 25; use constant CRONFILE => '/etc/cron.d/zentyal-users'; use constant LDAP_CONFDIR => '/etc/ldap/slapd.d/'; use constant LDAP_DATADIR => '/var/lib/ldap/'; use constant LDAP_USER => 'openldap'; use constant LDAP_GROUP => 'openldap'; # Kerberos constants use constant KERBEROS_PORT => 8880; use constant KPASSWD_PORT => 8464; use constant KRB5_CONF_FILE => '/etc/krb5.conf'; use constant KDC_CONF_FILE => '/etc/heimdal-kdc/kdc.conf'; use constant KDC_DEFAULT_FILE => '/etc/default/heimdal-kdc'; sub _create { my $class = shift; my $self = $class->SUPER::_create(name => 'users', printableName => __n('Users and Groups'), @_); bless($self, $class); return $self; } # Method: actions # # Override EBox::ServiceModule::ServiceInterface::actions # sub actions { my ($self) = @_; my @actions; push(@actions, { 'action' => __('Your LDAP database will be populated with some basic organizational units'), 'reason' => __('Zentyal needs this organizational units to add users and groups into them.'), 'module' => 'users' }, ); # FIXME: This probably won't work if PAM is enabled after enabling the module if ($self->model('PAM')->enable_pamValue()) { push(@actions, { 'action' => __('Configure PAM.'), 'reason' => __('Zentyal will give LDAP users system account.'), 'module' => 'users' } ); } return \@actions; } # Method: usedFiles # # Override EBox::Module::Service::files # sub usedFiles { my ($self) = @_; my @files = (); push(@files, { 'file' => '/etc/nsswitch.conf', 'reason' => __('To make NSS use LDAP resolution for user and '. 'group accounts. Needed for Samba PDC configuration.'), 'module' => 'users' }, { 'file' => LIBNSS_LDAPFILE, 'reason' => __('To let NSS know how to access LDAP accounts.'), 'module' => 'users' }, { 'file' => '/etc/fstab', 'reason' => __('To add quota support to /home partition.'), 'module' => 'users' }, { 'file' => '/etc/default/slapd', 'reason' => __('To make LDAP listen on TCP and Unix sockets.'), 'module' => 'users' }, { 'file' => LIBNSS_SECRETFILE, 'reason' => __('To copy LDAP admin password generated by ' . 'Zentyal and allow other modules to access LDAP.'), 'module' => 'users' }, { 'file' => KRB5_CONF_FILE, 'reason' => __('To set up kerberos authentication'), 'module' => 'users' }, { 'file' => KDC_CONF_FILE, 'reason' => __('To set up the kerberos KDC'), 'module' => 'users' }, { 'file' => KDC_DEFAULT_FILE, 'reason' => __('To set the KDC configuration'), 'module' => 'users', }, ); return \@files; } # Method: initialSetup # # Overrides: # # EBox::Module::Base::initialSetup # sub initialSetup { my ($self, $version) = @_; # Create default rules and services # only if installing the first time unless ($version) { my $services = EBox::Global->modInstance('services'); my $fw = EBox::Global->modInstance('firewall'); my $serviceName = 'ldap'; unless ($services->serviceExists(name => $serviceName)) { $services->addMultipleService( 'name' => $serviceName, 'printableName' => 'LDAP', 'description' => __('Lightweight Directory Access Protocol'), 'readOnly' => 1, 'services' => [ { protocol => 'tcp', sourcePort => 'any', destinationPort => 390 } ], ); $fw->setInternalService($serviceName, 'accept'); } $serviceName = 'kerberos'; unless ($services->serviceExists(name => $serviceName)) { $services->addMultipleService( 'name' => $serviceName, 'printableName' => 'Kerberos', 'description' => __('Kerberos authentication'), 'readOnly' => 1, 'services' => [ { protocol => 'tcp/udp', sourcePort => 'any', destinationPort => KERBEROS_PORT }, { protocol => 'tcp/udp', sourcePort => 'any', destinationPort => KPASSWD_PORT } ] ); $fw->setInternalService($serviceName, 'accept'); } $fw->saveConfigRecursive(); } # Execute initial-setup script $self->SUPER::initialSetup($version); } sub setupKerberos { my ($self) = @_; my $realm = $self->kerberosRealm(); EBox::info("Initializing kerberos realm '$realm'"); my @cmds = (); push (@cmds, 'sudo sed -e "s/^kerberos-adm/#kerberos-adm/" /etc/inetd.conf -i') if EBox::Sudo::fileTest('-f', '/etc/inetd.conf'); push (@cmds, "ln -sf /etc/heimdal-kdc/kadmind.acl /var/lib/heimdal-kdc/kadmind.acl"); push (@cmds, "ln -sf /etc/heimdal-kdc/kdc.conf /var/lib/heimdal-kdc/kdc.conf"); push (@cmds, "rm -f /var/lib/heimdal-kdc/m-key"); push (@cmds, "kadmin -l init --realm-max-ticket-life=unlimited --realm-max-renewable-life=unlimited $realm"); push (@cmds, 'rm -f /etc/kpasswdd.keytab'); push (@cmds, "kadmin -l ext -k /etc/kpasswdd.keytab kadmin/changepw\@$realm"); #TODO Only if master push (@cmds, 'chmod 600 /etc/kpasswdd.keytab'); # TODO Only if master EBox::Sudo::root(@cmds); $self->setupDNS(); } sub setupDNS { my ($self) = @_; EBox::info("Setting up DNS"); # Get the host domain my $sysinfo = EBox::Global->modInstance('sysinfo'); my $hostName = $sysinfo->hostName(); my $hostDomain = $sysinfo->hostDomain(); # Create the domain in the DNS module if it does not exists my $dnsMod = EBox::Global->modInstance('dns'); my $domain = { domain_name => $hostDomain, hostnames => [] }; my $domains = $dnsMod->domains(); my %domains = map {$_->{name} => $_} @{$domains}; if (not exists $domains{$hostDomain}) { $dnsMod->addDomain($domain); } EBox::debug("Adding DNS records for kerberos"); # Add the TXT record with the realm name my $txtRR = { name => '_kerberos', data => $hostDomain }; $dnsMod->addText($hostDomain, $txtRR); # Add the SRV records to the domain my $service = { service => 'kerberos', protocol => 'tcp', port => KERBEROS_PORT, priority => 100, weight => 100, target_type => 'domainHost', target => $hostName }; $dnsMod->addService($hostDomain, $service); $service->{protocol} = 'udp'; $dnsMod->addService($hostDomain, $service); ## TODO Check if the server is a master or slave and adjust the target ## to the master server $service = { service => 'kerberos-master', protocol => 'tcp', port => KERBEROS_PORT, priority => 100, weight => 100, target_type => 'domainHost', target => $hostName }; $dnsMod->addService($hostDomain, $service); $service->{protocol} = 'udp'; $dnsMod->addService($hostDomain, $service); $service = { service => 'kpasswd', protocol => 'tcp', port => KPASSWD_PORT, priority => 100, weight => 100, target_type => 'domainHost', target => $hostName }; $dnsMod->addService($hostDomain, $service); $service->{protocol} = 'udp'; $dnsMod->addService($hostDomain, $service); } # Method: enableActions # # Override EBox::Module::Service::enableActions # sub enableActions { my ($self) = @_; # Stop slapd daemon EBox::Sudo::root( 'invoke-rc.d slapd stop || true', 'stop ebox.slapd || true', 'cp /usr/share/zentyal-users/slapd.default.no /etc/default/slapd' ); my $dn = $self->model('Mode')->dnValue(); my $password = $self->_genPassword(EBox::Config::conf() . 'ldap.passwd'); my $password_ro = $self->_genPassword(EBox::Config::conf() . 'ldap_ro.passwd'); my $opts = [ 'dn' => $dn, 'password' => $password, 'password_ro' => $password_ro, ]; # Prepare ldif files my $LDIF_CONFIG = EBox::Config::tmp() . "slapd-config.ldif"; my $LDIF_DB = EBox::Config::tmp() . "slapd-database.ldif"; EBox::Module::Base::writeConfFileNoCheck($LDIF_CONFIG, "users/config.ldif.mas", $opts); EBox::Module::Base::writeConfFileNoCheck($LDIF_DB, "users/database.ldif.mas", $opts); # Preload base LDAP data $self->_loadLDAP($dn, $LDIF_CONFIG, $LDIF_DB); $self->_manageService('start'); $self->ldap->clearConn(); # Setup NSS (needed if some user is added before save changes) $self->_setConf(1); # Create default group EBox::UsersAndGroups::Group->create(DEFAULTGROUP, 'All users', 1); # Perform LDAP actions (schemas, indexes, etc) EBox::info('Performing first LDAP actions'); try { $self->performLDAPActions(); } otherwise { my $error = shift; EBox::error("Error performing users initialization: $error"); throw EBox::Exceptions::External(__('Error performing users initialization')); }; # Setup kerberos realm and DNS $self->setupKerberos(); # Execute enable-module script $self->SUPER::enableActions(); # Configure SOAP to listen for new slaves $self->masterConf->confSOAPService(); $self->masterConf->setupMaster(); # mark apache as changed to avoid problems with getpwent calls, it needs # to be restarted to be aware of the new nsswitch conf EBox::Global->modInstance('apache')->setAsChanged(); } # Load LDAP from config + data files sub _loadLDAP { my ($self, $dn, $LDIF_CONFIG, $LDIF_DB) = @_; EBox::info('Creating LDAP database...'); try { EBox::Sudo::root( # Remove current database (if any) 'rm -f /var/lib/heimdal-kdc/m-key', 'rm -rf ' . LDAP_CONFDIR . ' ' . LDAP_DATADIR, 'mkdir -p ' . LDAP_CONFDIR . ' ' . LDAP_DATADIR, 'chmod 750 ' . LDAP_CONFDIR . ' ' . LDAP_DATADIR, # Create database (config + structure) 'slapadd -F ' . LDAP_CONFDIR . " -b cn=config -l $LDIF_CONFIG", 'slapadd -F ' . LDAP_CONFDIR . " -b $dn -l $LDIF_DB", # Fix permissions and clean temp files 'chown -R openldap.openldap ' . LDAP_CONFDIR . ' ' . LDAP_DATADIR, "rm -f $LDIF_CONFIG $LDIF_DB", ); } catch EBox::Exceptions::Sudo::Command with { my $exception = shift; EBox::error('Trying to setup ldap failed, exit value: ' . $exception->exitValue()); throw EBox::Exceptions::External(__('Error while creating users and groups database.')); } otherwise { my $error = shift; EBox::error("Trying to setup ldap failed: $error"); }; EBox::debug('done'); } # Generate, store in the given file and return a password sub _genPassword { my ($self, $file) = @_; my $pass = EBox::Util::Random::generate(20); my ($login,$password,$uid,$gid) = getpwnam('ebox'); EBox::Module::Base::writeFile($file, $pass, { mode => '0600', uid => $uid, gid => $gid }); return $pass; } # Method: wizardPages # # Override EBox::Module::Base::wizardPages # sub wizardPages { my ($self) = @_; return [{ page => '/UsersAndGroups/Wizard/Users', order => 300 }]; } # Method: _setConf # # Override EBox::Module::Service::_setConf # sub _setConf { my ($self, $noSlaveSetup) = @_; my $ldap = $self->ldap; EBox::Module::Base::writeFile(LIBNSS_SECRETFILE, $ldap->getPassword(), { mode => '0600', uid => 0, gid => 0 }); my $dn = $ldap->dn; my $nsspw = $ldap->getRoPassword(); my @array = (); push (@array, 'ldap' => EBox::Ldap::LDAPI); push (@array, 'basedc' => $dn); push (@array, 'binddn' => $ldap->roRootDn()); push (@array, 'rootbinddn'=> $ldap->rootDn()); push (@array, 'bindpw' => $nsspw); push (@array, 'usersdn' => USERSDN . ',' . $dn); push (@array, 'groupsdn' => GROUPSDN . ',' . $dn); push (@array, 'computersdn' => COMPUTERSDN . ',' . $dn); $self->writeConfFile(LIBNSS_LDAPFILE, "users/ldap.conf.mas", \@array); $self->_setupNSSPAM(); # Slaves cron @array = (); push(@array, 'slave_time' => EBox::Config::configkey('slave_time')); if ($self->master() eq 'cloud') { push(@array, 'cloudsync_enabled' => 1); $self->writeConfFile(CRONFILE, "users/zentyal-users.cron.mas", \@array); } # Configure as slave if enabled $self->masterConf->setupSlave() unless ($noSlaveSetup); # Configure soap service $self->masterConf->confSOAPService(); # Get the FQDN my $realm = $self->kerberosRealm(); @array = (); push (@array, 'realm' => $realm); $self->writeConfFile(KRB5_CONF_FILE, 'users/krb5.conf.mas', \@array); my $ldapBase = $self->ldap->dn(); @array = (); push (@array, 'ldapBase' => $ldapBase); push (@array, 'realm' => $realm); $self->writeConfFile(KDC_CONF_FILE, 'users/kdc.conf.mas', \@array); @array = (); $self->writeConfFile(KDC_DEFAULT_FILE, 'users/heimdal-kdc.mas', \@array); } sub kerberosRealm { my ($self) = @_; my $sysinfo = EBox::Global->modInstance('sysinfo'); my $realm = uc ($sysinfo->hostDomain()); return $realm; } sub _setupNSSPAM { my ($self) = @_; my @array = (); my $umask = EBox::Config::configkey('dir_umask'); push (@array, 'umask' => $umask); $self->writeConfFile(AUTHCONFIGTMPL, 'users/acc-zentyal.mas', \@array); my $enablePam = $self->model('PAM')->enable_pamValue(); my $cmd; if ($enablePam) { $cmd = 'auth-client-config -a -p zentyal-krb'; } else { $cmd = 'auth-client-config -a -p zentyal-nokrb'; } EBox::Sudo::root($cmd); } # Method: editableMode # # Check if users and groups can be edited. # # Returns true if mode is master # sub editableMode { my ($self) = @_; my $global = EBox::Global->modInstance('global'); my @names = @{$global->modNames}; my @modules; foreach my $name (@names) { my $mod = EBox::Global->modInstance($name); if ($mod->isa('EBox::UsersAndGroups::SyncProvider')) { return 0 unless ($mod->allowUserChanges()); } } return 1; } # Method: _daemons # # Override EBox::Module::Service::_daemons # sub _daemons { my ($self) = @_; return [ { name => 'ebox.slapd' }, { name => 'heimdal-kdc', type => 'init.d', pidfiles => ['/var/run/heimdal-kdc.pid', '/var/run/kpasswdd.pid'], }, ]; } # Method: _enforceServiceState # # Override EBox::Module::Service::_enforceServiceState # sub _enforceServiceState { my ($self) = @_; $self->SUPER::_enforceServiceState(); # Clear LDAP connection $self->ldap->clearConn(); } # Method: groupsDn # # Returns the dn where the groups are stored in the ldap directory # Accepts an optional parameter as base dn instead of getting it # from the local LDAP repository # # Returns: # # string - dn # sub groupsDn { my ($self, $dn) = @_; unless(defined($dn)) { $dn = $self->ldap->dn(); } return GROUPSDN . "," . $dn; } # Method: groupDn # # Returns the dn for a given group. The group don't have to existst # # Parameters: # group # # Returns: # dn for the group sub groupDn { my ($self, $group) = @_; $group or throw EBox::Exceptions::MissingArgument('group'); my $dn = "cn=$group," . $self->groupsDn; return $dn; } # Method: usersDn # # Returns the dn where the users are stored in the ldap directory. # Accepts an optional parameter as base dn instead of getting it # from the local LDAP repository # # Returns: # # string - dn # sub usersDn { my ($self, $dn) = @_; unless(defined($dn)) { $dn = $self->ldap->dn(); } return USERSDN . "," . $dn; } # Method: userDn # # Returns the dn for a given user. The user don't have to existst # # Parameters: # user # # Returns: # dn for the user sub userDn { my ($self, $user) = @_; $user or throw EBox::Exceptions::MissingArgument('user'); my $dn = "uid=$user," . $self->usersDn; return $dn; } # Init a new user (home and permissions) sub initUser { my ($self, $user, $password) = @_; my $mk_home = EBox::Config::configkey('mk_home'); $mk_home = 'yes' unless $mk_home; if ($mk_home eq 'yes') { my $home = $user->home(); if ($home and ($home ne '/dev/null') and (not -e $home)) { my @cmds; my $quser = shell_quote($user->name()); my $qhome = shell_quote($home); my $group = DEFAULTGROUP; push(@cmds, "mkdir -p `dirname $qhome`"); push(@cmds, "cp -dR --preserve=mode /etc/skel $qhome"); push(@cmds, "chown -R $quser:$group $qhome"); my $dir_umask = oct(EBox::Config::configkey('dir_umask')); my $perms = sprintf("%#o", 00777 &~ $dir_umask); push(@cmds, "chmod $perms $qhome"); EBox::Sudo::root(@cmds); } } } # Reload nscd daemon if it's installed sub reloadNSCD { if ( -f '/etc/init.d/nscd' ) { try { EBox::Sudo::root('/etc/init.d/nscd reload'); } otherwise {}; } } # Method: user # # Returns the object which represents a give user. Raises a excpetion if # the user does not exists # # Parameters: # username # # Returns: # the appropaite EBox::UsersAndGroups::User . sub user { my ($self, $username) = @_; my $dn = $self->userDn($username); my $user = new EBox::UsersAndGroups::User(dn => $dn); if (not $user->exists()) { throw EBox::Exceptions::DataNotFound(data => __('user'), value => $username); } return $user; } # Method: users # # Returns an array containing all the users (not system users) # # Parameters: # system - show system users also (default: false) # # Returns: # # array ref - holding the users. Each user is represented by a # EBox::UsersAndGroups::User object # sub users { my ($self, $system) = @_; return [] if (not $self->isEnabled()); my %args = ( base => $self->ldap->dn(), filter => 'objectclass=posixAccount', scope => 'sub', ); my $result = $self->ldap->search(\%args); my @users = (); foreach my $entry ($result->sorted('uid')) { my $user = new EBox::UsersAndGroups::User(entry => $entry); # Include system users? next if (not $system and $user->system()); push (@users, $user); } return \@users; } # Method: group # # Returns the object which represents a give group. Raises a excpetion if # the group does not exists # # Parameters: # groupname # # Returns: # the appropaite EBox::UsersAndGroups::Group . sub group { my ($self, $groupname) = @_; my $dn = $self->groupDn($groupname); my $group = new EBox::UsersAndGroups::Group(dn => $dn); if (not $group->exists()) { throw EBox::Exceptions::DataNotFound(data => __('group'), value => $groupname); } return $group; } # Method: groups # # Returns an array containing all the groups # # Parameters: # system - show system groups (default: false) # # Returns: # # array - holding the groups as EBox::UsersAndGroups::Group objects # sub groups { my ($self, $system) = @_; return [] if (not $self->isEnabled()); my %args = ( base => $self->ldap->dn(), filter => 'objectclass=zentyalGroup', scope => 'sub', ); my $result = $self->ldap->search(\%args); my @groups = (); foreach my $entry ($result->sorted('cn')) { my $group = new EBox::UsersAndGroups::Group(entry => $entry); # Include system users? next if (not $system and $group->system()); push (@groups, $group); } return \@groups; } sub multipleOusEnabled { return EBox::Config::configkey('multiple_ous'); } # Method: ous # # Returns an array containing all the OUs # # Returns: # # array ref - holding the OUs # sub ous { my ($self) = @_; return [] if (not $self->isEnabled()); my %args = ( base => $self->ldap->dn(), filter => 'objectclass=organizationalUnit', scope => 'sub', ); my $result = $self->ldap->search(\%args); my @ous = (); foreach my $entry ($result->entries()) { my $ou = new EBox::UsersAndGroups::OU(entry => $entry); push (@ous, $ou); } return \@ous; } # Method: _modsLdapUserbase # # Returns modules implementing LDAP user base interface # # Parameters: # ignored_modules (Optional) - array ref to a list of module names to ignore # sub _modsLdapUserBase { my ($self, $ignored_modules) = @_; my $global = EBox::Global->modInstance('global'); my @names = @{$global->modNames}; $ignored_modules or $ignored_modules = []; my @modules; foreach my $name (@names) { next if ($name eq any @{$ignored_modules}); my $mod = EBox::Global->modInstance($name); if ($mod->isa('EBox::LdapModule')) { if ($mod->isa('EBox::Module::Service')) { if ($name ne $self->name()) { $mod->configured() or next; } } push (@modules, $mod->_ldapModImplementation); } } return \@modules; } # Method: allSlaves # # Returns all slaves from LDAP Sync Provider # sub allSlaves { my ($self) = @_; my $global = EBox::Global->modInstance('global'); my @names = @{$global->modNames}; my @modules; foreach my $name (@names) { my $mod = EBox::Global->modInstance($name); if ($mod->isa('EBox::UsersAndGroups::SyncProvider')) { push (@modules, @{$mod->slaves()}); } } return \@modules; } # Method: notifyModsLdapUserBase # # Notify all modules implementing LDAP user base interface about # a change in users or groups # # Parameters: # # signal - Signal name to notify the modules (addUser, delUser, modifyGroup, ...) # args - single value or array ref containing signal parameters # ignored_modules - array ref of modnames to ignore (won't be notified) # sub notifyModsLdapUserBase { my ($self, $signal, $args, $ignored_modules, $ignored_slaves) = @_; # convert signal to method name my $method = '_' . $signal; # convert args to array if it is a single value unless (ref($args) eq 'ARRAY') { $args = [ $args ]; } my $basedn = $args->[0]->baseDn(); my $defaultOU = ($basedn eq $self->usersDn() or $basedn eq $self->groupsDn()); foreach my $mod (@{$self->_modsLdapUserBase($ignored_modules)}) { # Skip modules not supporting multiple OU if not default OU next unless ($mod->multipleOUSupport or $defaultOU); # TODO catch errors here? $mod->$method(@{$args}); } # Save user corner operations for slave-sync daemon if ($self->isUserCorner) { my $dir = '/var/lib/zentyal-usercorner/syncjournal/'; mkdir ($dir) unless (-d $dir); my $time = time(); my ($fh, $filename) = tempfile("$time-$signal-XXXX", DIR => $dir); EBox::UsersAndGroups::Slave->writeActionInfo($fh, $signal, $args); $fh->close(); return; } # Notify slaves $ignored_slaves or $ignored_slaves = []; foreach my $slave (@{$self->allSlaves}) { my $name = $slave->name(); next if ($name eq any @{$ignored_slaves}); $slave->sync($signal, $args); } } # Method: initialSlaveSync # # This method will send a sync signal for each # stored user and group. # It should be called on a slave registering # sub initialSlaveSync { my ($self, $slave) = @_; foreach my $user (@{$self->users()}) { $slave->savePendingSync('addUser', [ $user ]); } foreach my $group (@{$self->groups()}) { $slave->savePendingSync('addGroup', [ $group ]); $slave->savePendingSync('modifyGroup', [ $group ]); } } sub isUserCorner { my ($self) = @_; my $auth_type = undef; try { my $r = Apache2::RequestUtil->request(); $auth_type = $r->auth_type; } catch Error with {}; return (defined $auth_type and $auth_type eq 'EBox::UserCorner::Auth'); } # Method: defaultUserModels # # Returns all the defaultUserModels from modules implementing # sub defaultUserModels { my ($self) = @_; my @models; for my $module (@{$self->_modsLdapUserBase()}) { my $model = $module->defaultUserModel(); push (@models, $model) if (defined($model)); } return \@models; } # Method: allUserAddOns # # Returns all the mason components from those modules implementing # the function _userAddOns from EBox::LdapUserBase # # Parameters: # # user - username # # Returns: # # array ref - holding all the components and parameters # sub allUserAddOns { my ($self, $user) = @_; my $global = EBox::Global->modInstance('global'); my @names = @{$global->modNames}; my $defaultOU = ($user->baseDn() eq $self->usersDn()); my @modsFunc = @{$self->_modsLdapUserBase()}; my @components; foreach my $mod (@modsFunc) { # Skip modules not support multiple OU, if not default OU next unless ($mod->multipleOUSupport or $defaultOU); my $comp = $mod->_userAddOns($user); if ($comp) { push (@components, $comp); } } return \@components; } # Method: allGroupAddOns # # Returns all the mason components from those modules implementing # the function _groupAddOns from EBox::LdapUserBase # # Parameters: # # group - group name # # Returns: # # array ref - holding all the components and parameters # sub allGroupAddOns { my ($self, $group) = @_; my $global = EBox::Global->modInstance('global'); my @names = @{$global->modNames}; my @modsFunc = @{$self->_modsLdapUserBase()}; my @components; foreach my $mod (@modsFunc) { my $comp = $mod->_groupAddOns($group); push (@components, $comp) if ($comp); } return \@components; } # Method: allWarning # # Returns all the the warnings provided by the modules when a certain # user or group is going to be deleted. Function _delUserWarning or # _delGroupWarning is called in all module implementing them. # # Parameters: # # object - Sort of object: 'user' or 'group' # name - name of the user or group # # Returns: # # array ref - holding all the warnings # sub allWarnings { my ($self, $object, $name) = @_; # Check for maximum users if (EBox::Global->edition() eq 'sb') { if (length(@{$self->users()}) >= MAX_SB_USERS) { throw EBox::Exceptions::External( __s('You have reached the maximum of users for this subscription level. If you need to run Zentyal with more users please upgrade.')); } } my @modsFunc = @{$self->_modsLdapUserBase()}; my @allWarns; foreach my $mod (@modsFunc) { my $warn = undef; if ($object eq 'user') { $warn = $mod->_delUserWarning($name); } else { $warn = $mod->_delGroupWarning($name); } push (@allWarns, $warn) if ($warn); } return \@allWarns; } # Method: _supportActions # # Overrides EBox::ServiceModule::ServiceInterface method. # sub _supportActions { return undef; } # Method: menu # # Overrides EBox::Module method. # sub menu { my ($self, $root) = @_; my $separator = 'Office'; my $order = 510; my $folder = new EBox::Menu::Folder('name' => 'UsersAndGroups', 'text' => $self->printableName(), 'separator' => $separator, 'order' => $order); if ($self->configured()) { if ($self->editableMode()) { $folder->add(new EBox::Menu::Item('url' => 'UsersAndGroups/Users', 'text' => __('Users'), order => 10)); $folder->add(new EBox::Menu::Item('url' => 'UsersAndGroups/Groups', 'text' => __('Groups'), order => 20)); $folder->add(new EBox::Menu::Item('url' => 'Users/Composite/UserTemplate', 'text' => __('User Template'), order => 30)); } else { $folder->add(new EBox::Menu::Item( 'url' => 'Users/View/Users', 'text' => __('Users'), order => 10)); $folder->add(new EBox::Menu::Item( 'url' => 'Users/View/Groups', 'text' => __('Groups'), order => 20)); $folder->add(new EBox::Menu::Item('url' => 'Users/Composite/UserTemplate', 'text' => __('User Template'), order => 30)); } if (EBox::Config::configkey('multiple_ous')) { $folder->add(new EBox::Menu::Item( 'url' => 'Users/View/OUs', 'text' => __('Organizational Units'), order => 25)); } $folder->add(new EBox::Menu::Item( 'url' => 'Users/Composite/Sync', 'text' => __('Synchronization'), order => 40)); $folder->add(new EBox::Menu::Item( 'url' => 'Users/Composite/Settings', 'text' => __('LDAP Settings'), order => 50)); } else { $folder->add(new EBox::Menu::Item('url' => 'Users/View/Mode', 'text' => __('Configure mode'), 'separator' => $separator, 'order' => 0)); } $root->add($folder); } # EBox::UserCorner::Provider implementation # Method: userMenu # sub userMenu { my ($self, $root) = @_; $root->add(new EBox::Menu::Item('url' => 'Users/View/Password', 'text' => __('Password'))); } # Method: syncJournalDir # # Returns the path holding sync pending actions for # the given slave. # If the directory does not exists, it will be created; # sub syncJournalDir { my ($self, $slave) = @_; my $dir = JOURNAL_DIR . $slave->name(); my $journalsDir = JOURNAL_DIR; # Create if the dir does not exists unless (-d $dir) { EBox::Sudo::root( "mkdir -p $dir", "chown -R ebox:ebox $journalsDir", "chmod 0700 $journalsDir", ); } return $dir; } # LdapModule implementation sub _ldapModImplementation { return new EBox::LdapUserImplementation(); } # SyncProvider implementation sub slaves { my ($self) = @_; my $model = $self->model('Slaves'); my @slaves; foreach my $id (@{$model->ids()}) { my $row = $model->row($id); my $host = $row->valueByName('host'); my $port = $row->valueByName('port'); push (@slaves, new EBox::UsersSync::Slave($host, $port, $id)); } my $g = EBox::Global->getInstance(1); my $u = $g->modInstance('users'); if ($u->master() eq 'cloud') { push (@slaves, new EBox::CloudSync::Slave()); } return \@slaves; } # Method: master # # Return configured master as string, undef in none # # Options: 'zentyal', 'cloud' or None # sub master { my ($self) = @_; my $row = $self->model('Master')->row(); return $row->elementByName('master')->value(); } # SyncProvider implementation sub allowUserChanges { my ($self) = @_; return (not $self->masterConf->isSlave()); } # Master-Slave UsersSync object sub masterConf { my ($self) = @_; unless ($self->{ms}) { $self->{ms} = new EBox::UsersSync::Master(); } return $self->{ms}; } sub dumpConfig { my ($self, $dir, %options) = @_; $self->ldap->dumpLdapConfig($dir); $self->ldap->dumpLdapData($dir); if ($options{bug}) { my $file = $self->ldap->ldifFile($dir, 'data'); $self->_removePasswds($file); } else { # Save rootdn passwords copy(EBox::Config::conf() . 'ldap.passwd', $dir); copy(EBox::Config::conf() . 'ldap_ro.passwd', $dir); } } sub _usersInEtcPasswd { my ($self) = @_; my @users; my @lines = File::Slurp::read_file('/etc/passwd'); foreach my $line (@lines) { my ($user) = split ':', $line, 2; push @users, $user; } return \@users; } sub backupDomains { my $name = 'homes'; my %attrs = ( printableName => __('Home directories'), description => __(q{User and groups home directoreies; anything under /home}), order => 300, ); return ($name, \%attrs); } sub backupDomainsFileSelection { return { includes => ['/home'] }; } sub restoreBackupPreCheck { my ($self, $dir) = @_; my %etcPasswdUsers = map { $_ => 1 } @{ $self->_usersInEtcPasswd() }; my @usersToRestore = @{ $self->ldap->usersInBackup($dir) }; foreach my $user (@usersToRestore) { if (exists $etcPasswdUsers{$user}) { throw EBox::Exceptions::External(__x('Cannot restore because LDAP user {user} already exists as /etc/passwd user. Delete or rename this user and try again', user => $user)); } } } sub restoreConfig { my ($self, $dir) = @_; my $mode = $self->mode(); $self->_manageService('stop'); my $LDIF_CONFIG = $self->ldap->ldifFile($dir, 'config'); my $LDIF_DB = $self->ldap->ldifFile($dir, 'data'); # retrieve base dn from backup my $fd; open($fd, $LDIF_DB); my $line = <$fd>; chomp($line); my @parts = split(/ /, $line); my $base = $parts[1]; $self->_loadLDAP($base, $LDIF_CONFIG, $LDIF_DB); # Restore passwords copy($dir . '/ldap.passwd', EBox::Config::conf()); copy($dir . '/ldap_ro.passwd', EBox::Config::conf()); EBox::debug("Copying $dir/ldap.passwd to " . EBox::Config::conf()); chmod(0600, "$dir/ldap.passwd", "$dir/ldap_ro.passwd"); $self->_manageService('start'); $self->ldap->clearConn(); # Save conf to enable NSS (and/or) PAM $self->_setConf(); for my $user (@{$self->users()}) { # Init local users if ($user->baseDn eq $self->usersDn) { $self->initUser($user); } # Notify modules $self->notifyModsLdapUserBase('addUser', $user); } } sub _removePasswds { my ($self, $file) = @_; my $anyPasswdAttr = any(qw( userPassword sambaLMPassword sambaNTPassword ) ); my $passwordSubstitution = "password"; my $FH_IN; open $FH_IN, "<$file" or throw EBox::Exceptions::Internal ("Cannot open $file: $!"); my ($FH_OUT, $tmpFile) = tempfile(DIR => EBox::Config::tmp()); foreach my $line (<$FH_IN>) { my ($attr, $value) = split ':', $line; if ($attr eq $anyPasswdAttr) { $line = $attr . ': ' . $passwordSubstitution . "\n"; } print $FH_OUT $line; } close $FH_IN or throw EBox::Exceptions::Internal ("Cannot close $file: $!"); close $FH_OUT or throw EBox::Exceptions::Internal ("Cannot close $tmpFile: $!"); File::Copy::move($tmpFile, $file); unlink $tmpFile; } # Method: authUser # # try to authenticate the given user with the given password # sub authUser { my ($self, $user, $password) = @_; my $authorized = 0; my $ldap = EBox::Ldap::safeConnect(EBox::Ldap::LDAPI); try { EBox::Ldap::safeBind($ldap, $self->userDn($user), $password); $authorized = 1; # auth ok } otherwise { $authorized = 0; # auth failed }; return $authorized; } sub listSchemas { my ($self, $ldap) = @_; my %args = ( 'base' => 'cn=schema,cn=config', 'scope' => 'one', 'filter' => "(objectClass=olcSchemaConfig)" ); my $result = $ldap->search(%args); my @schemas = map { $_->get_value('cn') } $result->entries(); return \@schemas; } sub mode { my ($self) = @_; return 'master'; } # common check for user names and group names sub checkNameLimitations { my ($name) = @_; # combination of unix limitations + windows limitation characters are # limited to unix portable file character + space for windows compability # slash not valid as first character (unix limitation) # see http://technet.microsoft.com/en-us/library/cc776019%28WS.10%29.aspx if ($name =~ /^[a-zA-Z0-9\._-][a-zA-Z0-9\._[:space:]-]*$/) { return 1; } else { return undef; } } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersSync/0000775000000000000000000000000012017154745016431 5ustar zentyal-users-2.3.15+quantal1/src/EBox/UsersSync/Master.pm0000664000000000000000000001503312017154745020224 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::UsersSync::Master; use strict; use warnings; # File containing password for master's web service (to register a new slave) use constant MASTER_PASSWORDS_FILE => EBox::Config::conf() . 'users/master.htaccess'; # Dir containing certificates for this master use constant SSL_DIR => EBox::Config::conf() . 'ssl/'; # Certificate of the authorized master use constant MASTER_CERT => '/var/lib/zentyal/conf/users/master.cert'; use EBox::Exceptions::External; use EBox::Util::Random; use EBox::Sudo; use EBox::SOAPClient; use EBox::Gettext; use URI::Escape; use File::Slurp; use EBox::UsersSync::Slave; use Error qw(:try); sub new { my $class = shift; my $self = {}; bless($self, $class); return $self; } # Method: confSOAPService # # Configure SOAP service to allow Master and Slave queries # sub confSOAPService { my ($self) = @_; my $confFile = EBox::Config::conf() . 'users/soap.conf'; my @params; push (@params, passwords_file => MASTER_PASSWORDS_FILE); EBox::Module::Base::writeConfFileNoCheck($confFile, 'users/soap.mas', \@params); my $apache = EBox::Global->modInstance('apache'); $apache->addInclude($confFile); $apache->addCA(MASTER_CERT) if (-f MASTER_CERT); } # SERVER METHODS # Method: getCertificate # # Return Master certificate (to be used when connecting to the slave's SOAP) # sub getCertificate() { my ($self) = @_; return read_file(SSL_DIR . 'ssl.cert'); } # Method: setupMaster # # Setup master server to allow new slaves connections # sub setupMaster { my ($self, $pass) = @_; defined $pass or $pass = EBox::Util::Random::generate(15); my $users = EBox::Global->getInstance()->modInstance('users'); my $table = $users->model('SlavePassword'); my $row = $table->row(); $row->elementByName('password')->setValue($pass); $row->store(); EBox::Sudo::root( 'rm -f ' . MASTER_PASSWORDS_FILE, 'htpasswd -bc ' . MASTER_PASSWORDS_FILE . ' slave ' . $pass, ); } # Method: addSlave # # Register a new slave in this master # # sub addSlave { my ($self, $host, $port, $cert) = @_; my $users = EBox::Global->modInstance('users'); my $table = $users->model('Slaves'); EBox::info("Adding a new slave on $host:$port"); my $changed = $users->changed(); my $id = $table->addRow(host => $host, port => $port); unless ($changed) { # FIXME do this better when framework available $users->_saveConfig(); $users->setAsChanged(0); } unless (-d EBox::UsersSync::Slave->SLAVES_CERTS_DIR) { mkdir EBox::UsersSync::Slave->SLAVES_CERTS_DIR; } # save slave's cert write_file(EBox::UsersSync::Slave->SLAVES_CERTS_DIR . $id, $cert); $users->initialSlaveSync(new EBox::UsersSync::Slave($host, $port, $id)); # Regenerate slave connection password $self->setupMaster(); } # CLIENT METHODS # Method: checkMaster # # Checks connection to a given master's SOAP # # Parameters: # # host - master hostname or ip # port - master administration port # password - password for slave connection # # Returns 1 if could connect and SOAP replied, 0 otherwise # sub checkMaster { my ($self, $host, $port, $password) = @_; my $apache = EBox::Global->modInstance('apache'); $password = uri_escape($password); local $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; my $master = EBox::SOAPClient->instance( name => 'urn:Users/Master', proxy => "https://slave:$password\@$host:$port/master", ); try { $master->getDN(); } otherwise { my $ex = shift; $self->_analyzeException($ex); }; } # Method: isSlave # # Return 1 if already configured as slave # sub isSlave { my ($self) = @_; return (-f MASTER_CERT); } # Method: setupSlave # # Configure users module as slave of a given master host # sub setupSlave { my ($self) = @_; my $users = EBox::Global->modInstance('users'); my $master = $users->model('Master'); if ($users->master() eq 'zentyal') { # return if already configured return if ($self->isSlave()); my $host = $master->hostValue(); my $port = $master->portValue(); my $password = $master->passwordValue(); my $apache = EBox::Global->modInstance('apache'); $password = uri_escape($password); my $client = EBox::SOAPClient->instance( name => 'urn:Users/Master', proxy => "https://slave:$password\@$host:$port/master", ); # Recreate LDAP for the master DN $self->_recreateLDAP($users, $client); # get master's certificate my $cert = $client->getCertificate(); my $client_cert = read_file(SSL_DIR . 'ssl.cert'); try { $client->registerSlave($apache->port(), $client_cert, 1); } otherwise { my $ex = shift; $self->_analyzeException($ex); }; # Write master certificate # (after registering slave, this means everything went well) write_file(MASTER_CERT, $cert); } else { # return if already disabled return unless ($self->isSlave()); # disable master access unlink (MASTER_CERT); } } sub _recreateLDAP { my ($self, $users, $client) = @_; my $dn = $client->getDN(); my $row = $users->model('Mode')->row(); $row->elementByName('dn')->setValue($dn); $row->store(); # Enable actions (without slave setup to avoid recursion) $users->enableActions(); # TODO: reenable all LDAP modules } sub _analyzeException { my ($self, $ex) = @_; my $msg = $ex->text(); if ($msg =~ m/^401/) { $msg = __('Invalid password'); } elsif ($msg =~ m/^500/) { $msg = __('Connection failed, check host, port and firewall settings'); } throw EBox::Exceptions::External(__("Couldn't configure Zentyal as slave") . ": $msg."); } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersSync/Slave.pm0000664000000000000000000001023112017154745020036 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::UsersSync::Slave; use strict; use warnings; use base 'EBox::UsersAndGroups::Slave'; # Dir containing certificates for this master use constant SSL_DIR => EBox::Config::conf() . 'ssl/'; # Dir storing slave use constant SLAVES_CERTS_DIR => '/var/lib/zentyal/conf/users/slaves/'; use EBox::Global; use EBox::Exceptions::External; use EBox::Util::Random; use EBox::Sudo; use EBox::SOAPClient; use EBox::Gettext; use URI::Escape; use File::Slurp; use Error qw(:try); use MIME::Base64; sub new { my ($class, $host, $port, $id) = @_; my $self = $class->SUPER::new(name => $id); $self->{host} = $host; $self->{port} = $port; $self->{cert} = SLAVES_CERTS_DIR . $id; bless($self, $class); return $self; } sub _addUser { my ($self, $user) = @_; # encode passwords my @passwords = map { encode_base64($_) } @{$user->passwordHashes()}; my $userinfo = { user => $user->get('uid'), fullname => $user->get('cn'), surname => $user->get('sn'), givenname => $user->get('givenName'), passwords => \@passwords }; if ($user->get('description')) { $userinfo->{comment} = $user->get('description'); } # Different OU? my $users = EBox::Global->modInstance('users'); if ($user->baseDn() ne $users->usersDn()) { $userinfo->{ou} = $user->baseDn(); } # Convert userinfo to SOAP::Data to avoid automatic conversion errors my @params; for my $k (keys %$userinfo) { if (ref($userinfo->{$k}) eq 'ARRAY') { push(@params, SOAP::Data->name($k => SOAP::Data->value(@{$userinfo->{$k}}))); } else { push(@params, SOAP::Data->name($k => $userinfo->{$k})); } } $userinfo = SOAP::Data->name("userinfo" => \SOAP::Data->value(@params)); $self->soapClient->addUser($userinfo); return 0; } sub _modifyUser { my ($self, $user, $pass) = @_; my $userinfo = { dn => $user->dn(), fullname => $user->get('cn'), surname => $user->get('sn'), givenname => $user->get('givenName'), }; $userinfo->{password} = $pass if ($pass); if ($user->get('description')) { $userinfo->{description} = $user->get('description'); } $self->soapClient->modifyUser($userinfo); return 0; } sub _delUser { my ($self, $user) = @_; $self->soapClient->delUser($user->dn()); return 0; } sub _addGroup { my ($self, $group) = @_; my $groupinfo = { name => $group->name(), comment => $group->get('description'), }; $self->soapClient->addGroup($groupinfo); return 0; } sub _modifyGroup { my ($self, $group) = @_; my @members = $group->get('member'); my $groupinfo = { dn => $group->dn(), members => \@members, }; $self->soapClient->modifyGroup($groupinfo); return 0; } sub _delGroup { my ($self, $group) = @_; $self->soapClient->delGroup($group->dn()); return 0; } # CLIENT METHODS sub soapClient { my ($self) = @_; my $hostname = $self->{host}; my $port = $self->{port}; unless ($self->{client}) { $self->{client} = EBox::SOAPClient->instance( name => 'urn:Users/Slave', proxy => "https://$hostname:$port/slave/", certs => { cert => SSL_DIR . 'ssl.pem', private => SSL_DIR . 'ssl.key', ca => $self->{cert}, } ); } return $self->{client}; } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersSync/WSDispatcherMaster.pm0000664000000000000000000000233512017154745022506 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::UsersSync::WSDispatcherMaster; # Class: EBox::UsersSync::WSDispatcherMaster # # A SOAP::Lite handle called by apache-perl (mod_perl) everytime # a SOAP service is required. # use EBox; use SOAP::Transport::HTTP; use strict; use warnings; EBox::init(); my $server = SOAP::Transport::HTTP::Apache ->dispatch_with( { 'urn:Users/Master' => 'EBox::UsersSync::SOAPMaster' } ); # Method: handler # # Handle the HTTP request # sub handler { # Currently connection is just once basis $server->handler(@_); } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersSync/SOAPSlave.pm0000664000000000000000000000552512017154745020533 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::UsersSync::SOAPSlave; use strict; use warnings; use EBox::Exceptions::MissingArgument; use EBox::Config; use EBox::Global; use Devel::StackTrace; use SOAP::Lite; use MIME::Base64; use EBox::UsersAndGroups::User; use EBox::UsersAndGroups::Group; # Group: Public class methods sub addUser { my ($self, $user) = @_; # rencode passwords my @pass = map { decode_base64($_) } @{$user->{passwords}}; $user->{passwords} = \@pass; EBox::UsersAndGroups::User->create($user); return $self->_soapResult(0); } sub modifyUser { my ($class, $userinfo) = @_; my $user = new EBox::UsersAndGroups::User(dn => $userinfo->{dn}); $user->set('cn', $userinfo->{fullname}, 1); $user->set('sn', $userinfo->{surname}, 1); $user->set('givenname', $userinfo->{givenname}, 1); if ($userinfo->{password}) { $user->changePassword($userinfo->{password}, 1); } $user->save(); return $class->_soapResult(0); } sub delUser { my ($self, $dn) = @_; my $user = new EBox::UsersAndGroups::User(dn => $dn); $user->deleteObject(); return $self->_soapResult(0); } sub addGroup { my ($class, $group) = @_; EBox::UsersAndGroups::Group->create($group->{name}, $group->{comment}); return $class->_soapResult(0); } sub modifyGroup { my ($self, $groupinfo) = @_; my $group = new EBox::UsersAndGroups::Group(dn => $groupinfo->{dn}); $group->set('member', $groupinfo->{members}); return 1; } sub delGroup { my ($self, $dn) = @_; my $group = new EBox::UsersAndGroups::Group(dn => $dn); $group->deleteObject(); return $self->_soapResult(0); } # Method: URI # # Overrides: # # # sub URI { return 'urn:Users/Slave'; } # Method: _soapResult # # Serialise SOAP result to be WSDL complaint # # Parameters: # # retData - the returned data # sub _soapResult { my ($class, $retData) = @_; my $trace = new Devel::StackTrace(); if ($trace->frame(2)->package() eq 'SOAP::Server' ) { $SOAP::Constants::NS_SL_PERLTYPE = $class->URI(); return SOAP::Data->name('return', $retData); } else { return $retData; } } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersSync/WSDispatcherSlave.pm0000664000000000000000000000233112017154745022321 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::UsersSync::WSDispatcherSlave; # Class: EBox::UsersSync::WSDispatcherSlave # # A SOAP::Lite handle called by apache-perl (mod_perl) everytime # a SOAP service is required. # use EBox; use SOAP::Transport::HTTP; use strict; use warnings; EBox::init(); my $server = SOAP::Transport::HTTP::Apache ->dispatch_with( { 'urn:Users/Slave' => 'EBox::UsersSync::SOAPSlave' } ); # Method: handler # # Handle the HTTP request # sub handler { # Currently connection is just once basis $server->handler(@_); } 1; zentyal-users-2.3.15+quantal1/src/EBox/UsersSync/SOAPMaster.pm0000664000000000000000000000412412017154745020706 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::UsersSync::SOAPMaster; use strict; use warnings; use EBox::Exceptions::MissingArgument; use EBox::Config; use EBox::Global; use Devel::StackTrace; use SOAP::Lite; sub getDN { my ($self) = @_; my $users = EBox::Global->modInstance('users'); my $dn = $users->ldap->dn(); return $self->_soapResult($dn); } sub getCertificate { my ($self) = @_; my $users = EBox::Global->modInstance('users'); my $master = $users->masterConf(); my $cert = $master->getCertificate(); return $self->_soapResult($cert); } sub registerSlave { my ($self, $port, $cert) = @_; my $req = Apache2::RequestUtil->request(); my $host = $req->connection->get_remote_host(); my $users = EBox::Global->modInstance('users'); my $master = $users->masterConf(); $master->addSlave($host, $port, $cert); return $self->_soapResult(0); } # Method: URI # # Overrides: # # # sub URI { return 'urn:Users/Master'; } # Method: _soapResult # # Serialise SOAP result to be WSDL complaint # # Parameters: # # retData - the returned data # sub _soapResult { my ($class, $retData) = @_; my $trace = new Devel::StackTrace(); if ($trace->frame(2)->package() eq 'SOAP::Server' ) { $SOAP::Constants::NS_SL_PERLTYPE = $class->URI(); return SOAP::Data->name('return', $retData); } else { return $retData; } } 1; zentyal-users-2.3.15+quantal1/src/EBox/KerberosModule.pm0000664000000000000000000000505512017154745017760 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::KerberosModule; use strict; use warnings; use Error qw( :try ); use EBox::Util::Random; sub new { my $class = shift; my $self = {}; bless ($self, $class); return $self; } sub kerberosServicePrincipals { my ($self) = @_; return []; } sub kerberosCreatePrincipals { my ($self) = @_; my $sysinfo = EBox::Global->modInstance('sysinfo'); my $hostname = $sysinfo->hostName(); my $hostdomain = $sysinfo->hostDomain(); my $data = $self->kerberosServicePrincipals(); EBox::Sudo::silentRoot("rm -f $data->{keytab}"); my $pass = EBox::Util::Random::generate(20); foreach my $service (@{$data->{principals}}) { $service = uc ($service); my $principal = "$service/$hostname.$hostdomain"; # TODO Generate all principals with the same password to import them into samba my @cmds=(); push (@cmds, 'kadmin -l add ' . "--password='$pass' " . "--max-ticket-life='1 day' " . "--max-renewable-life='1 week' " . "--attributes='' " . "--expiration-time=never " . "--pw-expiration-time=never " . "--policy=default '$principal'"); push (@cmds, "kadmin -l ext -k '$data->{keytab}' '$principal'"); push (@cmds, "chown root:$data->{keytabUser} '$data->{keytab}'"); push (@cmds, "chmod 440 '$data->{keytab}'"); EBox::Sudo::silentRoot("kadmin -l del $principal"); EBox::debug("Creating service principal $principal"); EBox::Sudo::root(@cmds); } # Import service principals from Zentyal to samba if (EBox::Global->modExists('samba')) { my $sambaModule = EBox::Global->modInstance('samba'); if ($sambaModule->isEnabled() and $sambaModule->isProvisioned()) { $sambaModule->ldb->ldapServicePrincipalsToLdb(); } } } 1; zentyal-users-2.3.15+quantal1/src/EBox/UserCorner/0000775000000000000000000000000012017154745016562 5ustar zentyal-users-2.3.15+quantal1/src/EBox/UserCorner/Provider.pm0000664000000000000000000000222312017154745020711 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, as # published by the Free Software Foundation. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # This is the interface that modules that want to provide UserCorner CGIs need # to implement package EBox::UserCorner::Provider; use strict; use warnings; sub new { my $class = shift; my $self = {}; bless($self, $class); return $self; } # Method: userMenu # # This function returns is similar to EBox::Module::Base::menu but # returns UserCorner CGIs for the eBox UserCorner. Override as needed. sub userMenu { #default empty implementation return undef; } 1; zentyal-users-2.3.15+quantal1/stubs/0000775000000000000000000000000012017154745014207 5ustar zentyal-users-2.3.15+quantal1/stubs/krb5.conf.mas0000664000000000000000000000065312017154745016504 0ustar <%args> $realm [libdefaults] default_realm = <% $realm %> dns_lookup_kdc = true dns_lookup_realm = true default_tgs_enctypes = arcfour-hmac-md5 des-cbc-md5 dec-cbc-crc default_tkt_enctypes = arcfour-hmac-md5 des-cbc-md5 dec-cbc-crc preferred_enctypes = arcfour-hmac-md5 des-cbc-md5 dec-cbc-crc [kadmin] default_keys = des-cbc-crc:pw-salt des-cbc-md5:pw-salt arcfour-hmac-md5:pw-salt zentyal-users-2.3.15+quantal1/stubs/acc-zentyal.mas0000664000000000000000000000476712017154745017141 0ustar <%args> $umask # # this configuration is for using ldap to authenticate and authorize # Zentyal LDAP users and groups on the system. # [zentyal-nokrb] nss_passwd=passwd: compat ldap nss_group=group: compat ldap nss_shadow=shadow: compat ldap nss_netgroup=netgroup: compat ldap pam_auth=auth [success=1 default=ignore] pam_unix.so nullok_secure auth requisite pam_deny.so auth required pam_permit.so pam_account=account [success=1 new_authtok_reqd=done default=ignore] pam_unix.so account requisite pam_deny.so account required pam_permit.so pam_password=password [success=1 default=ignore] pam_unix.so obscure sha512 password requisite pam_deny.so password required pam_permit.so pam_session=session [default=1] pam_permit.so session requisite pam_deny.so session required pam_permit.so session optional pam_umask.so session required pam_unix.so session required pam_mkhomedir.so skel=/etc/skel/ umask=<% $umask %> [zentyal-krb] nss_passwd=passwd: compat ldap nss_group=group: compat ldap nss_shadow=shadow: compat ldap nss_netgroup=netgroup: compat ldap pam_auth=auth [success=2 default=ignore] pam_krb5.so minimum_uid=1000 auth [success=1 default=ignore] pam_unix.so nullok_secure try_first_pass auth requisite pam_deny.so auth required pam_permit.so pam_account=account [success=1 new_authtok_reqd=done default=ignore] pam_unix.so account requisite pam_deny.so account required pam_permit.so account required pam_krb5.so minimum_uid=1000 pam_password=password [success=2 default=ignore] pam_krb5.so minimum_uid=1000 password [success=1 default=ignore] pam_unix.so obscure use_authtok try_first_pass sha512 password requisite pam_deny.so password required pam_permit.so pam_session=session [default=1] pam_permit.so session requisite pam_deny.so session required pam_permit.so session optional pam_umask.so session optional pam_krb5.so minimum_uid=1000 session required pam_unix.so session required pam_mkhomedir.so skel=/etc/skel/ umask=<% $umask %> zentyal-users-2.3.15+quantal1/stubs/ldap.conf.mas0000664000000000000000000000210612017154745016554 0ustar <%args> $basedc $ldap $rootbinddn $binddn $bindpw $usersdn $computersdn $groupsdn # network or connect timeouts (see bind_timelimit). # host 127.0.0.1 # The distinguished name of the search base. base <% $basedc %> # Another way to specify your LDAP server is to provide an # uri with the server name. This allows to use # Unix Domain Sockets to connect to a local LDAP Server. uri <% $ldap %> # The LDAP version to use (defaults to 3 # if supported by client library) ldap_version 3 bind_policy soft # The distinguished name to bind to the server with # if the effective user ID is root. Password is # stored in /etc/ldap.secret (mode 600) rootbinddn <% $rootbinddn %> binddn <% $binddn %> bindpw <% $bindpw %> nss_base_passwd <% $usersdn %>?one nss_base_passwd <% $computersdn %>?one nss_base_shadow <% $usersdn %>?one nss_base_group <% $groupsdn %>?one nss_schema rfc2307bis nss_map_attribute uniqueMember member nss_reconnect_tries 2 nss_initgroups_ignoreusers root,ldap,named,avahi,haldaemon,dbus,news,mailman,nscd,gdm,apache zentyal-users-2.3.15+quantal1/stubs/config.ldif.mas0000664000000000000000000000563712017154745017106 0ustar <%args> $dn $password dn: cn=config objectClass: olcGlobal cn: config olcPidFile: /var/run/slapd/slapd.pid olcArgsFile: /var/run/slapd/slapd.args olcLogLevel: none olcToolThreads: 1 # Load modules dn: cn=module{0},cn=config objectClass: olcModuleList cn: module{0} olcModulePath: /usr/lib/ldap olcModuleLoad: back_hdb olcModuleLoad: memberof olcModuleLoad: smbk5pwd.so # Load schemas dn: cn=schema,cn=config objectClass: olcSchemaConfig cn: schema include: file:///etc/ldap/schema/core.ldif include: file:///etc/ldap/schema/cosine.ldif include: file:///usr/share/zentyal-users/rfc2307bis.ldif include: file:///etc/ldap/schema/inetorgperson.ldif include: file:///usr/share/zentyal-users/heimdal.ldif # Set defaults for the backend dn: olcBackend=hdb,cn=config objectClass: olcBackendConfig olcBackend: hdb # Frontend settings dn: olcDatabase={-1}frontend,cn=config objectClass: olcDatabaseConfig objectClass: olcFrontendConfig olcDatabase: {-1}frontend olcSizeLimit: 500 olcAccess: {1}to dn.exact="" by * read olcAccess: {2}to dn.base="cn=Subschema" by * read olcPasswordHash: {K5KEY} # Config db settings dn: olcDatabase=config,cn=config objectClass: olcDatabaseConfig olcDatabase: config olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by dn="cn=zentyal,<% $dn %>" manage by * break # The database definition. dn: olcDatabase={1}hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: {1}hdb olcDbCheckpoint: 512 30 olcDbConfig: set_cachesize 0 2097152 0 olcDbConfig: set_lk_max_objects 1500 olcDbConfig: set_lk_max_locks 1500 olcDbConfig: set_lk_max_lockers 1500 olcLastMod: TRUE olcSuffix: <% $dn %> olcRootDN: cn=zentyal,<% $dn %> olcRootPW: <% $password %> olcDbDirectory: /var/lib/ldap olcLimits: dn="cn=zentyal,<% $dn %>" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by dn="cn=zentyal,<% $dn %>" manage by * break olcAccess: {1}to attrs=userPassword,shadowLastChange,krb5Key by dn="cn=zentyal,<% $dn %>" write by anonymous auth by dn="cn=zentyalro,<% $dn %>" none by self write by * none olcAccess: {2}to * by users read olcDbIndex: objectclass eq olcDbIndex: entryCSN eq olcDbIndex: entryUUID eq olcDbIndex: uid eq olcDbIndex: member eq # Memberof automatic attribute population dn: olcOverlay=memberof,olcDatabase={1}hdb,cn=config objectClass: olcMemberOf objectClass: olcOverlayConfig objectClass: olcConfig objectClass: top olcOverlay: memberof olcMemberOfDangling: ignore olcMemberOfRefInt: TRUE olcMemberOfGroupOC: zentyalGroup olcMemberOfMemberAD: member olcMemberOfMemberOfAD: memberOf # smbk5pwd overlay dn: olcOverlay=smbk5pwd,olcDatabase={1}hdb,cn=config objectClass: olcOverlayConfig objectClass: olcSmbK5PwdConfig olcOverlay: smbk5pwd olcSmbK5PwdEnable: krb5 olcSmbK5PwdMustChange: 0 olcSmbK5PwdCanChange: 0 zentyal-users-2.3.15+quantal1/stubs/kdc.conf.mas0000664000000000000000000000712212017154745016400 0ustar <%args> $ldapBase $realm [kdc] logging = FILE:/var/log/heimdal-kdc.log hdb-ldap-create-base = ou=kerberos,<% $ldapBase %> database = { label = { acl_file = /etc/heimdal-kdc/kadmind.acl dbname = ldap:<% $ldapBase %> realm = <% $realm %> log_file = /var/log/heimdal-database.log mkey_file = /etc/heimdal-kdc/m-key } } # detach = boolean # Gives an upper limit on the size of the requests that the kdc is # willing to handle. # max-request = integer # Turn off the requirement for pre-autentication in the initial AS- # REQ for all principals. The use of pre-authentication makes it # more difficult to do offline password attacks. You might want to # turn it off if you have clients that don't support pre-authenti- # cation. Since the version 4 protocol doesn't support any pre- # authentication, serving version 4 clients is just about the same # as not requiring pre-athentication. The default is to require # pre-authentication. Adding the require-preauth per principal is # a more flexible way of handling this. # require-preauth = boolean # Specifies the set of ports the KDC should listen on. It is given # as a white-space separated list of services or port numbers. # ports = 88,750 # The list of addresses to listen for requests on. By default, the # kdc will listen on all the locally configured addresses. If only # a subset is desired, or the automatic detection fails, this # option might be used. # addresses = list of ip addresses # respond to Kerberos 4 requests # enable-kerberos4 = false # respond to Kerberos 4 requests from foreign realms. This is a # known security hole and should not be enabled unless you under- # stand the consequences and are willing to live with them. # enable-kerberos4-cross-realm = false # respond to 524 requests # enable-524 = value of enable-kerberos4 # Makes the kdc listen on port 80 and handle requests encapsulated # in HTTP. # enable-http = boolean # What realm this server should act as when dealing with version 4 # requests. The database can contain any number of realms, but # since the version 4 protocol doesn't contain a realm for the # server, it must be explicitly specified. The default is whatever # is returned by krb_get_lrealm(). This option is only availabe if # the KDC has been compiled with version 4 support. # v4-realm = string # Enable kaserver emulation (in case it's compiled in). # enable-kaserver = false # Check the addresses in the ticket when processing TGS requests. # check-ticket-addresses = true # Permit tickets with no addresses. This option is only # relevent when check-ticket-addresses is TRUE. # allow-null-ticket-addresses = true # Permit anonymous tickets with no addresses. # allow-anonymous = boolean # Always verify the transited policy, ignoring the # disable-transited-check flag if set in the KDC client request. # transited-policy = {always-check,allow-per-principal,always-honour-request} # Encode AS-Rep as TGS-Rep to be bug-compatible with old DCE # code. The Heimdal clients allow both. # encode_as_rep_as_tgs_rep = boolean # How long before password/principal expiration the KDC should # start sending out warning messages. # kdc_warn_pwexpire = time # Specifies the set of ports the KDC should listen on. It is given # as a white-space separated list of services or port numbers. # kdc_ports = 88,750 # [password_quality] # check_library = LIBRARY # check_function = FUNCTION # min_length = value [kadmin] default_keys = des-cbc-crc:pw-salt des-cbc-md5:pw-salt arcfour-hmac-md5:pw-salt # use_v4_salt = boolean zentyal-users-2.3.15+quantal1/stubs/heimdal-kdc.mas0000664000000000000000000000064612017154745017061 0ustar <%args> # Do we start the KDC? KDC_ENABLED=yes KDC_PARAMS="--config-file=/etc/heimdal-kdc/kdc.conf --ports=8880" # the kpasswdd? KPASSWDD_ENABLED=yes KPASSWDD_PARAMS="-k /etc/kpasswdd.keytab --port=8464" # kprop master? MASTER_ENABLED=no # How about the kprop slave? SLAVE_ENABLED=no # Add at least your master server name here when using iprop-replication # otherwise it would fail silently. SLAVE_PARAMS="" zentyal-users-2.3.15+quantal1/stubs/soap.mas0000664000000000000000000000117112017154745015653 0ustar <%args> $passwords_file SetHandler perl-script PerlHandler EBox::UsersSync::WSDispatcherSlave SSLRequireSSL SSLVerifyClient require SSLVerifyDepth 1 Order allow,deny Allow from all SetHandler perl-script PerlHandler EBox::UsersSync::WSDispatcherMaster AuthType basic AuthName "Master SOAP Server" AuthUserFile <% $passwords_file %> Require valid-user RewriteRule /master - [L] RewriteRule /slave - [L] zentyal-users-2.3.15+quantal1/stubs/zentyal-users.cron.mas0000664000000000000000000000063012017154745020475 0ustar <%args> $slave_time $cloudsync_enabled => 0 # /etc/cron.d/zentyal-users SHELL=/bin/sh PATH=/usr/bin:/bin # sync the slaves every <% $slave_time %> minutes if there are missing changes */<% $slave_time %> * * * * root /usr/share/zentyal-users/slave-sync % if ($cloudsync_enabled) { # ask for users changes in cloud */<% $slave_time %> * * * * root /usr/share/zentyal-users/cloud-sync % } zentyal-users-2.3.15+quantal1/stubs/database.ldif.mas0000664000000000000000000000151612017154745017375 0ustar <%args> $dn $password $password_ro <%init> my @parts = split(/,/, $dn); my $dc = (split(/=/, $parts[0]))[1]; dn: <% $dn %> objectClass: organization objectClass: dcObject objectClass: top dc: <% $dc %> o: <% $dc %> dn: ou=Users,<% $dn %> objectClass: organizationalUnit ou: Users dn: ou=Groups,<% $dn %> objectClass: organizationalUnit ou: Groups dn: ou=Computers,<% $dn %> objectClass: organizationalUnit ou: Computers dn: ou=Kerberos,<% $dn %> objectClass: organizationalUnit ou: Kerberos dn: cn=zentyal,<% $dn %> objectClass: organizationalRole objectClass: simpleSecurityObject description: Zentyal admin account userPassword: <% $password %> dn: cn=zentyalro,<% $dn %> objectClass: organizationalRole objectClass: simpleSecurityObject description: Zentyal readonly account userPassword: <% $password_ro %> zentyal-users-2.3.15+quantal1/extra/0000775000000000000000000000000012017154745014172 5ustar zentyal-users-2.3.15+quantal1/extra/slapd.default.no0000664000000000000000000000353712017154745017266 0ustar # Default location of the slapd.conf file. If empty, use the compiled-in # default (/etc/ldap/slapd.conf). If using the cn=config backend to store # configuration in LDIF, set this variable to the directory containing the # cn=config data. SLAPD_CONF= # System account to run the slapd server under. If empty the server # will run as root. SLAPD_USER="openldap" # System group to run the slapd server under. If empty the server will # run in the primary group of its user. SLAPD_GROUP="openldap" # Path to the pid file of the slapd server. If not set the init.d script # will try to figure it out from $SLAPD_CONF (/etc/ldap/slapd.conf by # default) SLAPD_PIDFILE= # slapd normally serves ldap only on all TCP-ports 389. slapd can also # service requests on TCP-port 636 (ldaps) and requests via unix # sockets. # Example usage: # SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///" SLAPD_SERVICES="ldap://0.0.0.0:390 ldapi://%2fvar%2frun%2fslapd%2fldapi/????x-mod=0777" # If SLAPD_NO_START is set, the init script will not start or restart # slapd (but stop will still work). Uncomment this if you are # starting slapd via some other means or if you don't want slapd normally # started at boot. SLAPD_NO_START=1 # If SLAPD_SENTINEL_FILE is set to path to a file and that file exists, # the init script will not start or restart slapd (but stop will still # work). Use this for temporarily disabling startup of slapd (when doing # maintenance, for example, or through a configuration management system) # when you don't want to edit a configuration file. SLAPD_SENTINEL_FILE=/etc/ldap/noslapd # For Kerberos authentication (via SASL), slapd by default uses the system # keytab file (/etc/krb5.keytab). To use a different keytab file, # uncomment this line and change the path. #export KRB5_KTNAME=/etc/krb5.keytab # Additional options to pass to slapd SLAPD_OPTIONS="" zentyal-users-2.3.15+quantal1/extra/slapd.default0000664000000000000000000000364612017154745016654 0ustar # Location of the slapd configuration to use. If using the cn=config # backend to store configuration in LDIF, set this variable to the # directory containing the cn=config data; otherwise set it to the location # of your slapd.conf file. If empty, use the compiled-in default # (/etc/ldap/slapd.d). SLAPD_CONF= # System account to run the slapd server under. If empty the server # will run as root. SLAPD_USER="openldap" # System group to run the slapd server under. If empty the server will # run in the primary group of its user. SLAPD_GROUP="openldap" # Path to the pid file of the slapd server. If not set the init.d script # will try to figure it out from $SLAPD_CONF (/etc/ldap/slapd.d by # default) SLAPD_PIDFILE= # slapd normally serves ldap only on all TCP-ports 389. slapd can also # service requests on TCP-port 636 (ldaps) and requests via unix # sockets. # Example usage: # SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///" SLAPD_SERVICES="ldap://0.0.0.0:390/ ldapi:/// ldaps:///" # If SLAPD_NO_START is set, the init script will not start or restart # slapd (but stop will still work). Uncomment this if you are # starting slapd via some other means or if you don't want slapd normally # started at boot. #SLAPD_NO_START=1 # If SLAPD_SENTINEL_FILE is set to path to a file and that file exists, # the init script will not start or restart slapd (but stop will still # work). Use this for temporarily disabling startup of slapd (when doing # maintenance, for example, or through a configuration management system) # when you don't want to edit a configuration file. SLAPD_SENTINEL_FILE=/etc/ldap/noslapd # For Kerberos authentication (via SASL), slapd by default uses the system # keytab file (/etc/krb5.keytab). To use a different keytab file, # uncomment this line and change the path. #export KRB5_KTNAME=/etc/krb5.keytab # Additional options to pass to slapd SLAPD_OPTIONS="" zentyal-users-2.3.15+quantal1/extra/krb5Key.asn0000664000000000000000000000100612017154745016206 0ustar Key ::= SEQUENCE { mkvno [0] krb5int32 OPTIONAL, key [1] EncryptionKey, salt [2] Salt OPTIONAL } krb5int32 ::= SEQUENCE { value INTEGER } krb5str ::= SEQUENCE { value OCTET STRING } Salt ::= SEQUENCE { value _Salt } _Salt ::= SEQUENCE { type [0] krb5int32, salt [1] krb5str, opaque [2] krb5str OPTIONAL } EncryptionKey ::= SEQUENCE { value _EncryptionKey } _EncryptionKey ::= SEQUENCE { keytype [0] krb5int32, keyvalue [1] krb5str } zentyal-users-2.3.15+quantal1/extra/files.list0000664000000000000000000000016612017154745016174 0ustar slapd.default /usr/share/zentyal-users slapd.default.no /usr/share/zentyal-users krb5Key.asn /usr/share/zentyal-users zentyal-users-2.3.15+quantal1/ChangeLog0000664000000000000000000004606512017154745014634 0ustar 2.3.15 + Fixed password change at user corner + Change KDC port to 8880 to preserve the classic default for user corner 2.3.14 + Ignore the LDAP error 'no attributes to update' on save + Instantiate users by uid and groups by gid + Change kerberos ports from 88/464 to 8888/8464. This avoid conflicts and management logic of the heimdal daemons. Kerberos records are added with lower priority over samba ones. + Respect the optionality of the 'salt' field inside the kerberos keys in the 'setKerberosKeys' funcion of the User class. + Do not remove service principals when samba is enabled/disabled. Samba will import the keys + Add method to set the user kerberos keys + Stop samba daemon if module is disabled to ensure that port 88 is free + Initialize kerberos realm in lowercase to match the host domain + User template account default options not longer shown in slave servers + Added users filter by OU 2.3.13 + Better password policies for LDAP backend + Added user synchronization with Zentyal Cloud + Removed deprecated conf keys (password hashes selection) + Sync kerberos hashes on master-slave + Resolve slave hostname during registering + Fixed framework changes related regression getting redis keys directly 2.3.12 + Ask for the host domain in the wizard instead of the old mode selector + Fixed user name validation 2.3.11 + Remove deprecated reference to AD Sync in wizard + Check to make sure that quota has been really assigned logs an error instead of raising an exeception, because some file systems does not support quotas + Adapt lastUid and lastGid to the new API and make them compatible with multiple OUs 2.3.10 + Use DataForm::ReadOnly::_content instead of acquirers in LdapInfo + Delete obsolete daemons and attributes regarding old replication + Better error control in _loadACLDirectory + Adapted to new Model management framework + Adapted Password type to new framework + Added NTP as enable dependency 2.3.9 + Heimdal Kerberos integration for SSO features + Better validation of user names and groups names. Better message when this validation fails + Added user() and group methods() to EBox::UsersAndGroups + Added quota limit check + Added backup domain for /home + Adapted ldapvi to changes in port + Setup master method can now take a custom password 2.3.8 + Restart apache after changing master configuration + Removed all files + code cleaning + Disable user editing in slaves 2.3.7 + New modifications() method to allow retrieving modifications made to the LDAP object in the last call to 'save' + Create users without password and set it after that, needed for samba4 + Removed auth_type warnings 2.3.6 + Use the new unified tableBody.mas instead of tableBodyWithoutActions.mas 2.3.5 + Packaging fixes for precise 2.3.4 + Updated Standard-Versions to 3.9.2 2.3.3 + New master-slave architecture + Image in initial configuration wizard is shown again 2.3.2 + Added printableName to service and modified description + Fixed executable permissions in src/scripts + Added checks for small business subscription + Bugfix: lastGid method was calling MINUID and SYSMINUID + Reload nscd before trying to init users and groups 2.3.1 + Use Digest::SHA instead of Digest::SHA1 and remove libdigest-sha1-perl dependency which no longer exists on precise 2.3 + Commented unused code in cleanUser method + Replaced autotools with zbuildtools 2.2.5 + Bugfix: ad-sync can now populate groups with more than 1500 users + Bugfix: do not allow adsync passwords longer than 16 chars to avoid crash in pwdsync-server that keeps respawning + Bugfix: mark apache as changed in enableActions to avoid problems adding users before the new nsswitch conf is available for apache, also do not allow to add users if module is not really enabled after save changes + Make sure the default DN does not contains invalid characters + Do not allow malformed LDAP DNs in Mode 2.2.4 + Make LDAP ready after enableActions restarting the service to avoid problems when adding users or groups + Fixed corruption when adding ldap attributes + Also disable apparmor in ad-sync mode + Renamed default adsync username from eboxadsync to adsyncuser 2.2.3 + Adapt pwdsync user and password offsets to the new hook implementation + Always ignore ForeignSecurityPrincipals accounts in ad-sync + Added more debug messages and improved existing ones in ad-sync + Avoid warnings trying to get userPrincipalName in ad-sync + Skip machine accounts in ad-sync + Use paged queries in ad-sync + Allow to specify custom DN to bind to Windows Server in ad-sync + Ingore empty users in ad-sync 2.2.2 + Fixed validation of secret key length in ADSync Options model + Removed useless validation of AD username in ADSync Options model + Show different error when adding users from Windows with invalid chars + Fixed bug managing slapd on ad-sync 2.2.1 + Do not enable ADSync to avoid launching daemon before configuration + Also manage slapd daemon on ad-sync setups + Avoid slave connection to incompatible masters + Added quota change form on slaves + Allowed '\' character in ad-sync username 2.1.14 + Fixed regression in usercorner link 2.1.13 + Moved apache soap configuration from setConf to enableActions + Init slave users on enable (now home directories are created) + Create LDAP indexes during slave enable 2.1.12 + UsersAndGroups::lastUid() now takes also into account non-ldap users + Stop old ldap daemons in reinstall script, needed before changing mode 2.1.11 + Use a safer mode() implementation to avoid recursions with ModelManager 2.1.10 + Start slapd daemon when a module fails to connect + Help in wizard is show again if no custom_prefix defined 2.1.9 + Hide help with link in wizard if custom_prefix defined + Removed /zentyal prefix from URLs + Disable autocompletion in user form + Avoid duplicated restart during postinst 2.1.8 + Include quota schema in slaves LDAP (fixes replication) + Do not stop slapd daemons after slave enable + Fixed users and groups retrieval if module is disabled + Manage slapd daemon in master mode + Make the optional 'comment' field to also appear as optional on the UI + Ignore users also in pwdsync-server, not only in the ad-sync script 2.1.7 + Set submenu items order for integration with the User Corner menu + Avoid undefined dn warning 2.1.6 + Fix adsync mode check for zentyal-users cronjob + Removed bad default value for adsync_dn option + Update wizard pages with new order option + Use Unix socket for LDAP connections on standalone and slave without PAM 2.1.5 + Manage zentyal-users cronjob with configuration keys for sync times instead of debian/lucid/zentyal-users.cron.d and src/scripts/ad-sync.cron + Configuration key to not to create homes (usefull on LDAP master servers) + New ad-sync-info to show info of ADsync configuration + Allow multiple BDC for ADsync mode with adsync_bdc confkey + Add ADsync service by default and move port value to a confkey + userInfo() tolerates missing quota LDAP attribute + Added captiveportal to the list of modules in the reinstall script 2.1.4 + Moved redis_port_usercorner key to usercorner.conf in zentyal-usercorner + Move users/conf/user-eboxlog.conf to usercorner/conf/usercorner-log.conf 2.1.3 + Fixed issues with html html attributes quotation + Allow to specify a base DN to bind to AD + Add locking to slave-sync to avoid spawn multiple instances in the event of not being able to connect to a slave + Do not modify users and groups in AD sync if attributes are not changed + Wipe ignored users in AD sync + Allow contacts synchronization in AD sync + New checks in AD sync to avoid warnings + Added update package list command to reinstall script 2.1.2 + Non-editable user fields in slaves no longer appear as editable inputs + Numeric 0 is accepted as value for LDAP users attributes + Minor fixes in default quota from user template + Fixed error when writing ad-sync cron file + Do not allow to create users if their home directory already exists 2.1.1 + Quotas are now included in users module + System users don't require password + Fixed bug that allowed to create LDAP users whith the same name than users with UID 0 (like root) 2.1 + Separate usercorner module to the new zentyal-usercorner package + Remove zentyal- prefix from rejoin-slave and ldapvi scripts + Move /usr/share/ebox-usersandgroups/ebox-usersandgroups/reinstall to /usr/share/zentyal-users/reinstall + Show enableActions for master also in ad-slave mode + Deleted obsolete migrations and use new initialSetup method + Added locks to prevent overlapping in ad-sync script + Fix slave failed operation string on slave hostname + Replace /etc/ebox/80users.conf with /etc/zentyal/users.conf + Added indexes for common LDAP attributes + Replace /var/log/ebox-usercorner with /var/log/zentyal-usercorner 2.0.10 + Now the AD synchronization can be disabled at any moment and a server with AD-slave mode can be master for other Zentyal slaves + New /etc/ebox/ad-sync_ignore.users and ad-sync_ignore.groups files to ignore users and groups in the AD synchronization process + Improved zentyal-ldapvi script that works on slave servers + Creates the default group if not exists during restore + Added restore backup precheck to assure there are not conflicts between system users and Zentyal LDAP users (currently only works for masters) 2.0.9 + Make sure to create the base directory for user homes before create them + Reconnect to LDAP on backup restore + Better log messages + Save configuration files during restore + Catch possible SIGPIPE on LDAP reconnect 2.0.8 + Fix Samba PDC on slaves + Check for incompatibility between Samba PDC and PAM on slaves + Optimize slave-sync script if there are no pending operations + Remove useless call to mode() on slave-sync script (faster now) + Replica LDAP listens in all interfaces 2.0.7 + Added index add mechanism to LdapModule + Fixed NSS DN config in masters 2.0.6 + Added zentyal-rejoin-slave to rejoin a slave to its master + Fixed NSS/PAM in slave machines 2.0.5 + Removed wrong hooks implementation 2.0.4 + Fixed infinite recursion when setting up some models on slave servers + Added support for addUser/delUser hooks 2.0.3 + Allow LDAP users and groups up to 128 characters + Show precondition message for user corner on slave servers + Unconfigure ftp and zarafa in reinstall script + Do not show adsync debug messages if debug is disabled in config + Allow more than one dot in usernames 2.0.2 + Fixed master/slave synchronization issues + Remove userjournal dir when removing a slave + Added lock during module enable to avoid initialization problems + Fixed AD slave synchronization task 2.0.1 + Fixed incorrect LDAP binding in some cases 2.0 + Fixed user journal dir creation on master + Fixed failed login error on user corner + Default login_shell under PAM Settings UI instead of 80users.conf + Replaced /bin/false with /usr/sbin/nologin as default shell 1.5.10 + Some refactorizations centered in safer LDAP connections and defensive code 1.5.9 + More info link added in wizard 1.5.8 + Zentyal rebrand 1.5.7 + Removed NSS in slave configurations + Nasty bug page replaced by the new eBox error page 1.5.6 + Fixed user corner access problems with redis server 1.5.5 + LDAP master creation optimized and less error-prone 1.5.4 + Bug fix: adding a user name with spaces no longer fails 1.5.3 + Move NSS from ebox-samba to ebox-usersandgroups + Home directories are under /home now + New options to configure shell and home directory umask + New setup wizard 1.5.2 + Bug fix: fixed dbus init for usercorner 1.5.1 + Bug fix: fixed nasty bug with the last version of openldap in lucid + Bug fix: do not call processDir if there are no slaves in slave-sync + Bug fix: ebox-usersandgroups-reinstall now unconfigures all ldap modules + Bug fix: updateSchema() returns unless the schema to update is available + Bug fix: Set proper owner and permissions when updating a schema + Bug fix: some problems with the AD synchronization solved + Bug fix: userscorner title icon + Bug fix: addUser() now checks if the user already exists as a system user + Removed deprecated executable 'import-from-ldif' + Bug fix: addUser() now checks for password argument + Bug fix: when restoring we use the new users DN to init users 1.5 + Bug fix: don't try to contact slaves from within a slave when groups are updated + Use built-in EBox::ThirdParty::Apache2::AuthCookie 1.4.2 + Bug fix: fix wrong migration number 1.4.1 + Bug fix: surround LDAP migration with a try/catch to make sure the rest it is run + Bug fix: do not allow \w with localized characters as LDAP schema does not allow them for home directory attribute. (Closes #1713) 1.4 + Allow the master to pass extra parameters in SOAP calls to slaves 1.3.17 + Bug fix: Set style for login page in user corner 1.3.16 + Bug fix: keep menu open on LDAP Info 1.3.15 + Add support for ldaps + Add support for slaves running Apache in ports different than 443 + Allow to remove slaves from slave list + Added ebox-usersandgroups-reinstall to easily reset the LDAP mode + Bug fix: issue with user deletion in French (Closes #1651) + Bug fix: anonymous connection for getting DN is retried several times, this fixes a bug when restoring configuration backup 1.3.14 + Synchronize all the users from the AD and not only from CN=Users + Add operation name and username on updateGroup + Add slave notification for group modify and delete + Change button order to "Add" and "Add and Edit" in Add User template. If users press return in the form it adds a new user and stays on the same page. 1.3.13 + Usability enhancements: (Closes #1649) * Create a unique Users And Group Folder * Unify Add User/Edit User in a single page * Unify Add Group/Edit Group in a single page * Two buttons: "Add and Edit" and "Add" * Add breadcrumbs + Add UserTemplate composite to configure default options that are used when a new user is created + Add defaultUserModel to LdapUserBase.pm + Specify folder for SlaveInfo + Add menu entry with information about LDAP including password + Change enableActions to use the new LDAP default structure from Karmic 1.3.12 + Add EBox::Ldap::lastModificationTime to know when the master LDAP database was modified for the last time + Index uid and memberUid to avoid some warnings and improve performance, plus remove some old code and fix some broken one in that part of the code + Bugfix: disable edition of users and groups in ad-slave mode + Don't allow modification of ldap password in Mode model if it has been autogenerated by the eBox installer + Add page title + Separate the Windows AD options in a different model + Fixed the warning of "Edit User" when there are no users in a slave + Remove 'optional' from remote in Mode and also useless validateRow 1.3.10 + Use disableApparmorProfile from EBox::Module::Service twice. First in enableActions. And also in setConf to avoid issues if apparmor is installed after users is enabled. 1.3.9 + Bugfix: return empty array in usedFiles if it's not master mode 1.3.8 + Bugfix: fixed wrong disable of fields in selecting ad-slave in Mode model 1.3.7 + Synchronization with Windows Active Directory (#1443) 1.3.6 + Use anonymous bind to fetch dn 1.3.5 + Disable slapd apparmor profile in enableActions + Reload nscd when adding users and groups + Bugfix: backup bug report now works again + Bugfix: slave-sync does not try to real journal dir when not configured or in slave mode. Journal dir created on master's setup. 1.3.0 + eBox LDAP architecture now supports a master-slave configuration + bugfix: Update usercorner service when there is a change on the port number 1.1.30 + Added widget to manage group belonging from Edit User page + Fixed backup/restore problem with paswords and given/last names + Changed the way users are stored in LDAP, added givenName in addition to sn, now cn=givenName+sn instead of cn=uid, this fixes a incompatibility bug with eGroupware + In the Edit User interface now Name and Last name are separate fields + Usercorner web server certificate can be changed via the CA module 1.1.20 + New release 1.1.10 + Make slapd listen only on 127.0.0.1 1.1 + Added bind v2 compability needed by squid auth, slapd conf regenerated and daemon restarted in postinst to commit possibles changes in configuration + Added group model + Use the new ids() and row() API to optimize the management of hundreds of users + Allow dashes in user and group names + Initial release of UserCorner which allow users to change their password + Store multiple password hashes and scrap clear text passwords 0.12.100 + Restore backup is more robust: inexistent users in a group are ignored + Make and restore backup more robust: removed slapd.conf parameters in both slapadd and slapcat invokations, so we can use the module with sldap with configuration in the directory itself 0.12.99 + New release 0.12.1 + Bugfix: Remove eBox system users when restoring backup. This solves an issue restoring backups from 0.12 0.12 + Use the new EBox::Model::Row api + Check if there is any added user and show a message in case there isn't any. + Restore users reading from ldiff and adding them through eBox API + Set password-hash in slapd.conf to make password changes from samba sync the user password 0.11.101 + New release 0.11.100 + onInstall() functionality moved to migration script + Fixed several typos 0.11.99 + Remove use of Apache::Singleton 0.11.3 + Check used uid's on every posixAccount object under dc=ebox, instead of only under ou=Users,dc=ebox. This solves nasty issues with Samba PDC when adding machines and creating users with repeated uid 0.11.2 + Do not generate a new LDAP password if it already exists 0.11.1 + Fix issue with module naming which prevented backups from being restored 0.11 + Initial Ubuntu packaging + bugfix. fix issue with module naming which prevented backups from being restored 0.10.99 + Create pseudo-model to use the users table with Ajax 0.10 + Allow dots in user names 0.9.100 + New release 0.9.99 + Bugfix in EBox::Ldap 0.9.3 + New release 0.9.2 + New release 0.9.1 + Make OpenLDAP listen on internal interfaces 0.9 + Added Polish translation + Added Aragonese translation + Added Dutch translation + Added German translation 0.8.99 + New release 0.8.1 + Minor workaround. Create slapd run directory in case it does not exist 0.8 + Fix message 0.7.99 + Add extended backup support for LDAP + Performance tuning to slapd + Some minor code improvements + Quota now allows unlimited space and i-nodes number 0.7.1 + Add delObjectclass (useful for ldap clean actions) + Detect and recover when ldap connection is broken (#25) + Make EBox::Ldap a singleton class + Initial factoring + Use of ebox-sudoers-friendly 0.7 + New public release 0.6 + Move to client + API documented using naturaldocs + Update install + Update debian scripts + Use new syntax to define ACLs for ldap + Add function to create system users + Move ldap db under ebox directory 0.5.2 + Fix some packaging issues 0.5.1 + Convert module to new menu system 0.5 + Initial release zentyal-users-2.3.15+quantal1/AUTHORS0000664000000000000000000000024012017154745014113 0ustar Copyright (C) 2004-2012 eBox Technologies S.L. For an updated list of the current and past developers please visit: http://trac.zentyal.org/wiki/Contributors zentyal-users-2.3.15+quantal1/schemas/0000775000000000000000000000000012017154745014472 5ustar zentyal-users-2.3.15+quantal1/schemas/rfc2307bis.ldif0000664000000000000000000003330712017154745017124 0ustar # ################################################################################ # dn: cn=rfc2307bis,cn=schema,cn=config objectClass: olcSchemaConfig cn: rfc2307bis # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.2 NAME 'gecos' DESC 'The GECOS field; the common name' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.3 NAME 'homeDirectory' DESC 'The absolute path to the home directory' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.4 NAME 'loginShell' DESC 'The path to the login shell' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.6 NAME 'shadowMin' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.7 NAME 'shadowMax' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.8 NAME 'shadowWarning' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.9 NAME 'shadowInactive' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.10 NAME 'shadowExpire' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.11 NAME 'shadowFlag' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.12 NAME 'memberUid' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple' DESC 'Netgroup triple' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.15 NAME 'ipServicePort' DESC 'Service port number' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol' DESC 'Service protocol name' SUP name ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber' DESC 'IP protocol number' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber' DESC 'ONC RPC number' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber' DESC 'IPv4 addresses as a dotted decimal omitting leading zeros or IPv6 addresses as defined in RFC2373' SUP name ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber' DESC 'IP network as a dotted decimal, eg. 192.168, omitting leading zeros' SUP name SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber' DESC 'IP netmask as a dotted decimal, eg. 255.255.255.0, omitting leading zeros' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.22 NAME 'macAddress' DESC 'MAC address in maximal, colon separated hex notation, eg. 00:00:92:90:ee:e2' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.23 NAME 'bootParameter' DESC 'rpc.bootparamd parameter' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.24 NAME 'bootFile' DESC 'Boot image name' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.26 NAME 'nisMapName' DESC 'Name of a A generic NIS map' SUP name ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry' DESC 'A generic NIS entry' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.28 NAME 'nisPublicKey' DESC 'NIS public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.29 NAME 'nisSecretKey' DESC 'NIS secret key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.30 NAME 'nisDomain' DESC 'NIS domain' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.31 NAME 'automountMapName' DESC 'automount Map Name' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.32 NAME 'automountKey' DESC 'Automount Key value' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) # ################################################################################ # olcAttributeTypes: ( 1.3.6.1.1.1.1.33 NAME 'automountInformation' DESC 'Automount information' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' DESC 'Abstraction of an account with POSIX attributes' SUP top AUXILIARY MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory ) MAY ( userPassword $ loginShell $ gecos $ description ) ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' DESC 'Additional attributes for shadow passwords' SUP top AUXILIARY MUST uid MAY ( userPassword $ description $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag ) ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.2 NAME 'posixGroup' DESC 'Abstraction of a group of accounts' SUP top AUXILIARY MUST gidNumber MAY ( userPassword $ memberUid $ description ) ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.3 NAME 'ipService' DESC 'Abstraction an Internet Protocol service. Maps an IP port and protocol (such as tcp or udp) to one or more names; the distinguished value of the cn attribute denotes the services canonical name' SUP top STRUCTURAL MUST ( cn $ ipServicePort $ ipServiceProtocol ) MAY description ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' DESC 'Abstraction of an IP protocol. Maps a protocol number to one or more names. The distinguished value of the cn attribute denotes the protocols canonical name' SUP top STRUCTURAL MUST ( cn $ ipProtocolNumber ) MAY description ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.5 NAME 'oncRpc' DESC 'Abstraction of an Open Network Computing (ONC) [RFC1057] Remote Procedure Call (RPC) binding. This class maps an ONC RPC number to a name. The distinguished value of the cn attribute denotes the RPC services canonical name' SUP top STRUCTURAL MUST ( cn $ oncRpcNumber ) MAY description ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.6 NAME 'ipHost' DESC 'Abstraction of a host, an IP device. The distinguished value of the cn attribute denotes the hosts canonical name. Device SHOULD be used as a structural class' SUP top AUXILIARY MUST ( cn $ ipHostNumber ) MAY ( userPassword $ l $ description $ manager ) ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' DESC 'Abstraction of a network. The distinguished value of the cn attribute denotes the networks canonical name' SUP top STRUCTURAL MUST ipNetworkNumber MAY ( cn $ ipNetmaskNumber $ l $ description $ manager ) ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' DESC 'Abstraction of a netgroup. May refer to other netgroups' SUP top STRUCTURAL MUST cn MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.9 NAME 'nisMap' DESC 'A generic abstraction of a NIS map' SUP top STRUCTURAL MUST nisMapName MAY description ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.10 NAME 'nisObject' DESC 'An entry in a NIS map' SUP top STRUCTURAL MUST ( cn $ nisMapEntry $ nisMapName ) MAY description ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.11 NAME 'ieee802Device' DESC 'A device with a MAC address; device SHOULD be used as a structural class' SUP top AUXILIARY MAY macAddress ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.12 NAME 'bootableDevice' DESC 'A device with boot parameters; device SHOULD be used as a structural class' SUP top AUXILIARY MAY ( bootFile $ bootParameter ) ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.14 NAME 'nisKeyObject' DESC 'An object with a public and secret key' SUP top AUXILIARY MUST ( cn $ nisPublicKey $ nisSecretKey ) MAY ( uidNumber $ description ) ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.15 NAME 'nisDomainObject' DESC 'Associates a NIS domain with a naming context' SUP top AUXILIARY MUST nisDomain ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.16 NAME 'automountMap' SUP top STRUCTURAL MUST ( automountMapName ) MAY description ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.1.1.2.17 NAME 'automount' DESC 'Automount information' SUP top STRUCTURAL MUST ( automountKey $ automountInformation ) MAY description ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.4.1.5322.13.1.1 NAME 'namedObject' SUP top STRUCTURAL MAY cn ) # ################################################################################ # olcObjectClasses: ( 1.3.6.1.4.1.98546.1.2.3 NAME 'zentyalGroup' DESC 'Zentyal group' SUP top STRUCTURAL MUST cn MAY ( member $ description $ owner ) ) zentyal-users-2.3.15+quantal1/schemas/quota.ldif0000664000000000000000000000062712017154745016470 0ustar dn: cn=quota,cn=schema,cn=config objectClass: olcSchemaConfig cn: quota olcAttributeTypes: ( 1.3.6.1.4.1.19937.1.1.1 NAME 'quota' DESC 'Quotas (Fil eSystem:BlocksSoft,BlocksHard,InodesSoft,InodesHard)' EQUALITY caseIgnoreIA5M atch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) olcObjectClasses: ( 1.3.6.1.4.1.19937.1.2.1 NAME 'systemQuotas' DESC 'Syste m Quotas' SUP posixAccount AUXILIARY MUST uid MAY quota ) zentyal-users-2.3.15+quantal1/schemas/quota.schema0000664000000000000000000000105012017154745017001 0ustar ## ## schema file for Unix Quotas ## Schema for storing Unix Quotas in LDAP ## OIDs are owned by Cogent Innovators, LLC ## ## 1.3.6.1.4.1.19937.1.1.x - attributetypes ## 1.3.6.1.4.1.19937.1.2.x - objectclasses ## attributetype ( 1.3.6.1.4.1.19937.1.1.1 NAME 'quota' DESC 'Quotas (FileSystem:BlocksSoft,BlocksHard,InodesSoft,InodesHard)' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} ) objectclass ( 1.3.6.1.4.1.19937.1.2.1 NAME 'systemQuotas' SUP posixAccount AUXILIARY DESC 'System Quotas' MUST ( uid ) MAY ( quota )) zentyal-users-2.3.15+quantal1/schemas/rfc2307bis.schema0000664000000000000000000002251512017154745017445 0ustar # builtin # #attributetype ( 1.3.6.1.1.1.1.0 NAME 'uidNumber' # DESC 'An integer uniquely identifying a user in an administrative domain' # EQUALITY integerMatch # SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 # SINGLE-VALUE ) # builtin # #attributetype ( 1.3.6.1.1.1.1.1 NAME 'gidNumber' # DESC 'An integer uniquely identifying a group in an # administrative domain' # EQUALITY integerMatch # SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 # SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.2 NAME 'gecos' DESC 'The GECOS field; the common name' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.3 NAME 'homeDirectory' DESC 'The absolute path to the home directory' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.4 NAME 'loginShell' DESC 'The path to the login shell' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.6 NAME 'shadowMin' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.7 NAME 'shadowMax' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.8 NAME 'shadowWarning' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.9 NAME 'shadowInactive' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.10 NAME 'shadowExpire' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.11 NAME 'shadowFlag' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.12 NAME 'memberUid' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple' DESC 'Netgroup triple' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.1.1.1.15 NAME 'ipServicePort' DESC 'Service port number' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol' DESC 'Service protocol name' SUP name ) attributetype ( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber' DESC 'IP protocol number' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber' DESC 'ONC RPC number' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber' DESC 'IPv4 addresses as a dotted decimal omitting leading zeros or IPv6 addresses as defined in RFC2373' SUP name ) attributetype ( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber' DESC 'IP network as a dotted decimal, eg. 192.168, omitting leading zeros' SUP name SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber' DESC 'IP netmask as a dotted decimal, eg. 255.255.255.0, omitting leading zeros' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.22 NAME 'macAddress' DESC 'MAC address in maximal, colon separated hex notation, eg. 00:00:92:90:ee:e2' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.1.1.1.23 NAME 'bootParameter' DESC 'rpc.bootparamd parameter' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.1.1.1.24 NAME 'bootFile' DESC 'Boot image name' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.1.1.1.26 NAME 'nisMapName' DESC 'Name of a A generic NIS map' SUP name ) attributetype ( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry' DESC 'A generic NIS entry' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.28 NAME 'nisPublicKey' DESC 'NIS public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.29 NAME 'nisSecretKey' DESC 'NIS secret key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.30 NAME 'nisDomain' DESC 'NIS domain' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26) attributetype ( 1.3.6.1.1.1.1.31 NAME 'automountMapName' DESC 'automount Map Name' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.32 NAME 'automountKey' DESC 'Automount Key value' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.3.6.1.1.1.1.33 NAME 'automountInformation' DESC 'Automount information' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' SUP top AUXILIARY DESC 'Abstraction of an account with POSIX attributes' MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory ) MAY ( userPassword $ loginShell $ gecos $ description ) ) objectclass ( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' SUP top AUXILIARY DESC 'Additional attributes for shadow passwords' MUST uid MAY ( userPassword $ description $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag ) ) objectclass ( 1.3.6.1.1.1.2.2 NAME 'posixGroup' SUP top AUXILIARY DESC 'Abstraction of a group of accounts' MUST gidNumber MAY ( userPassword $ memberUid $ description ) ) objectclass ( 1.3.6.1.1.1.2.3 NAME 'ipService' SUP top STRUCTURAL DESC 'Abstraction an Internet Protocol service. Maps an IP port and protocol (such as tcp or udp) to one or more names; the distinguished value of the cn attribute denotes the services canonical name' MUST ( cn $ ipServicePort $ ipServiceProtocol ) MAY description ) objectclass ( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' SUP top STRUCTURAL DESC 'Abstraction of an IP protocol. Maps a protocol number to one or more names. The distinguished value of the cn attribute denotes the protocols canonical name' MUST ( cn $ ipProtocolNumber ) MAY description ) objectclass ( 1.3.6.1.1.1.2.5 NAME 'oncRpc' SUP top STRUCTURAL DESC 'Abstraction of an Open Network Computing (ONC) [RFC1057] Remote Procedure Call (RPC) binding. This class maps an ONC RPC number to a name. The distinguished value of the cn attribute denotes the RPC services canonical name' MUST ( cn $ oncRpcNumber ) MAY description ) objectclass ( 1.3.6.1.1.1.2.6 NAME 'ipHost' SUP top AUXILIARY DESC 'Abstraction of a host, an IP device. The distinguished value of the cn attribute denotes the hosts canonical name. Device SHOULD be used as a structural class' MUST ( cn $ ipHostNumber ) MAY ( userPassword $ l $ description $ manager ) ) objectclass ( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' SUP top STRUCTURAL DESC 'Abstraction of a network. The distinguished value of the cn attribute denotes the networks canonical name' MUST ipNetworkNumber MAY ( cn $ ipNetmaskNumber $ l $ description $ manager ) ) objectclass ( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL DESC 'Abstraction of a netgroup. May refer to other netgroups' MUST cn MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) ) objectclass ( 1.3.6.1.1.1.2.9 NAME 'nisMap' SUP top STRUCTURAL DESC 'A generic abstraction of a NIS map' MUST nisMapName MAY description ) objectclass ( 1.3.6.1.1.1.2.10 NAME 'nisObject' SUP top STRUCTURAL DESC 'An entry in a NIS map' MUST ( cn $ nisMapEntry $ nisMapName ) MAY description ) objectclass ( 1.3.6.1.1.1.2.11 NAME 'ieee802Device' SUP top AUXILIARY DESC 'A device with a MAC address; device SHOULD be used as a structural class' MAY macAddress ) objectclass ( 1.3.6.1.1.1.2.12 NAME 'bootableDevice' SUP top AUXILIARY DESC 'A device with boot parameters; device SHOULD be used as a structural class' MAY ( bootFile $ bootParameter ) ) objectclass ( 1.3.6.1.1.1.2.14 NAME 'nisKeyObject' SUP top AUXILIARY DESC 'An object with a public and secret key' MUST ( cn $ nisPublicKey $ nisSecretKey ) MAY ( uidNumber $ description ) ) objectclass ( 1.3.6.1.1.1.2.15 NAME 'nisDomainObject' SUP top AUXILIARY DESC 'Associates a NIS domain with a naming context' MUST nisDomain ) objectclass ( 1.3.6.1.1.1.2.16 NAME 'automountMap' SUP top STRUCTURAL MUST ( automountMapName ) MAY description ) objectclass ( 1.3.6.1.1.1.2.17 NAME 'automount' SUP top STRUCTURAL DESC 'Automount information' MUST ( automountKey $ automountInformation ) MAY description ) ## namedObject is needed for groups without members objectclass ( 1.3.6.1.4.1.5322.13.1.1 NAME 'namedObject' SUP top STRUCTURAL MAY cn ) zentyal-users-2.3.15+quantal1/schemas/kerberos.ldif0000664000000000000000000002206212017154745017150 0ustar dn: cn=kerberos,cn=schema,cn=config objectClass: olcSchemaConfig cn: kerberos olcAttributeTypes: {0}( 2.16.840.1.113719.1.301.4.1.1 NAME 'krbPrincipalName' EQUALITY caseExactIA5Match SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1 .1466.115.121.1.26 ) olcAttributeTypes: {1}( 1.2.840.113554.1.4.1.6.1 NAME 'krbCanonicalName' EQUAL ITY caseExactIA5Match SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4.1.1466 .115.121.1.26 SINGLE-VALUE ) olcAttributeTypes: {2}( 2.16.840.1.113719.1.301.4.3.1 NAME 'krbPrincipalType' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {3}( 2.16.840.1.113719.1.301.4.5.1 NAME 'krbUPEnabled' DESC 'Boolean' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE ) olcAttributeTypes: {4}( 2.16.840.1.113719.1.301.4.6.1 NAME 'krbPrincipalExpira tion' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SING LE-VALUE ) olcAttributeTypes: {5}( 2.16.840.1.113719.1.301.4.8.1 NAME 'krbTicketFlags' EQ UALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {6}( 2.16.840.1.113719.1.301.4.9.1 NAME 'krbMaxTicketLife' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {7}( 2.16.840.1.113719.1.301.4.10.1 NAME 'krbMaxRenewableAg e' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {8}( 2.16.840.1.113719.1.301.4.14.1 NAME 'krbRealmReference s' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) olcAttributeTypes: {9}( 2.16.840.1.113719.1.301.4.15.1 NAME 'krbLdapServers' E QUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) olcAttributeTypes: {10}( 2.16.840.1.113719.1.301.4.17.1 NAME 'krbKdcServers' E QUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) olcAttributeTypes: {11}( 2.16.840.1.113719.1.301.4.18.1 NAME 'krbPwdServers' E QUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) olcAttributeTypes: {12}( 2.16.840.1.113719.1.301.4.24.1 NAME 'krbHostServer' E QUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) olcAttributeTypes: {13}( 2.16.840.1.113719.1.301.4.25.1 NAME 'krbSearchScope' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {14}( 2.16.840.1.113719.1.301.4.26.1 NAME 'krbPrincipalRefe rences' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) olcAttributeTypes: {15}( 2.16.840.1.113719.1.301.4.28.1 NAME 'krbPrincNamingAt tr' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALU E ) olcAttributeTypes: {16}( 2.16.840.1.113719.1.301.4.29.1 NAME 'krbAdmServers' E QUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) olcAttributeTypes: {17}( 2.16.840.1.113719.1.301.4.30.1 NAME 'krbMaxPwdLife' E QUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {18}( 2.16.840.1.113719.1.301.4.31.1 NAME 'krbMinPwdLife' E QUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {19}( 2.16.840.1.113719.1.301.4.32.1 NAME 'krbPwdMinDiffCha rs' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {20}( 2.16.840.1.113719.1.301.4.33.1 NAME 'krbPwdMinLength' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {21}( 2.16.840.1.113719.1.301.4.34.1 NAME 'krbPwdHistoryLen gth' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {22}( 1.3.6.1.4.1.5322.21.2.1 NAME 'krbPwdMaxFailure' EQUAL ITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {23}( 1.3.6.1.4.1.5322.21.2.2 NAME 'krbPwdFailureCountInter val' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {24}( 1.3.6.1.4.1.5322.21.2.3 NAME 'krbPwdLockoutDuration' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {25}( 2.16.840.1.113719.1.301.4.36.1 NAME 'krbPwdPolicyRefe rence' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 S INGLE-VALUE ) olcAttributeTypes: {26}( 2.16.840.1.113719.1.301.4.37.1 NAME 'krbPasswordExpir ation' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SIN GLE-VALUE ) olcAttributeTypes: {27}( 2.16.840.1.113719.1.301.4.39.1 NAME 'krbPrincipalKey' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) olcAttributeTypes: {28}( 2.16.840.1.113719.1.301.4.40.1 NAME 'krbTicketPolicyR eference' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.1 2 SINGLE-VALUE ) olcAttributeTypes: {29}( 2.16.840.1.113719.1.301.4.41.1 NAME 'krbSubTrees' EQU ALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) olcAttributeTypes: {30}( 2.16.840.1.113719.1.301.4.42.1 NAME 'krbDefaultEncSal tTypes' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) olcAttributeTypes: {31}( 2.16.840.1.113719.1.301.4.43.1 NAME 'krbSupportedEncS altTypes' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) olcAttributeTypes: {32}( 2.16.840.1.113719.1.301.4.44.1 NAME 'krbPwdHistory' E QUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) olcAttributeTypes: {33}( 2.16.840.1.113719.1.301.4.45.1 NAME 'krbLastPwdChange ' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-V ALUE ) olcAttributeTypes: {34}( 1.3.6.1.4.1.5322.21.2.5 NAME 'krbLastAdminUnlock' EQU ALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE ) olcAttributeTypes: {35}( 2.16.840.1.113719.1.301.4.46.1 NAME 'krbMKey' EQUALIT Y octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) olcAttributeTypes: {36}( 2.16.840.1.113719.1.301.4.47.1 NAME 'krbPrincipalAlia ses' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) olcAttributeTypes: {37}( 2.16.840.1.113719.1.301.4.48.1 NAME 'krbLastSuccessfu lAuth' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SIN GLE-VALUE ) olcAttributeTypes: {38}( 2.16.840.1.113719.1.301.4.49.1 NAME 'krbLastFailedAut h' EQUALITY generalizedTimeMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE- VALUE ) olcAttributeTypes: {39}( 2.16.840.1.113719.1.301.4.50.1 NAME 'krbLoginFailedCo unt' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {40}( 2.16.840.1.113719.1.301.4.51.1 NAME 'krbExtraData' EQ UALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) olcAttributeTypes: {41}( 2.16.840.1.113719.1.301.4.52.1 NAME 'krbObjectReferen ces' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) olcAttributeTypes: {42}( 2.16.840.1.113719.1.301.4.53.1 NAME 'krbPrincContaine rRef' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 ) olcAttributeTypes: {43}( 1.3.6.1.4.1.5322.21.2.4 NAME 'krbAllowedToDelegateTo' EQUALITY caseExactIA5Match SUBSTR caseExactSubstringsMatch SYNTAX 1.3.6.1.4. 1.1466.115.121.1.26 ) olcObjectClasses: {0}( 2.16.840.1.113719.1.301.6.1.1 NAME 'krbContainer' SUP t op STRUCTURAL MUST cn ) olcObjectClasses: {1}( 2.16.840.1.113719.1.301.6.2.1 NAME 'krbRealmContainer' SUP top STRUCTURAL MUST cn MAY ( krbMKey $ krbUPEnabled $ krbSubTrees $ krbSe archScope $ krbLdapServers $ krbSupportedEncSaltTypes $ krbDefaultEncSaltType s $ krbTicketPolicyReference $ krbKdcServers $ krbPwdServers $ krbAdmServers $ krbPrincNamingAttr $ krbPwdPolicyReference $ krbPrincContainerRef ) ) olcObjectClasses: {2}( 2.16.840.1.113719.1.301.6.3.1 NAME 'krbService' SUP top ABSTRACT MUST cn MAY ( krbHostServer $ krbRealmReferences ) ) olcObjectClasses: {3}( 2.16.840.1.113719.1.301.6.4.1 NAME 'krbKdcService' SUP krbService STRUCTURAL ) olcObjectClasses: {4}( 2.16.840.1.113719.1.301.6.5.1 NAME 'krbPwdService' SUP krbService STRUCTURAL ) olcObjectClasses: {5}( 2.16.840.1.113719.1.301.6.8.1 NAME 'krbPrincipalAux' SU P top AUXILIARY MAY ( krbPrincipalName $ krbCanonicalName $ krbUPEnabled $ kr bPrincipalKey $ krbTicketPolicyReference $ krbPrincipalExpiration $ krbPasswo rdExpiration $ krbPwdPolicyReference $ krbPrincipalType $ krbPwdHistory $ krb LastPwdChange $ krbLastAdminUnlock $ krbPrincipalAliases $ krbLastSuccessfulA uth $ krbLastFailedAuth $ krbLoginFailedCount $ krbExtraData $ krbAllowedToDe legateTo ) ) olcObjectClasses: {6}( 2.16.840.1.113719.1.301.6.9.1 NAME 'krbPrincipal' SUP t op STRUCTURAL MUST krbPrincipalName MAY krbObjectReferences ) olcObjectClasses: {7}( 2.16.840.1.113719.1.301.6.11.1 NAME 'krbPrincRefAux' SU P top AUXILIARY MAY krbPrincipalReferences ) olcObjectClasses: {8}( 2.16.840.1.113719.1.301.6.13.1 NAME 'krbAdmService' SUP krbService STRUCTURAL ) olcObjectClasses: {9}( 2.16.840.1.113719.1.301.6.14.1 NAME 'krbPwdPolicy' SUP top STRUCTURAL MUST cn MAY ( krbMaxPwdLife $ krbMinPwdLife $ krbPwdMinDiffCha rs $ krbPwdMinLength $ krbPwdHistoryLength $ krbPwdMaxFailure $ krbPwdFailure CountInterval $ krbPwdLockoutDuration ) ) olcObjectClasses: {10}( 2.16.840.1.113719.1.301.6.16.1 NAME 'krbTicketPolicyAu x' SUP top AUXILIARY MAY ( krbTicketFlags $ krbMaxTicketLife $ krbMaxRenewabl eAge ) ) olcObjectClasses: {11}( 2.16.840.1.113719.1.301.6.17.1 NAME 'krbTicketPolicy' SUP top STRUCTURAL MUST cn ) zentyal-users-2.3.15+quantal1/schemas/smbk5pwd_module.ldif0000664000000000000000000000013712017154745020434 0ustar dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: {1}smbk5pwd.so zentyal-users-2.3.15+quantal1/schemas/passwords.ldif0000664000000000000000000000235512017154745017364 0ustar dn: cn=passwords,cn=schema,cn=config objectClass: olcSchemaConfig cn: passwords olcAttributeTypes: ( 1.3.6.1.4.1.31607.2.1.6.1.1 NAME 'eboxMd5Password' EQU ALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) olcAttributeTypes: ( 1.3.6.1.4.1.31607.2.1.6.1.2 NAME 'eboxSha1Password' EQ UALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) olcAttributeTypes: ( 1.3.6.1.4.1.31607.2.1.6.1.3 NAME 'eboxLmPassword' EQUA LITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) olcAttributeTypes: ( 1.3.6.1.4.1.31607.2.1.6.1.4 NAME 'eboxNtPassword' DESC 'NT Passwd' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) olcAttributeTypes: ( 1.3.6.1.4.1.31607.2.1.6.1.5 NAME 'eboxDigestPassword' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) olcAttributeTypes: ( 1.3.6.1.4.1.31607.2.1.6.1.6 NAME 'eboxRealmPassword' E QUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) olcObjectClasses: ( 1.3.6.1.4.1.31607.2.1.6.2.1 NAME 'passwordHolder' DESC 'Abstraction for holding several passwords in different formats' SUP top AUXI LIARY MAY ( eBoxMd5Password $ eBoxSha1Password $ eBoxLmPassword $ eBoxNtPassw ord $ eboxDigestPassword $ eboxRealmPassword ) ) zentyal-users-2.3.15+quantal1/schemas/heimdal.ldif0000664000000000000000000000503412017154745016737 0ustar # AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. # CRC32 183e7df4 dn: cn=hdb,cn=schema,cn=config objectClass: olcSchemaConfig cn: hdb olcAttributeTypes: {0}( 1.3.6.1.4.1.5322.10.1.1 NAME 'krb5PrincipalName' DESC 'The unparsed Kerberos principal name' EQUALITY caseIgnoreIA5Match SYNTAX 1.3 .6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) olcAttributeTypes: {1}( 1.3.6.1.4.1.5322.10.1.2 NAME 'krb5KeyVersionNumber' EQ UALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {2}( 1.3.6.1.4.1.5322.10.1.3 NAME 'krb5MaxLife' EQUALITY in tegerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {3}( 1.3.6.1.4.1.5322.10.1.4 NAME 'krb5MaxRenew' EQUALITY i ntegerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {4}( 1.3.6.1.4.1.5322.10.1.5 NAME 'krb5KDCFlags' EQUALITY i ntegerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) olcAttributeTypes: {5}( 1.3.6.1.4.1.5322.10.1.6 NAME 'krb5EncryptionType' EQUA LITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ) olcAttributeTypes: {6}( 1.3.6.1.4.1.5322.10.1.7 NAME 'krb5ValidStart' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4. 1.1466.115.121.1.24 SINGLE-VALUE ) olcAttributeTypes: {7}( 1.3.6.1.4.1.5322.10.1.8 NAME 'krb5ValidEnd' EQUALITY g eneralizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1. 1466.115.121.1.24 SINGLE-VALUE ) olcAttributeTypes: {8}( 1.3.6.1.4.1.5322.10.1.9 NAME 'krb5PasswordEnd' EQUALIT Y generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4 .1.1466.115.121.1.24 SINGLE-VALUE ) olcAttributeTypes: {9}( 1.3.6.1.4.1.5322.10.1.10 NAME 'krb5Key' DESC 'Encoded ASN1 Key as an octet string' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 ) olcAttributeTypes: {10}( 1.3.6.1.4.1.5322.10.1.11 NAME 'krb5PrincipalRealm' DE SC 'Distinguished name of krb5Realm entry' SUP distinguishedName ) olcAttributeTypes: {11}( 1.3.6.1.4.1.5322.10.1.12 NAME 'krb5RealmName' EQUALIT Y octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} ) olcObjectClasses: {0}( 1.3.6.1.4.1.5322.10.2.1 NAME 'krb5Principal' SUP top AU XILIARY MUST krb5PrincipalName MAY ( cn $ krb5PrincipalRealm ) ) olcObjectClasses: {1}( 1.3.6.1.4.1.5322.10.2.2 NAME 'krb5KDCEntry' SUP krb5Pri ncipal AUXILIARY MUST krb5KeyVersionNumber MAY ( krb5ValidStart $ krb5ValidEn d $ krb5PasswordEnd $ krb5MaxLife $ krb5MaxRenew $ krb5KDCFlags $ krb5Encrypt ionType $ krb5Key ) ) olcObjectClasses: {2}( 1.3.6.1.4.1.5322.10.2.3 NAME 'krb5Realm' SUP top AUXILI ARY MUST krb5RealmName ) zentyal-users-2.3.15+quantal1/schemas/smbk5pwd_overlay.ldif0000664000000000000000000000032612017154745020630 0ustar dn: olcOverlay={0}smbk5pwd,olcDatabase={1}hdb,cn=config objectClass: olcOverlayConfig objectClass: olcSmbK5PwdConfig olcOverlay: {0}smbk5pwd olcSmbK5PwdEnable: krb5 olcSmbK5PwdMustChange: 0 olcSmbK5PwdCanChange: 0 zentyal-users-2.3.15+quantal1/schemas/users.yaml0000664000000000000000000000063212017154745016520 0ustar class: 'EBox::UsersAndGroups' enabledepends: - dns - ntp models: - Mode - Users - Groups - Password - LdapInfo - PAM - AccountSettings - OUs - Slaves - Master - SlavePassword composites: Settings: [LdapInfo, PAM] Sync: [Master, SlavePassword, Slaves] UserTemplate: [] # NOTE: UserTemplate composite components are dynamic in componentNames()