From beb2263461a0250050e07e5d0c3e3f978317fe35 Mon Sep 17 00:00:00 2001 From: geos_one Date: Fri, 8 Aug 2025 20:28:57 +0200 Subject: [PATCH] New upstream version 2.1.3 --- .gitignore | 20 + AUTHORS | 6 + CONTRIB | 81 + COPYING | 340 ++++ ChangeLog | 690 ++++++++ INSTALL | 116 ++ Makefile | 95 ++ README.md | 77 + VERSION | 1 + conf/acls/README | 32 + conf/acls/all | 17 + conf/acls/dim | 7 + conf/acls/odmin | 8 + conf/acls/sveta | 8 + conf/acls/users | 3 + conf/conf.d/00-general.conf | 12 + conf/conf.d/01-auth.conf | 25 + conf/conf.d/02-restriction.conf | 109 ++ conf/conf.d/03-logging.conf | 24 + conf/conf.d/04-balancing.conf | 31 + conf/conf.d/05-sound.conf | 1 + conf/conf.d/06-path.conf | 116 ++ conf/conf.d/07-misc.conf | 42 + conf/conf.d/08-bash.conf | 11 + conf/conf.d/09-cups.conf | 26 + conf/conf.d/10-samba.conf | 16 + conf/conf.d/11-nxagent.conf | 10 + conf/conf.d/12-nxproxy.conf | 10 + conf/conf.d/50-numlockx.conf | 8 + conf/node.conf | 1 + data/99-debian-dimbor.conf | 22 + data/Xkbmap | 2 + data/Xsession | 222 +++ data/fixkeyboard | 19 + data/logrotate | 8 + data/sudoers.conf | 11 + data/terminate-suspend-nx.sh | 22 + debian/README.Debian | 8 + debian/changelog | 37 + debian/compat | 1 + debian/control | 36 + debian/copyright | 347 ++++ debian/freenx-server.postinst | 49 + debian/rules | 6 + debian/source/format | 1 + dists/alt/99-altlinux.conf | 4 + dists/alt/rx-etersoft.spec | 440 +++++ dists/gentoo/files/70-gentoo.conf | 14 + .../nxserver-freenx-0.7.4-nxloadconfig.patch | 68 + .../files/nxserver-freenx-0.7.4-pam_ssh.patch | 10 + dists/gentoo/gentoo.postinst | 7 + .../gentoo/nxserver-freenx-0.7.4-r665.ebuild | 162 ++ node.conf.def/00--internal.cnf | 62 + node.conf.def/00-general.conf | 15 + node.conf.def/01-auth.conf | 28 + node.conf.def/02-restriction.conf | 129 ++ node.conf.def/03-logging.conf | 29 + node.conf.def/04-balancing.conf | 39 + node.conf.def/05-sound.conf | 1 + node.conf.def/06-path.conf | 186 ++ node.conf.def/07-misc.conf | 57 + node.conf.def/08-bash.conf | 14 + node.conf.def/09-cups.conf | 44 + node.conf.def/10-samba.conf | 19 + node.conf.def/11-nxagent.conf | 13 + node.conf.def/12-nxproxy.conf | 12 + node.conf.def/50-numlockx.conf | 12 + node.conf.def/README | 2 + nx-session-launcher/ConsoleKit-NX.conf | 26 + nx-session-launcher/Makefile | 17 + nx-session-launcher/README | 12 + nx-session-launcher/freenx.session.policy | 19 + nx-session-launcher/nx-session-launcher | 170 ++ .../nx-session-launcher-suid.c | 54 + nxcheckload.sample | 67 + nxdialog.freenx | 298 ++++ nxfuncs | 437 +++++ nxkeygen | 85 + nxnode | 1487 ++++++++++++++++ nxnode-login | 105 ++ nxredir/Makefile | 29 + nxredir/nxredir | 21 + nxredir/nxredir.c | 116 ++ nxredir/nxsmb | 45 + nxserver | 1515 +++++++++++++++++ nxsetup | 814 +++++++++ nxviewer-passwd/COPYING | 340 ++++ nxviewer-passwd/Imakefile | 35 + nxviewer-passwd/README | 8 + nxviewer-passwd/WhatsNew.TIGHTVNC.original | 566 ++++++ nxviewer-passwd/include/rfbproto.h | 907 ++++++++++ nxviewer-passwd/include/vncauth.h | 30 + nxviewer-passwd/libvncauth/Imakefile | 14 + nxviewer-passwd/libvncauth/d3des.c | 440 +++++ nxviewer-passwd/libvncauth/d3des.h | 51 + nxviewer-passwd/libvncauth/vncauth.c | 247 +++ nxviewer-passwd/nxpasswd/Imakefile | 13 + nxviewer-passwd/nxpasswd/nxpasswd.man | 87 + nxviewer-passwd/nxpasswd/vncpasswd.c | 301 ++++ .../nxpasswd/vncpasswd.c.NX.original | 301 ++++ .../nxpasswd/vncpasswd.c.TIGHTVNC.original | 286 ++++ 101 files changed, 13044 insertions(+) create mode 100644 .gitignore create mode 100644 AUTHORS create mode 100644 CONTRIB create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile create mode 100644 README.md create mode 100644 VERSION create mode 100644 conf/acls/README create mode 100644 conf/acls/all create mode 100644 conf/acls/dim create mode 100644 conf/acls/odmin create mode 100644 conf/acls/sveta create mode 100644 conf/acls/users create mode 100644 conf/conf.d/00-general.conf create mode 100644 conf/conf.d/01-auth.conf create mode 100644 conf/conf.d/02-restriction.conf create mode 100644 conf/conf.d/03-logging.conf create mode 100644 conf/conf.d/04-balancing.conf create mode 100644 conf/conf.d/05-sound.conf create mode 100644 conf/conf.d/06-path.conf create mode 100644 conf/conf.d/07-misc.conf create mode 100644 conf/conf.d/08-bash.conf create mode 100644 conf/conf.d/09-cups.conf create mode 100644 conf/conf.d/10-samba.conf create mode 100644 conf/conf.d/11-nxagent.conf create mode 100644 conf/conf.d/12-nxproxy.conf create mode 100644 conf/conf.d/50-numlockx.conf create mode 100644 conf/node.conf create mode 100644 data/99-debian-dimbor.conf create mode 100644 data/Xkbmap create mode 100755 data/Xsession create mode 100755 data/fixkeyboard create mode 100644 data/logrotate create mode 100644 data/sudoers.conf create mode 100755 data/terminate-suspend-nx.sh create mode 100644 debian/README.Debian create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/freenx-server.postinst create mode 100755 debian/rules create mode 100644 debian/source/format create mode 100644 dists/alt/99-altlinux.conf create mode 100644 dists/alt/rx-etersoft.spec create mode 100644 dists/gentoo/files/70-gentoo.conf create mode 100644 dists/gentoo/files/nxserver-freenx-0.7.4-nxloadconfig.patch create mode 100644 dists/gentoo/files/nxserver-freenx-0.7.4-pam_ssh.patch create mode 100755 dists/gentoo/gentoo.postinst create mode 100644 dists/gentoo/nxserver-freenx-0.7.4-r665.ebuild create mode 100644 node.conf.def/00--internal.cnf create mode 100644 node.conf.def/00-general.conf create mode 100644 node.conf.def/01-auth.conf create mode 100644 node.conf.def/02-restriction.conf create mode 100644 node.conf.def/03-logging.conf create mode 100644 node.conf.def/04-balancing.conf create mode 100644 node.conf.def/05-sound.conf create mode 100644 node.conf.def/06-path.conf create mode 100644 node.conf.def/07-misc.conf create mode 100644 node.conf.def/08-bash.conf create mode 100644 node.conf.def/09-cups.conf create mode 100644 node.conf.def/10-samba.conf create mode 100644 node.conf.def/11-nxagent.conf create mode 100644 node.conf.def/12-nxproxy.conf create mode 100644 node.conf.def/50-numlockx.conf create mode 100644 node.conf.def/README create mode 100644 nx-session-launcher/ConsoleKit-NX.conf create mode 100644 nx-session-launcher/Makefile create mode 100644 nx-session-launcher/README create mode 100644 nx-session-launcher/freenx.session.policy create mode 100644 nx-session-launcher/nx-session-launcher create mode 100644 nx-session-launcher/nx-session-launcher-suid.c create mode 100755 nxcheckload.sample create mode 100755 nxdialog.freenx create mode 100644 nxfuncs create mode 100755 nxkeygen create mode 100755 nxnode create mode 100755 nxnode-login create mode 100644 nxredir/Makefile create mode 100755 nxredir/nxredir create mode 100644 nxredir/nxredir.c create mode 100755 nxredir/nxsmb create mode 100755 nxserver create mode 100755 nxsetup create mode 100644 nxviewer-passwd/COPYING create mode 100644 nxviewer-passwd/Imakefile create mode 100644 nxviewer-passwd/README create mode 100644 nxviewer-passwd/WhatsNew.TIGHTVNC.original create mode 100644 nxviewer-passwd/include/rfbproto.h create mode 100644 nxviewer-passwd/include/vncauth.h create mode 100644 nxviewer-passwd/libvncauth/Imakefile create mode 100644 nxviewer-passwd/libvncauth/d3des.c create mode 100644 nxviewer-passwd/libvncauth/d3des.h create mode 100644 nxviewer-passwd/libvncauth/vncauth.c create mode 100644 nxviewer-passwd/nxpasswd/Imakefile create mode 100644 nxviewer-passwd/nxpasswd/nxpasswd.man create mode 100644 nxviewer-passwd/nxpasswd/vncpasswd.c create mode 100644 nxviewer-passwd/nxpasswd/vncpasswd.c.NX.original create mode 100644 nxviewer-passwd/nxpasswd/vncpasswd.c.TIGHTVNC.original diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9eda397 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +nx-session-launcher/nx-session-launcher-suid +nxredir/libnxredir.so.0 +nxredir/nxredir.o +nxviewer-passwd/Makefile +nxviewer-passwd/Makefile.bak +nxviewer-passwd/libvncauth/Makefile +nxviewer-passwd/libvncauth/Makefile.bak +nxviewer-passwd/libvncauth/d3des.o +nxviewer-passwd/libvncauth/libvncauth.a +nxviewer-passwd/libvncauth/vncauth.o +nxviewer-passwd/nxpasswd/Makefile +nxviewer-passwd/nxpasswd/Makefile.bak +nxviewer-passwd/nxpasswd/nxpasswd +nxviewer-passwd/nxpasswd/vncpasswd.o + +debian/.debhelper/ +debian/files +debian/freenx-server.debhelper.log +debian/freenx-server.substvars +debian/freenx-server/ diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..bcc15c7 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,6 @@ +Fabian Franz +Rick Stout +Thorsten Sandfuchs +Kurt Pfeifle +Jon Severinsson +Dmitry Borisov diff --git a/CONTRIB b/CONTRIB new file mode 100644 index 0000000..7c01709 --- /dev/null +++ b/CONTRIB @@ -0,0 +1,81 @@ +III. How you can help +===================== + +1. Documentation +---------------- + +Documentation and experience reports are most important of course. So if you have something send it to us ;-). (FreeNX-kNX@kde.org) + +2. Code and Patches +------------------- + +While FreeNX is a volounteer project, it of course depends on the work of 7 years kindly donated by NoMachine to the Free Software Community: + +The NX open source libraries + +While they are mature and very good working, they need work in some very important fields. Most "difficulties" were provided by Gian Fillipo Pinzari main developer of NoMachine NX and CEO of NoMachine. + +2.1 Rootless nxagent + +This is the most needed feature at the moment. It will allow using single applications instead of a full featured desktop. Most code needed for that is already in the nxagent source tree; its just still a bit buggy and needs some "love". + +Difficulty: Medium + +2.2 Pseudo Color / True Color support + +This is the second most important feature needed. With the addition of Pseudo Color / True Color, it it possible to reconnect also on different depths (which is not possible at the moment). This will also make nxagent independent of the used Visuals (as far as I've understand it). + +Last but not least, will this allow me to use Xvfb to keep a session running, while no display is attached to it. + +Difficulty: Medium + +2.3 XRandr support + +XRandr support is available since version XFree86 4.3 and also most applications already support it. XRandr support would also enable one to reconnect at different geometry sizes and you could in an ideal case also just resize the window and it would work. + +At reconnection stage this is really important for the fullscreen mode. + +Difficulty: Easy + +2.4 XDamage support + +nxagent should be also able to profit from the new XDamage extension, to allow making NX sessions again even faster. + +Difficulty: Easy + +2.5 "Lazy image encoding" + +Currently images are sent at once and just limited by having a small control channel open to allow fast user interaction. It would be much better if the images would be "streamed" in a way. + +Quoting GFP: + +"> What about doing this asynchronously? Not necessarily doing it immediately, +> but analyzing (in parallel, the data is still sent with normal compression +> regardless) what is seen and then biasing the type of compression over +> time based on the "popularity" of given image characteristics for a +> specific application or window class. + +This is more or less what we want to do as part of the "lazy" +image encoding functionality that is going to be implemented. +The main goal of the "lazy" encoding is to decouple the image +handling from other protocol requests. The effect we want to +achieve is similar to loading a web page, where the browser +renders the images progressively, as they are downloaded from +the network. Once you have images sent asynchrounously, you +have opened the way to any form of post-processing." + +[TODO: This part is not yet explained enough ] + +2.6 Drag and Drop with automatic file transfer + +The idea is: + +Grab the X Drag And Drop requests in nxagent and advise the nxproxy on the other side to stream you the file with the filename, which you have got. The file should then be saved to a temporary location and the event given to the real application. While the file is transferred nxagent should display some kind of status bar. + +Difficulty: ~ Medium - Difficult + +2.7 Add the GLX extension + +Add the glx extension to nxagent and also try to remove roundtrips in GLX. + +Difficulty: Easy - Medium diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + 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. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..f85558e --- /dev/null +++ b/ChangeLog @@ -0,0 +1,690 @@ +xx.11.2008 FreeNX 0.7.4 + * Opened the 0.7.4 development. + * Fixed missing export of NX_ETC_DIR in Makefile, + so node.conf.sample is installed correctly. + (fabianx@bat.berlios.de) + * Fixed broken round-robin load balance algorithm. + (fabianx@bat.berlios.de) + * Fixed --terminate|--suspend|--force-terminate for + load balancing case. + (fabianx@bat.berlios.de) + * Fixed --terminate|--suspend|--force-terminate for + usermode case. + (fabianx@bat.berlios.de) + * Fixed non-encrypted session mode. You might need to + set EXTERNAL_PROXY_IP in node.conf. + (fabianx@bat.berlios.de) + +18.08.2008 FreeNX 0.7.3 "Priscilla One Year Edition" + * Opened the 0.7.3 development. + * Added logging of failed authentication attempts + to auth.log via syslog (3). This can be disabled by + setting ENABLE_LOG_FAILED_LOGINS="0". + (fabianx@bat.berlios.de) + * Added -nolisten tcp to nxagent invocation. + (fabianx@bat.berlios.de, idea by pappy- (Gentoo)) + * Used bash for all tasks as 'sh' might be not what we want + on standard ubuntu. + (fabianx@bat.berlios.de, thx to tan (IRC)) + * Finally fixed mv not working for failed or terminated + sessions. + (fabianx@bat.berlios.de, Terje Andersen ) + * Added patch from 2005 to enable reconnect to 24-bit display via + 32-bit or vice versa. Oops :) + (Sunil ) + * Added 3.2.0 as a backend version for nxloadconfig. + (fabianx@bat.berlios.de) + * Added configuration key ENABLE_SOURCE_BASH_PROFILE for toggling of + sourcing ~/.bash_profile. + (fabianx@bat.berlios.de) + * Added /usr/bin/xauth as default key and used /usr/X11R6/bin/xauth as + fallback. + (fabianx@bat.berlios.de) + * Fixed Makefile to stop on all errors. + (Idea by Hai Zaar , fabianx@bat.berlios.de) + * Changed the default for ENABLE_PASSDB_AUTHENTICATION. If you had + added a user with different password via --adduser consider + re-activating this option in node.conf. + (fabianx@bat.berlios.de) + * Added constraints for passdb based commands. They are only available + when ENABLE_PASSDB_AUTHENTICATION="1" else a friendly error message + is shown. This should help with users using old tutorials. + (fabianx@bat.berlios.de) + * Added unix-console patch. Added default handler as unix-default with + a fallback to xterm, + (Idea by Jens Hatlak , fabianx@bat.berlios.de) + * Fixed external rdesktop keyboards: A "$" was missing. + (Bug by Phil Stricker , fabianx@bat.berlios.de) + * Added workaround for "ch" keyboard layout to nxdesktop_helper, + which NXClient 3.2.0 means as de-ch. + (Bug by Phil Stricker , fabianx@bat.berlios.de) + * Added clean target to Makefile. + (Based on patch by Ubuntu FreeNX-Team, fabianx@bat.berlios.de) + * Use :0.0 if mirrorhost is 127.0.0.1 and add -localhost for + enhanced security. Also increase sleep timeout for slow machines. + (Based on Patch by Jeremy Wilkins , fabianx@bat.berlios.de) + * Allow RDP "Run application" sessions to work correctly. + (David Corral < davefury@gmail.com > & the Silice Telecom staff, + fabianx@bat.berlios.de) + * Merge Xresources on startup of session. + (Jeremy Wilkins ) + * Added nx-session-launcher from Ubuntu FreeNX-Team to use FreeNX with + ConsoleKit. + (marceloshima@gmail.com, fabianx@bat.berlios.de) + * Moved logging functions to a more appropriate place. + (fabianx@bat.berlios.de) + * Finally fixed the bug when NX Client was stopped on "Negotiating + link parameters" and failed session after first session suspend. + (fabianx@bat.berlios.de) + * Fixed missing "fi" statement. In fact it was a missing ";;". + (fabianx@bat.berlios.de) + * Used source instead of "." for Makefile. (Closes: #13954) + (fabianx@bat.berlios.de) + * Allow passwords with '\' by changing read -s to read -r -s. + (Closes: #10699) + (Patch by rpfuller@bat.berlios.de, fabianx@bat.berlios.de) + * Allow passwords with special chars by using new url_decode on + agent_password. (Closes: #10248) + (fabianx@bat.berlios.de) + * Fixed start/stop exit codes. + (Patch by Gentoo Portage, fabianx@bat.berlios.de) + * Finally checked for all service ports. (cups, media, samba) + and also checked it on the host where the load balancing actually + leads to. + (fabianx@bat.berlios.de) + * Fixed broken fallback logic if SSH_CLIENT variables cannot be read + correctly. + (fabianx@bat.berlios.de) + * Overhauled the usermode: + * There are now two modes of operation. + - One statically setting the + ENABLE_USERMODE_AUTHENTICATION key + in node.conf. (old behavior) + - Or using nxserver-usermode as startup + binary, which directly goes into the 103 stage. + * Fixed using commandline parameters like --cleanup + for static usermode. + * Enabled the root commandline parameters in usermode. + * Fixed usage of "nx" user as normal user in usermode. + * Disabled slave mode and load balancing for usermode. + * Fixed creation of the logfile directory. + * Fixed nxnode usage of SSH_CLIENT using fallback mechanism. + (Patch by nbartos@bat.berlios.de, fabianx@bat.berlios.de) + * Added disabled nxserver-suid wrapper with help from Google. To + enable it uncomment the suid_install target in Makefile. + ( Alistair Riddoch , fabianx@bat.berlios.de) + * Automatically disabled slave mode, when load balancing is activated. + (fabianx@bat.berlios.de) + * Made ENABLE_SLAVE_MODE="1" the new default as its faster + and more reliable. If you encounter any problems with it, + disable it in node.conf. + (fabianx@bat.berlios.de) + * Changed type for external agents to windows-helper or vnc-helper + so that those sessions can be mirrored / shadowed as well. + (fabianx@bat.berlios.de) + * Added nxshadowacl.sample component to be able to shadow + foreign sessions. + (fabianx@bat.berlios.de) + * Prepared shadowing foreign users for VNC-shadowing. + (fabianx@bat.berlios.de) + * Added shadow support to --listsession command. + (fabianx@bat.berlios.de) + * Added shadow mode as nxagent target. + (fabianx@bat.berlios.de) + * Fixed shadow mode and made it usable. + (Patch by Amin Shehata , fabianx@bat.berlios.de) + +14.03.2008 FreeNX 0.7.2 "Priscilla Edition" + * Opened the 0.7.2 development. + * Fixed the display of local sessions to display only + when session type is VNC. + (fabianx@bat.berlios.de) + * Fixed the issue that commercial NXClient was called with 0 parameters + and such the "Connection Wizard" came up. + (fabianx@bat.berlios.de) + * Added freenx-server startup script. You can make a symlink to + /etc/init.d/ to have it start automatically. + (fabianx@bat.berlios.de) + * Added catching of exception after failed nscd command. + (fabianx@bat.berlios.de) + * Invoke curl with --proxy "" for automatic download of ppd files. + (Wolfgang Schweer ) + * Reorganized nxsetup to have a function for parsing command line + options. + (fabianx@bat.berlios.de) + * Added nxsetup --test to test the configuration and connection to + localhost nxserver. + (fabianx@bat.berlios.de) + * Added -o ConnectTimeout 3 to nxnode-login for test-nx case. + (cedric briner ) + * Added more examples for "failed ssh connection to localhost" cases. + (cedric briner , fabianx@bat.berlios.de) + * Fixed helpers (desktop, viewer) to honour the AGENT_EXTRA_OPTIONS_{RDP,RFB} + parameters set in node.conf. + (fabianx@bat.berlios.de) + * Fixed the default value for ENABLE_CLIPBOARD="both" instead of ' = '. + (fabianx@bat.berlios.de) + * Fixed parsing of SMB port and added a fallback if mport file is empty. + (Patch from Gentoo Portage) + * Run nscd only when nscd.pid is present. + (Patch from Gentoo Portage) + * Fixed possible bug in nxserver when $USER is not set. + (Patch from Gentoo Portage) + * Set ENABLE_USESSION="1" option by default - its hard to find and those who know can + shut it off anyway. Added automatic adding of user nx to group utmp. + (Patch by Gentoo Portage) + * Added support for 3.1.0 and later backends. Made 2.0.0 backend the + default and added a fallback to 1.5.0 via the same detection mechanism. + (fabianx@bat.berlios.de) + * Added the configuration key ENABLE_PULLDOWN_MENU to be able to + disable the pulldown menu for rootless sessions. + (fabianx@bat.berlios.de) + * Fixed a small bug in nxserver when password has spaces at the end or + beginning. + (Dimitar Paskov) + * Fixed round-robin mode of load balancing. + (fabianx@bat.berlios.de) + * Added check for /tmp/.X11-unix/X*. + (Yves-Gaël Chény ) + * Fixed --send|--broadcast for load balancing case. + Note: ssh is used, so you need to either insert your root ssh password + for the nodes again and again, use a public key + agent or use host keys. + (fabianx@bat.berlios.de) + * Added possibility to use the new nxsmb backend. This enables us to support + CIFS and SMB printing at the same time - without recompiling samba - + via the nxredir preload library. + (fabianx@bat.berlios.de) + * Added usage of nxredir library to forward port 139,445 to the + client side forwarded SMB port. + (fabianx@bat.berlios.de) + * Made the slave mode finally functional. With that slave mode it is + possible to do a single sign on instead of the multiple logins used + before. It is also possible to use a suid wrapper to login as user. + With single sign on session startup is a lot faster. This is true + especially if there are many printers and files to be shared. + (fabianx@bat.berlios.de) + * Added detection of backend version and added this output + to version string. + (fabianx@bat.berlios.de) + * Added foomatic-ppdfile to the retested values. + (fabianx@bat.berlios.de) + * Added possibility to balance all nx services to different cores + using taskset. Use for example USE_PROCESSOR_TASKSET="3,4" to + balance all services to processor cores 3 and 4. + This wish was granted for Gregory Carter. + (fabianx@bat.berlios.de) + * Added initial code to add an application to an already running + rootless session. + Set ENABLE_ADVANCED_SESSION_CONTROL="1" and use session name + like "add ". Unfortunately the client returns an + error, but the application is started anyway. + The wish was granted for Bernhard Donaubauer. + (fabianx@bat.berlios.de) + * Added option to disable the showing of running sessions. + Set ENABLE_SHOW_RUNNING_SESSIONS="0" if you want that behaviour. + (fabianx@bat.berlios.de) + * Updated documentation in INSTALL file. + (fabianx@bat.berlios.de) + * Added nxviewer-passwd to distribution. It is a fork of the + tightvnc vncpasswd part, which is necessary for FreeNX to work + with standard vncviewer. + (fabianx@bat.berlios.de) + * Added a Makefile so FreeNX can be build and installed via. + $ make + $ # edit nxloadconfig to point where it should install to + $ make install + Hereby FreeNX is installed to where nxloadconfig points and + static paths in nxredir and nxsmb are adjusted accordingly. + So if you want it to be in /usr/NX/ be sure to apply + gentoo-nomachine.diff first or edit nxloadconfig manually. + (fabianx@bat.berlios.de) + * Added nxacl.sample component. If you copy nxacl.sample to + $PATH_BIN/nxacl you can make as complex acl scenarios as you + want. You have complete control over all data and can deny + any session. + (fabianx@bat.berlios.de) + +14.10.2007 FreeNX 0.7.1 "Hip Hop Edition" + * Fixed the issue that makes fonts look tiny and unreadable by default + with freenx and the commercial client. (diamond@google.com) + * Added invalidating of NSCD cache after group and user add. + (diamond@google.com) + * Added better wording with less misunderstanding to dialog of + nxclient for Suspend/Terminate/Close case. (diamond@google.com) + * Added 'dialog_interface=dialog' option since many installations may + not have Xdialog and since xmessage is very limiting. This new option + will work on any machine that has dialog and xterm. + (puterguy@bat.berlios.de) + * Fixed the APPLICATION_LIBRARY_PRELOAD to be just a warning and fixed + the default path. (fabianx@bat.berlios.de) + * Added drivers.cache.all that is reloaded just every 60 minutes. + (puterguy@bat.berlios.de) + * Fixed missing services stop that lead to redundant mounts and still + running cupsd processes. + (puterguy@bat.berlios.de) + * Added support for mount.cifs additionally to the deprecated + smbmount. (fabianx@bat.berlios.de, puterguy@bat.berlios.de) + * Added "host" output to --list to see which user is connected to + which server in case of loadbalancing. + (fabianx@bat.berlios.de, Bastian Kames ) + * Fixed nxclient -printer to not use commercial client, because its too + slow in case of huge databases like foomatic. (fabianx@bat.berlios.de) + * Removed bad -noautokill option from the nxclient dialog spawning. + (wayneb@bat.berlios.de) + * Added basic support for mirrored sessions. + * The functionality can be used by connecting to VNC session + and choosing to "resume" such a session. + * New configuration key: ENABLE_MIRROR_VIA_VNC=1 + * New configuration key: ENABLE_DESKTOP_SHARING=1 + (fabianx@bat.berlios.de) + * Fixed some portability issues. + * Fixed nxloadconfig in case that COMMAND_X is not only one word, + like "openssl md5". + * Added usage of "openssl md5" instead of "md5sum" by default. + * Changed perl to COMMAND_PERL. + * Removed rev and replaced the code with efficient awk code. + * Added an outcommented way to also use "POSIX find" for history + cleaning. + (Peter O'Gorman ) + * Fix ownership of $SSH_AUTHORIZED_KEYS in nxkeygen, just in case + it is run without nxsetup. + (fabianx@bat.berlios.de, thx to sambiase on #nx) + * Fixed diverse occurences of $sess_id in nxnode, when hostname + contains whitespace. + (fabianx@bat.berlios.de) + * Fixed setting up KDE_PRINTRC altogether if ENABLE_KDE_CUPS is not 1, + and handles errors better when it is but kde-config is not available + or fails. + (scop@bat.berlios.de) + * Changed unix:$display -> :$display to enable FreeNX usage with newer + xlib in C (used for example by Novell). + (fabianx@bat.berlios.de) + * Enabled 3.0.0 backend with same usage pattern as 2.[0|1].0 backend. + (Shawn Starr ) + * Bumped version number to 2.1.0-71 to let things like File-sharing + port and auxiliary channels work. + (fabianx@bat.berlios.de) + * Added parsing of aux parameter. This should remove all keyboard + related problems with nxdesktop with 2.[01].0 backend. + (fabianx@bat.berlios.de) + * Renamed nxclient to nxdialog and setup the necessary environment + variable for nxagent to find it. + (fabianx@bat.berlios.de, Thanks to NoMachine for giving this hint) + * Added experimental support for usage of external rdesktop and + vncviewer programs. + This is for example needed for 3.0.0 backend. + (fabianx@bat.berlios.de) + * Changed the default load balancing algorithm to "random" + as the nxcheckload script might not be available. + (fabianx@bat.berlios.de) + * Added ENABLE_CLIPBOARD="none|client|server|both" option + to node.conf to disable, restrict or enable the clipboard + synchronization. + (fabianx@bat.berlios.de) + +07.07.2007 FreeNX 0.7.0 "Jornade SPL Edition VI+1" + * Fixed the printing support for CUPS 1.2. + Older versions of CUPS are no longer supported. + * Note: You must do as root: + + cp /usr/lib/cups/backend/ipp /usr/lib/cups/backend/nxipp + chmod 755 /usr/lib/cups/backend/nxipp + + Or alternatively re-run nxsetup. + + * Added foomatic support. + * Note: You might need to do: ln -s /usr/bin/foomatic-ppdfile + /usr/lib/cups/driver/ + * Added setting of CUPS_SERVER environment var. + * Added automatic downloading of PPDs, if the client supports it. + * Added configuration vars to tweak the new behaviour. + * Added cups seamless support with no "use this driver?" dialogs at all. + * Note: You need nxcupsd-wrapper on the client side for CUPS 1.2 + clients. + + Get it from nxutils repository. + + * Fixed Support for "Running" sessions - again. + * Made the NXAgent exited with exit code 1 message more verbose. + * Added support for nxipp to nxnode and nxsetup. + * Added nxcups-gethost script for automatic usage in KDE. + * Fixed RDP/VNC sessions. No application should be started for that type. + (Patch by Bernard Cafarelli ) + * Added backingstore fix for older clients from Gentoo. + (http://bugs.gentoo.org/show_bug.cgi?id=149298) + * Fixed VNC sessions. + * Fixed fullscreen sessions. + (Patch by Gentoo Bugtracker) + * Fixed --broadcast. + * Added "passwd -u nx" to nxsetup to fix slackware. + * Fixed respecting of enconding settings in case of rootless mode. + * Fixed smb mounting in case nxclient sends the wrong port. + (Patch by Jan Lockenvitz ) + * Fixed loadbalancing - was still using an undocumented variable. + +23.01.2007 FreeNX 0.6.0 "Juliana birthday edition" + * Opened the 0.6.0 branch. + * Added nxnode slave mode. + * General code cleanup. + * Huge cleanup of nxnode. + * Removed "no-x11-forwarding" from keys to allow client to use the + faster interactive sessions. + * Fixed nxsetup automatic testing of sessions and cleared up + explanations. + * Added support for NX 2.0.0 style nxclient dialogs. + * Support for NX 2.0.0 backend in nxloadconfig. + * Fixed cups printing (added username and password). + * Fixed one more stray tail process. + * Added example script for "load" based loadbalancing. + * Fixed spaces in parameters for NX Client 2.0.0. + (ssycplkbocve@spammotel.com) + * Added version 2.1.0 support. + * Fixed LD_LIBRARY_PRELOAD default path in nxloadconfig. + * Fixed nxclient to work with 2.1.0 backend. + * Added autodetection of backend. + +01.07.2006 FreeNX 0.5.0 "UKUUG 2006 Edition" + * Opened the 0.5.0 branch. + * Added load balancing. + * Completely removed support for 1.4.0 backend. + * Rootless mode is now the default. + * Reworked nxnode / suspend on connection failure should work now. + * Added support for "Running" sessions. + * Fixed --send command. (Emmanuel Blindauer ) + * Fixed resume with nxclient >=1.5.0-106 for Windows. + * Fixed rootless sessions with Windows nxclient. + * Fixed keyboard issues by enabling the keybd channel. + * Fixed one more stray tail process and being able to + cleanup after a hopelessly failed reconnection. (i.e. agent died) + * Fixed detection of xauth / netcat. Added option to disable extra + checks. + * Fixed --terminate / --suspend when hostname has a '-' in it. + (Emmanuel Blindauer ) + * ESD_NO_SPAWN is always set when ESPEAKER is set. + ("Felipe Alfaro Solana" ) + * Added perl replacement for 'rev' function on Sun OS 5.10. + * Fixed NODE_AUTOSTART to be unable to block sessions. + * Fixed stale sessions introduced by the new session handling model. + * Added usage of TCP NODELAY option. + * Fixed loadbalancing IP issues. + * Added --force-terminate to remove session info. + Fixed issue with suspend/terminate commands. + * Added correct errorcode 596 instead of 504. + * Implemented "round-robin" and "load" loadbalancing algorithms. + Cleaned up node.conf keys. + * Fixed help for --restart. + * Fixed session_running function, which fixes all remaining stale + session problems. + * Removed termination of nxagent in case of rootless mode. + (Fixes kontact without --nofork) + * Last minute fixes for new functions using rev. + * Added experimental last minute support for NX 2.0.0 backend. + (set ENABLE_2_0_0_BACKEND=1) + +XX.XX.2006 FreeNX 0.4.5 "aKademy Edition" + * Made nxsetup more user-friendly and hopefully finally failsafe. + * Added --agent to nxnode/nxserver to allow easier debugging. + * Added addgroup/groupadd to nxsetup + * Added --ignore-errors support on nxsetup/nxloadconfig + * Added check for expect. + +06.08.2005 FreeNX 0.4.4 "UKUUG Enterprise Edition" + * Added ENABLE_1_5_0_BACKEND configuration directive: + * Fixed fullscreen support in nxdesktop (still feels more like + 'Available Area', but with Ctrl-Alt-F you can get "real" + fullscreen) + * Added COMMAND_MD5SUM directive + * Security: $USER_FAKE_HOME/.nx now gets 0700 + * Fixed support for CUPS forwarding. + * Added secure re-transmitting to client. + * Removed grep from getent to not search through the whole database. + (Suggestion by "Matthew S. Harris" , + "Ed Warnicke" ) + * Set sleeps to 60 instead of 10 seconds, removed one wrong trap. + (Suggestion by "Sunil" ) + * Made automatic timeout configurable. + (Patch by "Ed Warnicke" ) + * Made nxsetup more enterprise friendly. Added --localuser + (RedHat only) and --gid. + (Based on a patch by "Ed Warnicke" ) + * Fixed resume of multiple sessions. + +28.07.2005 FreeNX 0.4.3 "NoMachine 1.5.0 Edition" + * Fixed reconnection problems with !M 1.5.0 client. + * Fixed reconnection problems with !M 1.5.0 backend. + * Added evaluation of $NX_ETC_DIR/node.conf.d/* config files. + * Fixed a possible security problem. (The client was able + to overwrite parameters set by the server) + * Added ENABLE_1_5_0_BACKEND configuration directive: + * Added support for fake cookie authentication with + !M 1.5.0 client and 1.5.0 backend. + * Fixed nxagent termination problems with !M 1.5.0 + backend. + * Added RDP highcolor support for !M 1.5.0 client + with !M 1.5.0 backend. + * Added secure logging - Passwords are no longer shown in log files. + * Security: Certain passwords for VNC/RDP could have been visible via + `ps aux`. + * Added experimental usermode authentication scheme. + (Disabled by default) + +16.07.2005 FreeNX 0.4.2 "Solaris / Bugfix / Linux Infotag Pforzheim Edition" + * Removed forwarding support via "freenx.", because it was + buggy. + * Cleaned up lots of code. + * Fixed one case of a left over file. + * Removed one unnecessary usage of a temporary file. + * Added exit handlers in nxserver and nxnode for more stability on + reboot of system. + * Changed nxnode to be much more stable. + * Catched one additional "unclean termination of nxagent" + case, which lead to "zombie" sessions. + * Reworked reconnection support for more stability. + * Added displaying of reconnection failure in + system log / client ssh log. + * Added even more possibilities to catch and report session startup + failures. + * Fixed PNG and JPEG-levels pack method. + * Added usage of netcat -z to check that the port is really not used by + another agent. + * Added nxserver --cleanup, which terminates all running sessions. + Useful after a power outage. + * Fixed nxclient invocation with non-standard installation path + * Added detection of SSH2_CLIENT variable (commercial ssh) + * Finally fixed problems with GNOME. + * FINALLY added Solaris Support Patch. + +24.06.2005 FreeNX 0.4.1 "LinuxTag Edition" + * Fixed a small security problem giving access to session database. + * Added support for 1.5.0 OSS components. (especially rootless mode) + * Fixed Filesharing over the Internet. (Thanks to rogierm@users.berlios.de) + * Fixed Resume on Windows with non-fullscreen sessions. + * Added suspend/resume support for 1.5.0 OSS components. + * Fixed display of suspended sessions in nxserver --list. + +04.05.2005 FreeNX 0.4.0 "SambaXP Edition" + * Opened the 0.4.0 branch. + * Added initial support for filesharing via samba. + * Improvements to be more node.conf compatible. + * Added COMMAND_NETCAT, COMMAND_SSH & COMMAND_SSH_KEYGEN directive + * Added support for 'nxloadconfig --check' to validate node.conf + settings + * Added initial support for sound (esd/artsd). + * Added optional support for utmp/wtmp/lastlog database. + * Removed support for OSS components prior version 1.4.0 in nxnode. + Added -option option to nxagent/nxdesktop/nxviewer. + * Added forwarding to commercial server via destination port. + * Added more compatible getparam function + * Sets LD_PRELOAD for applications and LD_LIBRARY_PATH for + nxagent/nxproxy by default. + - SET_LD_LIBRARY_PATH replaces NX_NOMACHINE_WAY and is + enabled by default, as it is now safe to do so + * Implemented SSHD_CHECK_IP directive. + * Added the SESSION_HISTORY directive. Session history will by default + be kept for 30 days. + * Implemented DEFAULT_X_WM for unix-application virtual desktop mode. + * Implemented SESSION_LIMIT and SESSION_USER_LIMIT. + * Fixed nxviewer commandline for geometry and fullscreen-support + * Added NX_LOG_LEVEL instead of NX_LOGGING, allowing less verbose + logfile. + * Added SESSION_LOG_CLEAN for configurable removal of the temporary + session directory. + * Added "--ssh2" cmdline switch for commercial ssh2-server support + in nxsetup. + * Added ENABLE_FORCE_ENCRYPTION to enforce the usage of encryption on + the server. + * Added nxprint and added -printer to nxclient together with handling + of drivers cache. + * Fixed a possible race-condition. (reported by Edward Warnicke + ) + * Feature Request #847 (stderror of some applications to log-file) + * Feature Request #900 (Detect ssh/sshd in nxsetup) + * Added printing support via userspace CUPSd and Samba. + +20.03.2005 FreeNX 0.3.1 "Bugfix Edition" + * Fixed keyboard mapping problems. + * Fixed unix-custom mode; now allowing parameters to be passed. + * Fixed password prompt detection support in nxnode-login. + * Fixed locking to prevent usage of the same display. + * Fixed resume when agent is no longer there. + * Fixed error message shown to user, when session startup fails. + * Fixed handling of /tmp/.X*-lock files. + * Fixed handling of not closed sessions in "Terminating" status. + * Fixed resume of multiple suspended sessions. + +05.03.2005 FreeNX 0.3.0 "Chemnitzer LinuxTage Edition" + * Initial CVS checkin. + * Added unix-default as session type - by Kalev Lember + + * Fixed nxclient loop - by "Neil Wilson" . + * Several fixes by Thorsten Sandfuchs . + * Optional config file support (system- and user-wide) + - by Jon Severinsson . + * Moved logfile to /var/log/nxserver.log. + * Moved nx homedir to /var/lib/nxserver/home + * Complete rewrite of authentication code + * passdb, su or ssh is now supported. + - by Jon Severinsson . + * Added NODE_AUTOSTART, EXPORT_{USERIP/SESSIONID} config file + directives. + * Added mechanism to forward connection to commercial NoMachine + nxserver (as available from www.nomachine.com). + * Added mechanism to forward connection to another nxserver. This + allows using a "chain" of nxservers. + * Added "floating window" support by using rootless nxagent as + it will be standard in NX 1.5.0. + * Added "floating window" support by just nxproxy/nxproxy connection + and added configuration directive to enable rootless mode. + * Added nxsetup --uninstall and added more feature to nxsetup. + Note: You need to use nxsetup --install for installation now. + * Added Disabling of port-forwarding, X11-forwarding, ... to ssh-key. + + * Security: Fixed a security blunder. Authority file was not used + and so basically xhost +localhost was set. (ported from + 0.2.8) + + Update immediately. + + * Security: Fixed two possible security problems (umask was not set + correctly; ported from 0.2.8) + +20.11.2004 FreeNX 0.2.7 "Skolelinux Edition" + * Fix nxserver to work again with KNX-Client. ('\r' is evil) + * Fix timeout in nxnode-login to allow proper session management + again. + * Fixed possible race condition for the wait-file. + +11.11.2004 FreeNX 0.2.6 + + * Security: Fixed a possible exploit in ssh-usage + (thanx to Sebastian Krahmer from the SuSE security team) + * Important: Public/Private key is no longer used for PAM auth mode. + +14.10.2004 FreeNX 0.2.5 + * Added Xdialog interface for nxclient and automatic usage + of commercial nxclient when available. (Thx go to Rick Stout + ) + * Added bugfix from the 0.3.0 branch for more flexible nxdesktop in + nxnode. + * Added patch by Rick Stout for permission problems in nxnode. + * Added patch by Rick Stout for a typo in nxkeygen. + * Updated gentoo-nomachine.diff. + * Updated CONTRIB to include a description of lazy-image encoding. + +11.09.2004 FreeNX 0.2.4 + * Added timeout to avoid having hanging tail processes. + * Added "locking" of the display-offset if nxagent failed to start. + * Fixed ssh encryption for resume on client 1.4.0-snapshot 5. + * Fixed mktemp, which was non-portable to FreeBSD and Red Hat 9. + +10.09.2004 FreeNX 0.2-3 + * Added support for autoreconnection or autoreconnection just + for the case when an older client version is used. + * This makes it possible to use Reconnection with the + stable version 1.3.2-7 (enabled by default) + * Added instructions how to install the NoMachine sources to INSTALL + * Changed $NX_DIR/bin/ssh to ssh to fix gentoo-nomachine.diff + * Added nxkeygen by Stuart Herbert for easier change from the + NoMachine key to another key afterwards. + + * Security: Any user was able to change the status of other sessions + in the session database by providing the correct uniqueid. + +10.09.2004 FreeNX 0.2-2 + * Added additional support for safe session suspend, + autosuspend when network connection times out works now! + * AuthorizedKeysFile cannot be safely determined on Gentoo; + changed it to config option now. + * Added config option to completely disable passdb support. + * Fixed bugs in nxclient dialog frontend. + * Removed all usage of nxssh due to security concerns from SuSE. + * Fixed session management for knx client. + * Added detection of failed nxagent startup. + * Updated the gentoo-nomachine.diff to be not fuzzy. + +08.09.2004 FreeNX 0.2-1 + * Fixed support for one windows client version. + * Fixed setting of key with --adduser. + (Thanks to Stuart Herbert ) + * Fixed _some_ cases for AuthorizedKeysFile in sshd_config. + (Thanks to Peter Holik ) + + * Fixed gentoo-nomachine.diff (nxnode not in path, but nxnode-login would try that) + * Fixed the bug with hanging tail processes. + +07.09.2004 FreeNX 0.2-0 + * Reworked the whole security model in nxsetup due to requests from SuSE and Gentoo. + - nxsetup does not use the NoMachine key by default. + - PAM authentication is enabled by default. + + * Added nxclient for compatibility with nxclient -dialog mode. + + * Minor changes + * Added SSHD_AUTH_PORT to config vars in nxserver + * Made all programs NX_ aware + * Programs do now honor the setting of AuthorizedKeysFile in sshd_config + * Changed nxsetup check from direct reading of passwd to getent + (Thanks to Tom Hibbert ) + * Changed overall messages in nxsetup + + * Made a overall clean upstream package. + * Added Gentoo / NoMachine compatibility diff + +06.09.2004 + * Added pam authentication + * Added user_db switch + * moved some su - to nxnode-login + +02.09.2004 + * Added support for snapshot 4 (43/66) + * Fixed compatibility issue with 1.3.0 + (Used by Knoppix 3.4 and earlier) + * added sane logging (LOGGING is now properly used) + +20.06.2004 + * Added Protocol version 1.4.0 + * Cleanup + * Added missing functions + +14.06.2004 + * Added Protocol version 1.3.2 diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..600cb90 --- /dev/null +++ b/INSTALL @@ -0,0 +1,116 @@ +INTRODUCTION +------------ + +This is the FreeNX server package. + +DEPENDENCIES +------------ + +It depends on: + +- NX sources +- X11 libraries +- sshd +- expect +- netcat + +NOTE +---- + +This tarball is intented mainly for distributions, which want to use FreeNX as building the other OpenSource NX components is quite difficult. + +In the following sections it is outlined how to install FreeNX as soon as you've build all open source components. + +HOWTO MANUALLY INSTALL +---------------------- + +The easy way: + +See: http://mail.kde.org/pipermail/freenx-knx/2007-October/006041.html + +The real way: + +You must apply the gentoo-nomachine.diff and then copy the files to /usr/NX/bin and /usr/NX/lib. + +Here is a howto: + +Get all sources except nx-X11-compat.tar.gz from www.nomachine.com/sources.php + +Untar all sources, install all dependencies then do: + + $ cd nx-X11 + $ make World + $ cd .. + $ cd nxproxy + $ ./configure && make + +# Libraries + +You can use the following schema to do the install to /usr/NX/: + + $ NXPREFIX=/usr/NX + $ mkdir -p ${NXPREFIX}/lib ${NXPREFIX}/bin + + $ cp -a nx-X11/lib/X11/libX11.so* ${NXPREFIX}/lib + $ cp -a nx-X11/lib/Xext/libXext.so* ${NXPREFIX}/lib + $ cp -a nx-X11/lib/Xrender/libXrender.so* ${NXPREFIX}/lib + $ cp -a nxcomp/libXcomp.so* ${NXPREFIX}/lib + $ cp -a nxcompext/libXcompext.so* ${NXPREFIX}/lib + +# binaries + + $ cp -a nx-X11/programs/Xserver/nxagent ${NXPREFIX}/bin + $ cp -a nxproxy/nxproxy ${NXPREFIX}/bin + +### Now comes the FreeNX part + +# build binaries and libs included in FreeNX distribution + + $ cd freenx- + $ patch -p0 < gentoo-nomachine.diff + $ make + $ make install + +You should also install the nxclient from NoMachine or install Xdialog. + +Then you need to run 'nxsetup --install' and follow the instructions given. + +Have Fun! + +Best regards, + +Fabian + +-- + +Old way without Makefile (instead of make; make install): + +# nxredir + + $ cd nxredir + $ make + $ cd .. + +# nxpasswd + + $ cd nxviewer-passwd + $ xmkmf + $ make World + $ cd .. + +# install binaries included in FreeNX trunk + + $ cd nxredir + $ make install + $ cd .. + $ cp -a nxviewer-passwd/nxpasswd/nxpasswd ${NXPREFIX}/bin + +# scripts + + $ cp nx* ${NXPREFIX}/bin + +# config file + + $ cp -a freenx*/node.conf.sample ${NXPREFIX}/etc/ + +SVN: $Id: INSTALL 536 2008-03-27 18:54:08Z fabianx $ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e82c36d --- /dev/null +++ b/Makefile @@ -0,0 +1,95 @@ +.PHONY: all install clean nxenv_install suid_install + +SHELL = /bin/bash + +# helpers for "install" target +INSTALL_DIR=install -d -m 755 +INSTALL_FILE=install -m 644 -C +INSTALL_PROGRAM=install -m 755 +INSTALL_SYMLINK=ln -s -f + +NX_ETC_DIR ?= /etc/nxserver +PREFIX ?= /usr +PATH_BIN ?= $(PREFIX)/bin +PATH_LIB ?= $(PREFIX)/lib +CUPS_BACKEND ?= $(PREFIX)/lib/cups/backend +PATH_SHARE ?= $(PREFIX)/share + +NX_VERSION=`cat VERSION 2>/dev/null` + +SUBDIRS=nxredir nxviewer-passwd nx-session-launcher +PROGRAMS=nxcheckload.sample nxdialog.freenx nxkeygen nxnode nxnode-login nxserver nxsetup nx-session-launcher/nx-session-launcher +PROGRAMS_BIN=nxviewer-passwd/nxpasswd/nxpasswd nx-session-launcher/nx-session-launcher-suid + +all: + cd nxviewer-passwd && xmkmf && make Makefiles && make depend + export PATH_BIN PATH_LIB CUPS_BACKEND NX_VERSION NX_ETC_DIR &&\ + for i in $(SUBDIRS) ; \ + do\ + echo "making" all "in $$i..."; \ + $(MAKE) -C $$i all || exit 1;\ + done + +suid_install: + chown nx:root $(DESTDIR)/$(PATH_BIN)/nx-session-launcher-suid + chmod 4755 $(DESTDIR)/$(PATH_BIN)/nx-session-launcher-suid + chown :users $(DESTDIR)/$(NX_ETC_DIR)/ppd + chmod 775 $(DESTDIR)/$(NX_ETC_DIR)/ppd + chown nx:nx $(DESTDIR)/var/lib/nxserver/home/ + chown nx:nx $(DESTDIR)/var/lib/nxserver/db/ + + +nxenv_install: + $(INSTALL_DIR) $(DESTDIR)/$(PATH_BIN)/ + $(INSTALL_DIR) $(DESTDIR)/$(PATH_LIB)/freenx-server/ + $(INSTALL_DIR) $(DESTDIR)/$(NX_ETC_DIR)/ + $(INSTALL_FILE) conf/node.conf $(DESTDIR)/$(NX_ETC_DIR)/ + $(INSTALL_FILE) data/Xkbmap $(DESTDIR)/$(NX_ETC_DIR)/ + $(INSTALL_PROGRAM) data/fixkeyboard $(DESTDIR)/$(NX_ETC_DIR)/ + $(INSTALL_PROGRAM) data/Xsession $(DESTDIR)/$(NX_ETC_DIR)/ + $(INSTALL_DIR) $(DESTDIR)/$(NX_ETC_DIR)/node.conf.d/ + $(INSTALL_FILE) conf/conf.d/*.conf $(DESTDIR)/$(NX_ETC_DIR)/node.conf.d/ + $(INSTALL_DIR) $(DESTDIR)/$(NX_ETC_DIR)/acls/ + $(INSTALL_FILE) conf/acls/* $(DESTDIR)/$(NX_ETC_DIR)/acls/ + install -m775 -gusers -d $(DESTDIR)/$(NX_ETC_DIR)/ppd/ + $(INSTALL_DIR) $(DESTDIR)/$(PATH_SHARE)/freenx-server/node.conf.def + $(INSTALL_FILE) node.conf.def/* $(DESTDIR)/$(PATH_SHARE)/freenx-server/node.conf.def/ + $(INSTALL_FILE) nxfuncs $(DESTDIR)/$(PATH_SHARE)/freenx-server/ + $(INSTALL_DIR) $(DESTDIR)/$(CUPS_BACKEND)/ + $(INSTALL_DIR) $(DESTDIR)/etc/logrotate.d/ + $(INSTALL_FILE) data/logrotate $(DESTDIR)/etc/logrotate.d/freenx-server + $(INSTALL_DIR) $(DESTDIR)/etc/sudoers.d/ + install -m400 data/sudoers.conf $(DESTDIR)/etc/sudoers.d/nxserver + $(INSTALL_DIR) $(DESTDIR)/etc/dbus-1/system.d/ + $(INSTALL_FILE) nx-session-launcher/ConsoleKit-NX.conf $(DESTDIR)/etc/dbus-1/system.d/ + $(INSTALL_DIR) $(DESTDIR)/var/lib/nxserver/ + install -m2750 -d $(DESTDIR)/var/lib/nxserver/home/ + install -m2770 -d $(DESTDIR)/var/lib/nxserver/db/ + for i in $(PROGRAMS) ;\ + do\ + $(INSTALL_PROGRAM) $$i $(DESTDIR)/$(PATH_BIN)/ || exit 1;\ + done + for i in $(PROGRAMS_BIN) ;\ + do\ + $(INSTALL_PROGRAM) -s $$i $(DESTDIR)/$(PATH_BIN)/ || exit 1;\ + done + $(MAKE) -C nxredir install + #$(MAKE) suid_install + +clean: + for i in $(SUBDIRS) ; \ + do\ + echo "making" clean "in $$i..."; \ + if test -e "$$i/Makefile"; \ + then $(MAKE) -C $$i clean || exit 1;\ + else echo ignoring $$i;\ + fi;\ + done + rm -f nxviewer-passwd/Makefile.back + rm -f nxviewer-passwd/Makefile + rm -f nxviewer-passwd/nxpasswd/Makefile + rm -f nxviewer-passwd/libvncauth/Makefile + +install: + export PATH_BIN PATH_LIB CUPS_BACKEND NX_VERSION NX_ETC_DIR &&\ + $(MAKE) nxenv_install diff --git a/README.md b/README.md new file mode 100644 index 0000000..b5fe644 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# Evolution of classic nx technology - FreeNX + +All these years, the classic nx was not as dead as it seemed ;) +It is used in production and develops as fast as it can. + +I am very grateful to the developers of the [ArcticaProject/nx-libs](https://github.com/ArcticaProject/nx-libs) for maintaining backward +compatibility and the opportunity to use their libraries instead +of self-assembly. + +Compared to the original freenx new features added by community: + +- CUPS Server mode: servers's system CUPS used directlty (witch sudo) +and remote printers can be share between users; + +- NXACLS in user mode: control of starting specific applications and +their substitution for users and groups; + +- Printers and shares multimount: in case multiply sessions from one +client's computer try shares leave while there is at least one running +session; + +- Pulseaudio sound: tunnelled, with or without resampling; + +- Localization of windows sharenames; + +- Control of rootles sessions ending: based on application-process +internal customizable map; + +- Reduced connection time; + +- Used nxsetting sqlite db (nxsetup --reload or nxsetup --mkdb for update). +Everything got even a little faster; + +- vnc and rdp over nx modes running; + +- Shadow mode worked also; + +- nxshadowacl script functionality moved to existing acl. + + +Many thanks to Djelf for long consultations on sqlite. + +Thats all worked with [opennx ce](https://github.com/dimbor-ru/opennx) liux/windows client, but original nxclient +basicaly alive too (with restrictions). + +Debian package home-maded for Devuan ASCII now. There is a suspicion that +under Debian Stretch everything will be fine. + +On modern systems with glibc >= 2.28 to run nxclient you must apply [solution](https://github.com/dimbor-ru/freenx-server/issues/5#issuecomment-579694048) +from Djelf (on nxclient side of course). + +Code from him to install nxclient 32/64: +#!/bin/sh +mkdir nxclient +cd nxclient +wget http://debian.rot13.org/binary/64.34.161.181/download/3.5.0/Linux/nxclient_3.5.0-7_amd64.deb +#wget http://debian.rot13.org/binary/64.34.161.181/download/3.5.0/Linux/nxclient_3.5.0-7_i386.deb +wget https://github.com/dimbor-ru/freenx-server/files/4128228/nxfixglibc1190.tar.gz +dpkg -i ./nxclient_3.5.0-7_amd64.deb +find /usr/NX/lib -name "libz*" -delete +tar -xvf nxfixglibc1190.tar.gz +#cp ./nxfixglibc1190/x32/nxfixglibc1190.so /usr/NX/lib/nxfixglibc1190.so +cp ./nxfixglibc1190/x64/nxfixglibc1190.so /usr/NX/lib/nxfixglibc1190.so +cp /usr/NX/bin/nxclient /usr/NX/bin/nxclient.bin +echo '#!/bin/sh' > /usr/NX/bin/nxclient +echo 'LD_PRELOAD=/usr/NX/lib/nxfixglibc1190.so /usr/NX/bin/nxclient.bin /$@' >> /usr/NX/bin/nxclient + +Solution to use Arctica nx-libs: +#!/bin/sh +find /usr/NX/lib -name "libjpeg*" -delete +find /usr/NX/lib -name "libXcomp*" -delete +ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/NX/lib/libjpeg.so.62 +ln -s /usr/lib/x86_64-linux-gnu/libXcomp.so.3 /usr/NX/lib/libXcomp.so + +Archives of old nx stuff you can find [here](http://ftp.disconnected-by-peer.at/NX/) + +dimbor. 2022 diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..b2865a2 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +3.5.0-2.1.3-CE diff --git a/conf/acls/README b/conf/acls/README new file mode 100644 index 0000000..d3e1608 --- /dev/null +++ b/conf/acls/README @@ -0,0 +1,32 @@ +# nxacl.app v1.1 Copyleft by dimbor at unixforum.org +# Freenx parse ACL-files in NX_ACL_DIR and search user/group permissions +# for given cmdstr. ACL filenames are usernames, groupnames and "all". +# Permissions search order: user - group - all. ACL contain one or more +# strings of regexp-patterns. See examples at existing ACL. Format: +# +# # some comment-string +# [!]CmdTpl [%%% [[!][@@]OnceAppTpl] %%% Prog|"Msg"] +# +# ! - not equal == invert rule +# %%% - fields delimiter +# CmdTpl - startsession command template +# OnceAppTpl - if it not found/found (""/"!") in process-list of user do'nt start session +# @@ - search in process-list of all users (ps ax) +# Prog - string for nxdialog or other x-binary to execute instead session-app +# if "OnceAppTpl" condition is FALSE +# +# Attention!!! Spec-symbols (like ".","$","^") must be escaped twice vs once +# ('\\.' vs '\.'), sorry. +# +# In acl file for any user0 may be addded special CmdTpl named '@shadow@'. +# Format: +# +# @shadow@ %%% user1[,user2[,user3...]] +# +# It means that user0 have permissions to shadow connect to sessions running +# of the users listed in the second field. +# +# user may be described as [#]user[!] +# where '#' means view only mode, '!' - don't ask user for authorization +# +# In the list of users is also allowed keyword 'all' \ No newline at end of file diff --git a/conf/acls/all b/conf/acls/all new file mode 100644 index 0000000..8fd6564 --- /dev/null +++ b/conf/acls/all @@ -0,0 +1,17 @@ +# ACL for all users, that not mentioned in others ACLS + +# Uncomment string below to set communism for them +#.* + +# Uncomment below to send them your original message only (bad example) +#.* %%% !.* %%% "Get out, imbecile!" +# the same +#.* %%% %%% "Get out, imbecile!" + +# Uncomment below to start very specialy app instead of given (good example ;) +#.* %%% !.* %%% /usr/games/kpat + +# Uncomment below if your'e contempt is limited to running standart +# warning app. (WARN_APP from nxacl script.) +# But this is a useless act, because it's installed by default. ;) +#.* %%% !.* diff --git a/conf/acls/dim b/conf/acls/dim new file mode 100644 index 0000000..0ccaa4d --- /dev/null +++ b/conf/acls/dim @@ -0,0 +1,7 @@ +# ACL for user named + +# start KDE-session only once, else warn. +startkde %%% !startkde %%% "You can have only one KDE-session!" + +# start KDE-session only once, else start your script +#startkde %%% !startkde %%% /usr/bin/super-puper-start-with-control KDE diff --git a/conf/acls/odmin b/conf/acls/odmin new file mode 100644 index 0000000..b80a97e --- /dev/null +++ b/conf/acls/odmin @@ -0,0 +1,8 @@ +# ACL for user named + +# Admin is like a Got. Well, almost... +.* + +# Admin have permissions to shadow connect to sessions of all users +# without authorization +@shadow@ %%% all! diff --git a/conf/acls/sveta b/conf/acls/sveta new file mode 100644 index 0000000..92e3adf --- /dev/null +++ b/conf/acls/sveta @@ -0,0 +1,8 @@ +# ACL for user named + +# could start app 1c.sh if "Alliance" present in own parameters +1c8\\.sh.*Alliance + +# user have permissions to shadow connect to sessions of dim and all users +# to all except dim - in view mode only +@shadow@ %%% dim,#all diff --git a/conf/acls/users b/conf/acls/users new file mode 100644 index 0000000..82be0b8 --- /dev/null +++ b/conf/acls/users @@ -0,0 +1,3 @@ +# ACL for group named + +1c8\\.sh %%% !1cv8 %%% "You can only run one 1C app at a time." diff --git a/conf/conf.d/00-general.conf b/conf/conf.d/00-general.conf new file mode 100644 index 0000000..75aad2d --- /dev/null +++ b/conf/conf.d/00-general.conf @@ -0,0 +1,12 @@ +######################################################################### +# General FreeNX directives +######################################################################### + +# The host name which is used by NX server. It's should be used if it's +# different than the default hostname (as returned by `hostname`) +#SERVER_NAME="$(hostname)" + +# The node ip which is used by NX Node in unecnrypted session mode. +# Set it if you want to use a specific external ip or the autodetection +# is not working. +#EXTERNAL_PROXY_IP="" diff --git a/conf/conf.d/01-auth.conf b/conf/conf.d/01-auth.conf new file mode 100644 index 0000000..d83aabc --- /dev/null +++ b/conf/conf.d/01-auth.conf @@ -0,0 +1,25 @@ +######################################################################### +# Authentication / Security directives +######################################################################### + +# If enabled forces the user to use encryption. This will bail out +# if the user does not have encryption enabled. +#ENABLE_FORCE_ENCRYPTION=0 + +# Refuse the NX client connection if SSHD does not export the +# SSH_CONNECTION and SSH_CLIENT variables in the environment +# passed to the NX server. +# 1: Will check the remote IP and will not accept the +# connection if it can't be determined. +# 0: Will accept the connection even if the remote IP +# is not provided. +#SSHD_CHECK_IP=0 + +# If ENABLE_LOG_FAILED_LOGINS=1 then failed login attempts are logged to the +# system auth.log. +# +# This is useful in combination with tools like fail2ban. +# +# The default is to log failed login attemps via syslog (3). +# +#ENABLE_LOG_FAILED_LOGINS=1 diff --git a/conf/conf.d/02-restriction.conf b/conf/conf.d/02-restriction.conf new file mode 100644 index 0000000..c6e503a --- /dev/null +++ b/conf/conf.d/02-restriction.conf @@ -0,0 +1,109 @@ +######################################################################### +# Restriction directives +######################################################################### + +# The base display number from which sessions are started. +#DISPLAY_BASE=2000 + +# The maximum number of contemporary sessions that can be run on FreeNX +#SESSION_LIMIT=200 + +# The maximum number of contemporary sessions that a single user can run +# on FreeNX. +#SESSION_USER_LIMIT=20 + +# The number of displays reserved for sessions, it has to be greater or equal +# to the maximum number of contemporary sessions that a server can run. +#DISPLAY_LIMIT=200 + + +# User for which sessions should be persistent. Either the keyword "all" or a +# comma-separated list of usernames or groups in the @groupname syntax. +#ENABLE_PERSISTENT_SESSION="all" + +# Users and groups for whom persistent sessions should be disabled. +# Especially useful if ENABLE_PERSISTENT_SESSION="all" +#DISABLE_PERSISTENT_SESSION="" + +# General nx shadowing +# If ENABLE_SESSION_SHADOWING=1 nxserver will store in db shadow +# cookies +#ENABLE_SESSION_SHADOWING=1 + +# +# When using NX 3.0 shadowing, this enables asking the user whether +# he authorizes another user to shadow his session +# +# 0: No authorization request will be presented, +# and the session will be shadowed as if the user had approved. +# 1: (default) Ask for authorization +# +#ENABLE_SESSION_SHADOWING_AUTHORIZATION=1 + +# Allow session shadowing in interactive mode: +# +# 1: The shadowing user can interact with the shadowed session. +# +# 0: The shadowed session is view-only. No interaction with the +# shadowed session is possible. +# +#ENABLE_INTERACTIVE_SESSION_SHADOWING=1 + +# +# Enable or disable clipboard: +# +# client: The content copied on the client can be pasted inside the +# NX session. +# +# server: The content copied inside the NX session can be pasted +# on the client. +# +# both: The copy&paste operations are allowed both between the +# client and the NX session and vice-versa. +# +# none: The copy&paste operations between the client and the NX +# session are never allowed. +# +#ENABLE_CLIPBOARD="both" + + +# +# Enable or disable the pulldown dialog, which provides a graphical +# way to suspend or terminate the rootless session: +# +# 1: Enabled. The pulldown menu is shown when the mouse pointer +# moves near the middle of the top boundary of a window and +# allows the user to suspend or terminate the session by means +# of an icon-click. +# +# 0: Disabled. The ctrl+alt+T key combination has to be issued +# to get the dialog for suspending or terminating the session. +# +#ENABLE_PULLDOWN_MENU=1 + +# If you set ENABLE_ADVANCED_SESSION_CONTROL=1 you can start a new application +# in an already running rootless session by using "add " as +# session name. +# +# Note: The client will return a message on that. +# +#ENABLE_ADVANCED_SESSION_CONTROL=0 + +# If you set ENABLE_SHOW_RUNNING_SESSIONS=0 then nxserver will only show +# suspended sessions and you will not be able to resume or terminate a running +# session. +# dimbor: for autoreconnect must set to 0 +# +#ENABLE_SHOW_RUNNING_SESSIONS=0 + +# If value of this option not empty (valid dir) "run-acl" system is switch on: +# On session start (node_find_application) called acl check process. +# ACL-files in NX_ACL_DIR describes user/group permissions for given cmdstr. +# ACL filenames are usernames, groupnames and "all". Permissions search order: +# user - group - all. See $NX_ETC_DIR/acls/README for detail +# After change of NX_ACL_DIR running 'nxsetup --mkdb' is required +# Example: NX_ACL_DIR="/etc/nxserver/acls" +#NX_ACL_DIR="" + +# Default acl warning message. +#NX_ACL_WARN="Access denied!" diff --git a/conf/conf.d/03-logging.conf b/conf/conf.d/03-logging.conf new file mode 100644 index 0000000..7dd734a --- /dev/null +++ b/conf/conf.d/03-logging.conf @@ -0,0 +1,24 @@ +######################################################################### +# Logging directives +######################################################################### + +# This directives controls the verbosity of the server-wide log. +# 0/1: No Logging/Logging +#NX_LOG_LEVEL=0 + +# Before turning logging on, please make sure that NX_LOGFILE is +# writeable for the "nx" user +#NX_LOGFILE=/var/log/nxserver.log + +# This directive controls if the temporary session directory +# ($HOME/.nx/C---) should be kept after a +# session has ended. A successfully terminated session will be saved as +# T-C--- while a failed session will be saved +# as F-C---. +# The default is to cleanup the directories. +#SESSION_LOG_CLEAN=1 + +# Amount of seconds nxserver is to keep session history. The default of 2592000 +# is equivalent to 30 days. If this is 0 no session history will be kept +# and a negative value denotes infinity. +#SESSION_HISTORY=2592000 diff --git a/conf/conf.d/04-balancing.conf b/conf/conf.d/04-balancing.conf new file mode 100644 index 0000000..179a4b4 --- /dev/null +++ b/conf/conf.d/04-balancing.conf @@ -0,0 +1,31 @@ + +# LOAD BALANCING +# ============== +# +# To do load balancing setup some hosts in LOAD_BALANCE_SERVERS and +# make: +# +# - either sure that all incoming connections are sent to the master +# server by using forwarding directives on the "slave" servers. +# +# - or share the session database space via NFS between the servers. +# (not recommended at the moment as race conditions for DISPLAYs can +# occur) +# +#LOAD_BALANCE_SERVERS="" + +# The following load_balance_algorithms are available at the moment: +# +# "load", "round-robin", "random" +# +# For "load" you need a script called nxcheckload in PATH_BIN. +# +# A sample script, which you can change to your needs it shipped with +# FreeNX under the name nxcheckload.sample. +#LOAD_BALANCE_ALGORITHM="random" + +# By setting ENABLE_LOADBALANCE=1 you can let users choose their +# preferred host, while being forwarded to another server. Of course +# this is just a preference. The loadbalancing algorithm can completely +# choose to ignore the users choice. +#ENABLE_LOAD_BALANCE_PREFERENCE=0 diff --git a/conf/conf.d/05-sound.conf b/conf/conf.d/05-sound.conf new file mode 100644 index 0000000..5fb2fcf --- /dev/null +++ b/conf/conf.d/05-sound.conf @@ -0,0 +1 @@ +# is empty diff --git a/conf/conf.d/06-path.conf b/conf/conf.d/06-path.conf new file mode 100644 index 0000000..57e3f81 --- /dev/null +++ b/conf/conf.d/06-path.conf @@ -0,0 +1,116 @@ +######################################################################### +# Path directives +######################################################################### + +# Add the nx libraries to LD_LIBRARY_PATH before starting nx agents. +# WARNING: This will NOT (and should not) affect applications. ONLY Disable +# this if the nx libraries are in a standard system path (such as /usr/lib)! +#SET_LD_LIBRARY_PATH=0 + +# The command binary for the default window manager. If set it is run when a +# 'unix-custom' session is requested by the NX Client and an application +# to run is specified. It defaults to empty (ie no WM is run). +# If KILL_DEFAULT_X_WM is set the WM is terminated after the started +# application finishes. Else FreeNX will wait for the WM to complete. +#DEFAULT_X_WM="" +#KILL_DEFAULT_X_WM=1 + +# When a 'unix-default' session is requested by the client the user's X startup +# script will be run if pressent and executable, otherwise the default X +# session will be run. +# Depending on distribution USER_X_STARTUP_SCRIPT might be .Xclients, .xinitrc +# and .Xsession +# Depending on distribution DEFAULT_X_SESSION might be /etc/X11/xdm/Xsession, +# /etc/X11/Sessions/Xsession or /etc/X11/xinit/xinitrc +#USER_X_STARTUP_SCRIPT=.Xclients +#DEFAULT_X_SESSION=/etc/X11/Xsession +#COMMAND_GDM_X_SESSION="/etc/X11/gdm/Xsession custom" + +# When the session is started some distros execute some scripts to get the +# environment ready. Set 1 if you want DEFAULT_X_SESSION to be called before +# executing the session. +#BOOTSTRAP_X_SESSION=0 + +# The key that contains the name of the script that starts a KDE session. +# It's run when a 'unix-kde' session is requested by the client. +# Default is "startkde" +#COMMAND_START_KDE=startkde + +# The key that contains the name of the script that starts a gnome session. +# It's run when a 'unix-gnome' session is requested by the client. +# Default is "gnome-session" +#COMMAND_START_GNOME=gnome-session + +# The key that contains the name of the script that starts a CDE session. +# It's run when a 'unix-cde' session is requested by the client. +#COMMAND_START_CDE=cdwm + +#COMMAND_NXAGENT=nxagent + +# The key that contains the name of the complete path of command name +# 'xterm'. It is run when a unix "xterm" session is requested by the +# client. +#COMMAND_XTERM=xterm + +# The key that contains the name of the complete path of command name +# 'xauth'. +#COMMAND_XAUTH=xauth + +# The key that contains the name of the complete path of command name +# 'sudo'. +#COMMAND_SUDO=sudo + +# The key that contains the name of the complete path of command name +# 'mount'. +#COMMAND_MOUNT_LIST=mount + +# The key that contains the name of the complete path of command name +# 'mount.cifs'. +#COMMAND_SMBMOUNT=mount.cifs + +# The key that contains the name of the complete path of command name +# 'umount.cifs'. +#COMMAND_SMBUMOUNT=umount + +# The key that contains the name of the complete path of the 'netcat' command. +#COMMAND_NETCAT=netcat + +# The key that contains the name of the complete path of the 'ssh' and +# 'ssh-keygen' command. +#COMMAND_SSH=ssh + +#COMMAND_SSH_KEYGEN=ssh-keygen + +# The tool to generate md5sums with +#COMMAND_MD5SUM=md5sum + +# The key that contains the name of the complete path of the 'rdesktop' command. +#COMMAND_RDESKTOP=rdesktop + +# The key that contains the name of the complete path of the 'vncviewer' command. +#COMMAND_VNCVIEWER=vncviewer + +#COMMAND_NXCHECKLOAD="nxcheckload" + +# The key that contains the name of the complete path of the 'vncpasswd' command. +# By default the builtin nxpasswd is used. +#COMMAND_VNCPASSWD=nxpasswd + +#COMMAND_SESSREG=sessreg + +# Command for cp converting +#COMMAND_ICONV=iconv + +# Commands for hiding/unhiding passwords +#COMMAND_HIDE=base64 +#COMMAND_UNHIDE="base64 -d" + +# Command to get process list +#COMMAND_PS=ps + +# Commands to pulseaudio control +#COMMAND_PA=pulseaudio +#COMMAND_PACTL=pactl + +# Application to display X message. +#COMMAND_XMSG="nxdialog --dialog ok --caption 'freenx server' --message" diff --git a/conf/conf.d/07-misc.conf b/conf/conf.d/07-misc.conf new file mode 100644 index 0000000..3717885 --- /dev/null +++ b/conf/conf.d/07-misc.conf @@ -0,0 +1,42 @@ +######################################################################### +# Misc directives +######################################################################### + +# When set to 1 this will automatically resume started sessions +#ENABLE_AUTORECONNECT=1 + +# When set to 1 exports NXUSERIP / NXSESSIONID in nxnode +#EXPORT_USERIP=1 +#EXPORT_SESSIONID=1 + +# This can be set to any executable, which is started after session startup +# like: $NODE_AUTOSTART {start|restore} +#NODE_AUTOSTART="" + +# When set to 1 will start nxagent in rootless mode. +#ENABLE_ROOTLESS_MODE=1 + +# If enabled writes entries via the COMMAND_SESSREG program +# into utmp/wtmp/lastlog database. +# Note: You have to make sure that you add the nx user to the +# utmp or tty group or how its called on your system +# before this directive works. +#ENABLE_USESSION=1 + +# Extra options to vncviewer command. Default are for tigervnc-viewer +#EXTRA_OPTIONS_RFB="-Shared" + +# Extra options to rdesktop command. Default are for xfreerdp +#EXTRA_OPTIONS_RDP="/cert-ignore /kbd:0x00000409 /home-drive +clipboard" + +# Time to sleep before calling terminate nxagent +#NODE_APP_WAIT_TIMEOUT=3 + +# Force terminate session if NODE_APP_WAIT_TIMEOUT ends +#ENABLE_ROOTLESS_TERMINATE_SESSION=0 + +# In case ENABLE_ROOTLESS_TERMINATE_SESSION=1 if starting apps found +# in APP_WAIT_MAP then appropriate processes will be controlled of. +# Further nxnode will wait for them completion after main app finished. +# Format: "app_name1:sname1[,sname2...][;app_name2:sname3[,sname4...][;...]]" +#APP_WAIT_MAP="" diff --git a/conf/conf.d/08-bash.conf b/conf/conf.d/08-bash.conf new file mode 100644 index 0000000..340c409 --- /dev/null +++ b/conf/conf.d/08-bash.conf @@ -0,0 +1,11 @@ +# If SOURCE_SYS_PROFILE is not empty and readable FreeNX will source +# it before application startup as we are kind of a login shell. +# default: /etc/profile +#SOURCE_SYS_PROFILE="/etc/profile" + +# If SOURCE_BASH_USER_PROFILE is not empty and readable FreeNX will source +# it before application startup as we are kind of a login shell. +# Please use absolute path or short file name. +# default: .profile +#SOURCE_USER_PROFILE=".profile" + diff --git a/conf/conf.d/09-cups.conf b/conf/conf.d/09-cups.conf new file mode 100644 index 0000000..4af936c --- /dev/null +++ b/conf/conf.d/09-cups.conf @@ -0,0 +1,26 @@ +# System CUPS with sudo is used. +# put drivers to /etc/nxserver/ppd dir (more info in +# http://unixforum.org/index.php?showforum=89) + +# Our own CUPS ppd dir +#NX_PPD_DIR=$NX_ETC_DIR/ppd + +# Commands to CUPS control + +#COMMAND_LPINFO=lpinfo + +#COMMAND_LPSTAT=lpstat + +#COMMAND_LPADMIN="lpadmin" + +#COMMAND_PPDCAT=/usr/lib/cups/daemon/cups-driverd + +#CUPS_DEFAULT_SOCK=/var/run/cups/cups.sock + +# for check cups backends only + +#CUPS_BACKEND=/usr/lib/cups/backend + +#CUPS_IPP_BACKEND=$CUPS_BACKEND/ipp + +#CUPS_NXSMB_BACKEND=$CUPS_BACKEND/nxsmb diff --git a/conf/conf.d/10-samba.conf b/conf/conf.d/10-samba.conf new file mode 100644 index 0000000..dd41ab3 --- /dev/null +++ b/conf/conf.d/10-samba.conf @@ -0,0 +1,16 @@ +# FreeNX with ENABLE_SAMBA_PRELOAD=1 will automatically setup +# port 445 and 139 and forward them to the used samba port. +# +# This enables samba browsing to the local subnet in for example +# konqueror. +# +#ENABLE_SAMBA_PRELOAD=0 + +# Additional mount options for mount command (mount.cifs) +#SMB_MOUNT_OPTIONS="vers=2.1,iocharset=utf8,file_mode=0660,dir_mode=0770" + +# How to inteprete international symbols in win-client resource-names. +# Contains none,one or more charsets pairs - arguments "[from]>[to]" of iconv command. +# if none, it's equivalent of system charset, +# eg ">cp1252 cp1251>" == "latin1>cp1252 cp1251>UTF-8" +#WIN_CP_CONVERT_CHAIN="" diff --git a/conf/conf.d/11-nxagent.conf b/conf/conf.d/11-nxagent.conf new file mode 100644 index 0000000..932c230 --- /dev/null +++ b/conf/conf.d/11-nxagent.conf @@ -0,0 +1,10 @@ +#AGENT_EXTRA_OPTIONS_X="-nolisten tcp -dpi 96" + +# The number of seconds we wait for the nxagent to start before +# deciding startup has failed +#AGENT_STARTUP_TIMEOUT=15 + +# The font server the agent will use. If set to "" no font server is used. +# For this to do any good, the client has to have the same font server set +# in /etc/X11/XF86Config +#AGENT_FONT_SERVER="" diff --git a/conf/conf.d/12-nxproxy.conf b/conf/conf.d/12-nxproxy.conf new file mode 100644 index 0000000..d9097c6 --- /dev/null +++ b/conf/conf.d/12-nxproxy.conf @@ -0,0 +1,10 @@ +# Disable or enable use of 'tcp nodelay' on proxy. Old versions of Linux +# kernels have problems using this option on sockets that will cause a loss +# of TCP connections. This option is not set by default to allow clients to +# specify whether to enable or disable TCP nodelay. Setting this option to +# the value of 0 NX proxy avoids using 'tcp nodelay' but it will cause a +# loss of interaction in sessions. +#PROXY_TCP_NODELAY="" + +# Extra options to nxproxy. See !M documentation for useful parameters. +#PROXY_EXTRA_OPTIONS="" diff --git a/conf/conf.d/50-numlockx.conf b/conf/conf.d/50-numlockx.conf new file mode 100644 index 0000000..9adb30a --- /dev/null +++ b/conf/conf.d/50-numlockx.conf @@ -0,0 +1,8 @@ +# Binary filename provides numlockx +#NUMLOCKX=numlockx + +# numlockx run strategy. valid value are: +# 'on' -- run 'numlockx on' at session startup +# 'off' -- run 'numlockx off' at session startup +# 'system' -- default. don't run numlockx +#NUMLOCK_METHOD="system" diff --git a/conf/node.conf b/conf/node.conf new file mode 100644 index 0000000..7a91859 --- /dev/null +++ b/conf/node.conf @@ -0,0 +1 @@ +# See /etc/nxserver/node.conf.d/*.conf diff --git a/data/99-debian-dimbor.conf b/data/99-debian-dimbor.conf new file mode 100644 index 0000000..8e772ab --- /dev/null +++ b/data/99-debian-dimbor.conf @@ -0,0 +1,22 @@ +# kill warnings +COMMAND_START_CDE="/bin/false" +COMMAND_START_KDE="/bin/false" +COMMAND_START_GNOME="/bin/false" + +# my settings +DISPLAY_BASE=4000 +WIN_CP_CONVERT_CHAIN=">cp1252 cp1251>" +#ENABLE_DIRECT_NATIVE_PA_CHECK="1" + + +NX_LOG_LEVEL=1 +SESSION_LOG_CLEAN=0 +COMMAND_XTERM="/usr/bin/xfce4-terminal --hide-menubar --geometry 80x40" +#AGENT_EXTRA_OPTIONS_X="-nolisten tcp -dpi 120" +#AGENT_EXTRA_OPTIONS_X="-forcenx" + +EXTERNAL_PROXY_IP="192.168.1.86" + +ENABLE_ROOTLESS_TERMINATE_SESSION="1" +NODE_APP_WAIT_TIMEOUT="2" +APP_WAIT_MAP="1c8.sh:1cv8s;test.sh:xfce4-terminal" diff --git a/data/Xkbmap b/data/Xkbmap new file mode 100644 index 0000000..80eca52 --- /dev/null +++ b/data/Xkbmap @@ -0,0 +1,2 @@ +-layout en_US,ru(winkeys) +-option grp:ctrl_shift_toggle,grp_led:scroll diff --git a/data/Xsession b/data/Xsession new file mode 100755 index 0000000..f52d70e --- /dev/null +++ b/data/Xsession @@ -0,0 +1,222 @@ +#!/bin/bash -login +# +# Copyright (C) 2002-2006 Dmitry V. Levin +# +# Traditional X session start script. +# +# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +# + +PROG="${0##*/}" + +if [ -z "$DISPLAY" ]; then + echo "$PROG: \$DISPLAY undefined." >&2 + exit 1 +fi + +# Emulate which(1) internally. +absolute() +{ + local WHICH + + [ -n "$1" ] || return 1 + WHICH="$(type -p "$1")" || return 1 + [ "$WHICH" != "${WHICH##/}" ] || return 1 + [ -x "$WHICH" ] || return 1 + + printf %s "$WHICH" +} + +SourceIfNotEmpty() +{ + local f="$1" + shift + [ -s "$f" ] && . "$f" "$@" +} + +RunIfExecutable() +{ + local f="$1" + shift + f="$(absolute "$f")" && [ -x "$f" ] && "$f" "$@" +} + +ExecIfExecutable() +{ + local f="$1" + shift + f="$(absolute "$f")" && [ -x "$f" ] && exec "$f" "$@" +} + +f="$HOME/.xsession-errors" +[ -z "${DISPLAY##:*}" ] && f="$f$DISPLAY" || f="$f-$DISPLAY" + +# Redirect errors to a file. +for errfile in "$f" "$HOME/.xsession-errors"; do + if install -m600 /dev/null "$errfile" 2>/dev/null; then + exec &>"$errfile" + break + fi +done + +unset f + +echo "Running $PROG[$$] $*" + +if [ $# -ge 1 ]; then + # Clean up after xbanner. + RunIfExecutable freetemp +else + # ALT default background and cursor. + xsetroot -solid "#666699" + xsetroot -cursor_name left_ptr +fi + +if [ -n "$LANGUAGE" ]; then + try_lang="$LANGUAGE" +elif [ -n "$LANG" ]; then + try_lang="$LANG" +else + try_lang= +fi + +Xrdb() +{ + if [ -s "$1" ]; then + xrdb -merge "$1" + return 0 + else + return 1 + fi +} + +MergeResources() +{ + local f + for f in "$@"; do + Xrdb "$f" + local found= + local n + for n in `printf %s "$try_lang" |tr : ' '`; do + n1="${n%.*}" + n2="${n1%_*}" + Xrdb "$f.$n2" && found=1 + Xrdb "$f.$n1" && found=1 + Xrdb "$f.$n" && found=1 + [ -z "$found" ] || break + done + done +} + +# Merge in defaults and keymaps. +if [ -d /etc/X11/Xresources ]; then + Xresources_d=$(ls /etc/X11/Xresources) + MergeResources $Xresources_d "$HOME/.Xresources" "$HOME/.Xdefaults" +else + MergeResources /etc/X11/Xresources "$HOME/.Xresources" "$HOME/.Xdefaults" +fi + +TryXBrowser() +{ + local n + for n in "$@"; do + if n=`absolute "$n"`; then + export BROWSER="$n" + break + fi + done + return 0 +} + +TryTextBrowser() +{ + local n + for n in "$@"; do + if n=`absolute "$n"`; then + export BROWSER="xvt -e $n" + break + fi + done + return 0 +} + +# We need to set default browser. +# Window manager may redefine this setting. +if [ -z "$BROWSER" ] || [ ! -x "$BROWSER" ]; then + TryXBrowser xbrowser mozilla firefox konqueror +fi + +if [ -z "$BROWSER" ] || [ ! -x "$BROWSER" ]; then + TryTextBrowser browser links lynx +fi + +if [ -z "$BROWSER" ] || [ ! -x "$BROWSER" ]; then + export BROWSER= +fi + +export HELP_BROWSER="$BROWSER" + +# Source shell scripts from user ~/.xprofile +SourceIfNotEmpty "$HOME"/.xprofile "$@" + +# Run system scripts from /etc/X11/xinit.d/ +for f in /etc/X11/xinit.d/*; do + # Don't run *.rpm* and *~ scripts + [ "${f%.rpm*}" = "$f" -a "${f%\~}" = "$f" ] || continue + + if [ -x "$f" ]; then + "$f" & + fi +done + +# Run user scripts from ~/.xsession.d/ +for f in "$HOME"/.xsession.d/*; do + # Don't run *.rpm* and *~ scripts + [ "${f%.rpm*}" = "$f" -a "${f%\~}" = "$f" ] || continue + + if [ -x "$f" ]; then + "$f" & + fi +done + +unset f + +RunIfExecutable /etc/nxserver/fixkeyboard + +RunIfExecutable /etc/X11/xinit/xrandrrc +RunIfExecutable /etc/X11/xinit/fixkeyboard +RunIfExecutable /etc/X11/xinit/XIM + +CMD="" +#ssh-agent doesnt start +[ -z "$SSH_AGENT_PID" ] && CMD="$CMD /usr/bin/ssh-agent" +[ -z "$DBUS_SESSION_BUS_ADDRESS" ] && CMD="$CMD /usr/bin/dbus-launch --exit-with-session" + +if [ $# -ge 1 ]; then + $CMD "$@" +else + # Try user defined action. + RunIfExecutable "$HOME/.xsession" + RunIfExecutable "$HOME/.Xclients" + + # Try WM Selector. + RunIfExecutable wm-select + + # Try WM Manager. + RunIfExecutable wmselect + + # Try default from runwm. + runwm default +fi diff --git a/data/fixkeyboard b/data/fixkeyboard new file mode 100755 index 0000000..2e890da --- /dev/null +++ b/data/fixkeyboard @@ -0,0 +1,19 @@ +#!/bin/sh +# Startup script called from /etc/X11/Xsession and /etc/X11/xdm/Xsetup_0 +# to adjust keyboard. + +usermodmap="$HOME/.Xmodmap" +userxkbmap="$HOME/.Xkbmap" + +sysmodmap=/etc/nxserver/Xmodmap +sysxkbmap=/etc/nxserver/Xkbmap + +if xdpyinfo |fgrep -qs XKEYBOARD; then + [ -s "$sysxkbmap" ] && setxkbmap `cat "$sysxkbmap"` + [ -s "$userxkbmap" ] && setxkbmap `cat "$userxkbmap"` +fi + +[ -s $sysmodmap ] && xmodmap "$sysmodmap" +[ -s $usermodmap ] && xmodmap "$usermodmap" + +exit 0 diff --git a/data/logrotate b/data/logrotate new file mode 100644 index 0000000..08ba171 --- /dev/null +++ b/data/logrotate @@ -0,0 +1,8 @@ +/var/log/nxserver.log { + rotate 4 + size=1M + notifempty + missingok + sharedscripts + copytruncate +} diff --git a/data/sudoers.conf b/data/sudoers.conf new file mode 100644 index 0000000..9c708a1 --- /dev/null +++ b/data/sudoers.conf @@ -0,0 +1,11 @@ +Defaults:nx targetpw,passwd_tries=1,timestamp_timeout=0.3,umask=0777 +nx ALL= (%users) /bin/bash -c /usr/bin/nxnode * + +User_Alias ADMINS = %nxadmin +User_Alias USERS = %users + +ADMINS ALL= NOPASSWD: /bin/bash -c /usr/bin/nxserver --admin +USERS ALL= NOPASSWD: /usr/sbin/lpadmin + +USERS ALL= NOPASSWD: /sbin/mount.cifs +USERS ALL= NOPASSWD: /bin/umount diff --git a/data/terminate-suspend-nx.sh b/data/terminate-suspend-nx.sh new file mode 100755 index 0000000..015724a --- /dev/null +++ b/data/terminate-suspend-nx.sh @@ -0,0 +1,22 @@ +#!/bin/bash + + +[ -e /etc/sysconfig/freenx-server ] && . /etc/sysconfig/freenx-server + +SESSION_TTL=${SESSION_TTL:-3600} +nxdir="/var/lib/nxserver/db/running" +nxserver="/usr/bin/nxserver" +if [ -d "$nxdir" -a $SESSION_TTL -gt 0 ] ; then + for f in `ls $nxdir` ; do + sessiontype=`cat $nxdir/$f | grep status | cut -d= -f2` + user=`cat $nxdir/$f | grep userName | cut -d= -f2` + sessiontime=`cat $nxdir/$f | grep creationTime | cut -d= -f2` + sessionid=`cat $nxdir/$f | grep sessionId | cut -d= -f2` + criticaltime=$(expr `date +%s` - $SESSION_TTL) + if [ $sessiontime -lt $criticaltime ] ; then + if [ $sessiontype = "Suspended" ] ; then + $nxserver --terminate $sessionid + fi + fi + done +fi \ No newline at end of file diff --git a/debian/README.Debian b/debian/README.Debian new file mode 100644 index 0000000..eb09e80 --- /dev/null +++ b/debian/README.Debian @@ -0,0 +1,8 @@ +freenx for Debian + +Please edit this to provide information specific to +this freenx Debian package. + + (Automatically generated by debmake Version 4.2.9) + + -- Dmitry Borisov Fri, 27 Dec 2019 00:21:36 +0300 diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..0625b3b --- /dev/null +++ b/debian/changelog @@ -0,0 +1,37 @@ +freenx-server (2.1.3) UNRELEASED; urgency=low + + * Fixing a funny misunderstanding with localization. + + -- Dmitry Borisov Wed, 08 Nov 2023 02:40:25 +0300 + +freenx-server (2.1.2) UNRELEASED; urgency=low + + * Fix ACL parsing (no globbing). + + -- Dmitry Borisov Tue, 05 Sep 2023 06:48:35 +0300 + +freenx-server (2.1.1) UNRELEASED; urgency=low + + * Shadow mode add view only on client request. + * nxshadowacl add new keyword 'all'. + + -- Dmitry Borisov Sun, 19 Jun 2022 12:07:23 +0300 + +freenx-server (2.1.0) UNRELEASED; urgency=low + + * Shadow mode is worked now. + * Readd nxshadowacl functionality. + + -- Dmitry Borisov Thu, 16 Jun 2022 22:39:43 +0300 + +freenx-server (2.0.0) UNRELEASED; urgency=low + + * Release with sqlite3 db engine. + + -- Dmitry Borisov Fri, 27 May 2022 20:04:11 +0300 + +freenx-server (1.0.0) UNRELEASED; urgency=low + + * Initial release. + + -- Dmitry Borisov Fri, 27 Dec 2019 00:21:36 +0300 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +9 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..2d6c4d3 --- /dev/null +++ b/debian/control @@ -0,0 +1,36 @@ +Source: freenx-server +Section: x11 +Priority: optional +Maintainer: Dmitry Borisov +Build-Depends: debhelper (>=9), xutils-dev +Standards-Version: 3.9.8 +Homepage: https://unixforum.org/viewforum.php?f=89 + +Package: freenx-server +Architecture: any +Multi-Arch: foreign +Depends: + openssh-server, + libnx-x11-6 (>= 3.5.0), + libxcomp3 (>= 3.5.0), + nxagent (>= 3.5.0), + nxproxy (>= 3.5.0), + expect, + sudo, + zenity, + x11-xserver-utils, + x11-xkb-utils, + x11-utils, + gettext, + sqlite3 +Recommends: cups, samba, pulseaudio, tigervnc-viewer, freerdp-x11 +Description: Evolution of Freenx application/thin-client server + Freenx is an application/thin-client server based on nx technology. + NoMachine nx is the next-generation X compression and roundtrip suppression + scheme. It can operate remote X11 sessions over 56k modem dialup links + or anything better. This package contains a free (GPL) implementation + of the nxserver component. + Added features of community: printers/shares multimount, cups-server + system mode, direct and tunnelled pulseaudio sound, acls on user's level + ... etc. Thats all worked with opennx ce client, but original nxclient + basicaly alive too. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..987a247 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,347 @@ +This package was debianized by Dmitry Borisov on + +Copyright: 2005 Fabian Franz + 2005 Jon Severinsson + 2008-2019 Dmitry Borisov + +License: GPL-2.0 + 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. diff --git a/debian/freenx-server.postinst b/debian/freenx-server.postinst new file mode 100644 index 0000000..c9254ac --- /dev/null +++ b/debian/freenx-server.postinst @@ -0,0 +1,49 @@ +#!/bin/sh +# postinst script for opennx +# +# see: dh_installdeb(1) + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-remove' +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + configure|triggered) + PBIN="/usr/bin" + groupadd nx 2>/dev/null + groupadd nxadmin 2>/dev/null + useradd -g nx -G utmp -d /var/lib/nxserver/home/ \ + -s $PBIN/nxserver -c "NX System User" nx 2>/dev/null + chown nx:root $PBIN/nx-session-launcher-suid + chmod 4755 $PBIN/nx-session-launcher-suid + chown :users /etc/nxserver/ppd + chown nx:nx /var/lib/nxserver/home + chown nx:nx /var/lib/nxserver/db + sessdb="/var/lib/nxserver/db/sessions.sq3" + [ -f "$sessdb" ] && rm -f "$sessdb" 2>/dev/null + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..f2244f7 --- /dev/null +++ b/debian/rules @@ -0,0 +1,6 @@ +#!/usr/bin/make -f + +export DH_VERBOSE=1 + +%: + dh $@ diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/dists/alt/99-altlinux.conf b/dists/alt/99-altlinux.conf new file mode 100644 index 0000000..08fa7ce --- /dev/null +++ b/dists/alt/99-altlinux.conf @@ -0,0 +1,4 @@ +# override defaualts for altlinux +CUPS_ETC=/usr/share/cups/mime +DEFAULT_X_SESSION=/etc/X11/Xsession +COMMAND_START_GNOME="startgnome2" diff --git a/dists/alt/rx-etersoft.spec b/dists/alt/rx-etersoft.spec new file mode 100644 index 0000000..6dc7333 --- /dev/null +++ b/dists/alt/rx-etersoft.spec @@ -0,0 +1,440 @@ +%define cups_root %_prefix/lib +%define oname freenx-server +Name: rx-etersoft +Version: 1.1.1 +Release: alt13 + +Summary: Freenx application/thin-client server +Group: Networking/Remote access +License: GPLv2 +Url: http://wiki.etersoft.ru/RX + +Packager: Denis Baranov + +Source: ftp://updates.etersoft.ru/pub/Etersoft/RX@Etersoft/unstable/sources/tarball/%oname-%version.tar.bz2 +Source1: %oname.init +Source2: %oname.outformat +Source6: sudoers.conf +Source8: terminate-suspend-nx.sh +Source10: 99-altlinux.conf + +Obsoletes: freenx +Provides: freenx = %version + +Obsoletes: %oname +Provides: %oname = %version + +Requires: nx +Requires: openssl +Requires: netcat +Requires: expect +Requires: foomatic-db-engine +Requires: zenity +%if %_vendor == "alt" +Requires: dbus-tools-gui +# FIXME: it needs for strings command, need to be removed +Requires: binutils +#Requires: Xdialog +# FIXME: for which purposes? +#Requires: /usr/bin/xvt +%endif + +BuildPreReq: rpm-build-intro +BuildRequires: imake xorg-cf-files gccmakedep xauth openssh-server + +%description +Freenx is an application/thin-client server based on nx technology. +NoMachine nx is the next-generation X compression and roundtrip suppression +scheme. It can operate remote X11 sessions over 56k modem dialup links +or anything better. This package contains a free (GPL) implementation +of the nxserver component. + +%prep +%setup -n %oname-%version +# wrong install path +%__subst "s|/usr/lib|%_libdir|g" nxredir/Makefile +%__subst "s|%_libdir/cups|%cups_root/cups|g" Makefile +# install use nxloadconfig +%__subst "s|/usr/lib|%_libdir|g" nxloadconfig +%__subst "s|%_libdir/cups|%cups_root/cups|g" nxloadconfig +%__subst "s|\$NX_DIR/lib|%_libdir|g" nxloadconfig +# nxredir nxsmb +%__subst "s|/usr/lib|%_libdir|g" nxredir/nxredir +%__subst "s|/usr/lib|%_libdir|g" nxredir/nxsmb +%__subst "s|/usr/lib|%_libdir|g" %SOURCE10 +%__subst "s|%_libdir/cups|%cups_root/cups|g" nxredir/nxsmb + +%build +%make_build + +%install +%makeinstall_std +mkdir -p %buildroot%_bindir/ +mkdir -p %buildroot%_var/lib/nxserver/home/ +mkdir -p %buildroot%_var/lib/nxserver/db/ +mkdir -p %buildroot%_sysconfdir/nxserver/node.conf.d/ +mkdir -p %buildroot%_sysconfdir/nxserver/acls/ +mkdir -p %buildroot%_datadir/%oname/node.conf.d/ +mkdir -p %buildroot%_sysconfdir/sysconfig/ + + +echo "# See /etc/nxserver/node.conf.d/*.conf" > node.conf + +install -m755 rxsetup %buildroot%_bindir/ +install -Dp -m755 %SOURCE1 %buildroot%_initdir/%oname +install -Dp -m755 data/fixkeyboard %buildroot%_sysconfdir/nxserver/fixkeyboard +install -Dp -m755 data/Xsession %buildroot%_sysconfdir/nxserver/Xsession +install -Dp -m644 data/Xkbmap %buildroot%_sysconfdir/nxserver/Xkbmap +install -Dp -m400 %SOURCE6 %buildroot%_sysconfdir/sudoers.d/nxserver +install -Dp -m700 %SOURCE8 %buildroot%_bindir/terminate-suspend-nx +install -Dp -m644 node.conf %buildroot%_sysconfdir/nxserver/node.conf +install -m644 conf/conf.d/*.conf %buildroot%_datadir/%oname/node.conf.d +install -m644 conf/conf.d/*.conf %buildroot%_sysconfdir/nxserver/node.conf.d +install -m644 conf/acls/* %buildroot%_sysconfdir/nxserver/acls +%if %_vendor == "alt" +install -m644 %SOURCE10 %buildroot%_sysconfdir/nxserver/node.conf.d/ +%else +install -m755 %SOURCE2 %buildroot%_initdir/ +%endif + +install -Dp -m644 data/logrotate %buildroot%_sysconfdir/logrotate.d/freenx-server +install -Dp -m644 nx-session-launcher/ConsoleKit-NX.conf %buildroot%_sysconfdir/dbus-1/system.d/ConsoleKit-NX.conf +mv nx-session-launcher/README nx-session-launcher/README.suid + +cat >> %buildroot%_sysconfdir/sysconfig/%oname << EOF +#Time to live SUSPENDED freenx session in seconds for cron task. +#If not set default value is 3600. +#Cron task enable if value greater than 0. +SESSION_TTL=0 +EOF + +%pre +%groupadd nx 2> /dev/null ||: +%useradd -g nx -G utmp -d /var/lib/nxserver/home/ -s %_bindir/nxserver \ + -c "NX System User" nx 2> /dev/null ||: +# FIXME: remove it strange code +if [ ! -d %_datadir/fonts/misc ] && [ ! -e %_datadir/fonts/misc ] && [ -d %_datadir/fonts/bitmap/misc ] +then + ln -s %_datadir/fonts/bitmap/misc %_datadir/fonts/misc +fi + +%files +%doc AUTHORS ChangeLog CONTRIB nxcheckload.sample node.conf.sample nx-session-launcher/README.suid +%dir %_sysconfdir/nxserver/ +%dir %_sysconfdir/nxserver/node.conf.d/ +%dir %_sysconfdir/nxserver/acls/ +%config(noreplace) %_sysconfdir/nxserver/node.conf +%config(noreplace) %_sysconfdir/nxserver/node.conf.d/* +%config(noreplace) %_sysconfdir/nxserver/acls/* +%_sysconfdir/nxserver/node.conf.sample +%config(noreplace) %_sysconfdir/logrotate.d/freenx-server +%attr(0400,root,root) %config %_sysconfdir/sudoers.d/nxserver +%config(noreplace) %_sysconfdir/dbus-1/system.d/ConsoleKit-NX.conf +%config(noreplace) %_sysconfdir/nxserver/Xkbmap +%_sysconfdir/nxserver/fixkeyboard +%_sysconfdir/nxserver/Xsession +%config(noreplace) %_sysconfdir/sysconfig/%oname +%_sysconfdir/cron.hourly/terminate-suspend-nx.sh +%_initdir/%oname +%if %_vendor == "alt" +%else +%_initdir/%oname.outformat +%endif +%attr(4711,nx,root) %_bindir/nx-session-launcher-suid +%_bindir/nx* +%_bindir/rxsetup +%dir %_libdir/%oname/ +%attr(755,root,root) %_libdir/%oname/libnxredir.so.0 +%cups_root/cups/backend/nx* +%attr(2750,nx,nx) %_var/lib/nxserver/home/ +%attr(2750,root,nx) %_var/lib/nxserver/db/ +%_datadir/%oname/ + +%changelog +* Fri Oct 21 2011 Denis Baranov 1.1.1-alt13 +- add nx-3.5.0 version in check function (eterbug #7728) + +* Thu Sep 01 2011 Denis Baranov 1.1.1-alt12 +- fix requires + +* Thu Aug 04 2011 Denis Baranov 1.1.1-alt11 +- add start kill suspend script every 10 min +- move sudo settings to sudoers.d folder + +* Fri Jan 14 2011 Denis Baranov 1.1.1-alt10 +- Fix error with zenity +- Add message when folder not mount + +* Thu Jan 06 2011 Denis Baranov 1.1.1-alt9 +- rxsetup: add check for expect +- fix error on mount folder with empty password +- fix rxsetup log path +- nxnode: logging is a little faster +- fix endless cycle in node_start_applications() +- new algorithm of share mounting (--smbmount) +- chg start-modes of share/printer adding +- norm_param(): check for iconv, logging switch off +- fix Makefile: add nxacl.app to +- smile acl syntax fix +- upd config to acls check +- add code&configs to acls check + +* Thu Dec 16 2010 Vitaly Lipatov 1.1.1-alt8 +- cleanup spec +- change SMB_MOUNT_OPTIONS again, change links to unixforum.org +- converting smb/cifs resurce-names +- fix check_remote_printer() +- fix for kde4 (merge with git.alt) +- fix node_umount_smb() +- new code to ENABLE_SHARE_MULTIMOUNT=1 or +- nxlog tunning +- rxsetup: disable direct dependency to /etc/init.d (missed on ALT) +- rxsetup write output into log +- update sudoers.conf + +* Tue Oct 12 2010 Denis Baranov 1.1.1-alt7 +- load config files from node.conf.d/ only *.conf + +* Mon Oct 11 2010 Denis Baranov 1.1.1-alt6 +- add autodetect KDE4 by default in conf +- clean node.conf, all values must be override from /etc/nxserver/node.conf.d/*.conf + +* Thu Oct 07 2010 Denis Baranov 1.1.1-alt5 +- change COMMAND_MD5SUM on md5sum +- add in config default DPI=96 (eterbug#6112) + +* Thu Oct 07 2010 Denis Baranov 1.1.1-alt4 +- fix build requeries + +* Fri Oct 01 2010 Denis Baranov 1.1.1-alt3 +- fix requeries + +* Fri Jul 30 2010 Denis Baranov 1.1.1-alt2 +- add support zenity for dialog interface +- add requires zenity + +* Mon Jul 26 2010 Denis Baranov 1.1.1-alt1 +- release RX@Etersoft 1.1.1 + +* Sun Jul 25 2010 Boris Savelev 0.7.4-alt24 +- fix printer forwarding (thx to dimbor and unixforum) +- nxlog now always return '0' + +* Mon Jul 12 2010 Boris Savelev 0.7.4-alt23 +- fix double slashes in nxsmb and nxredir (thx to dimbor) + +* Sun Jul 11 2010 Boris Savelev 0.7.4-alt22 +- Added rxsetup script +- Fixed config replacement +- fix restore session after suspend (eterbug #5704) +- do not source /etc/X11/profile.d/* in freenx Xsession + +* Sun Feb 14 2010 Boris Savelev 0.7.4-alt21 +- move default config set to %_datadir/%name/node.conf.d. + All values must be override from /etc/nxserver/node.conf + and /etc/nxserver/node.conf.d + +* Sun Jan 31 2010 Boris Savelev 0.7.4-alt20.1 +- fix defaults for all +- add 100-altlinux.conf with ALTLinux defaults + +* Sun Jan 31 2010 Boris Savelev 0.7.4-alt20 +- move all config values form node.conf to %_sysconfdir/nxserver/node.conf.d/*.conf + +* Sun Jan 03 2010 Boris Savelev 0.7.4-alt19.7 +- fix permission on /tmp/.X11-unix after creating (fix eter#4653) + +* Sun Jan 03 2010 Boris Savelev 0.7.4-alt19.6 +- fix NETCAT_COMMAND running (fix eter#3818) +- add additional config for profile including during node startup ('on' by default) + +* Tue Dec 29 2009 Boris Savelev 0.7.4-alt19.5 +- fix COMMAND_START_GNOME for ALTLinux (fix eter#4725) +- don't start numlockx during session startup by default. Add additional config for numlockx + +* Wed Dec 02 2009 Eugeny A. Rostovtsev (REAL) 0.7.4-alt19.4.1 +- Rebuilt with python 2.6 + +* Fri Nov 20 2009 Boris Savelev 0.7.4-alt19.4 +- disable terminate-suspend-nx.sh cron task by default + +* Thu Nov 12 2009 Boris Savelev 0.7.4-alt19.3 +- add Requires schedutils for ALT-system (fix eter#4421) +- add cron-script for terminate suspended sessions (fix eter#4436) + +* Wed Oct 07 2009 Boris Savelev 0.7.4-alt19.2 +- fix perm on nxserver sudo config (closes: #21860) + +* Tue Oct 06 2009 Vitaly Lipatov 0.7.4-alt19.1 +- fix mount-additional.conf packing + +* Wed Sep 30 2009 Boris Savelev 0.7.4-alt19 +- add patch for Server mode CUPS + and SMB per-user share mount (from dimbor) + +* Tue Sep 22 2009 Boris Savelev 0.7.4-alt18.12 +- fix CUPSLogLevel config parser + +* Thu Jul 30 2009 Boris Savelev 0.7.4-alt18.11 +- fix restoring suspended sessions + +* Wed Jul 29 2009 Boris Savelev 0.7.4-alt18.10 +- fix new bash regexp syntax + +* Wed Jul 29 2009 Boris Savelev 0.7.4-alt18.9 +- fix new bash regexp syntax + +* Mon Jul 27 2009 Boris Savelev 0.7.4-alt18.8 +- add patch from Mario Becroft (increase nxserver work speed) + +* Mon Jul 27 2009 Boris Savelev 0.7.4-alt18.7 +- increase timeout for hangup session + +* Tue Jul 21 2009 Boris Savelev 0.7.4-alt18.6 +- fix typo in nxnode + +* Tue Jul 21 2009 Boris Savelev 0.7.4-alt18.5 +- fix typo in nxnode. Affected non-ALT systems + +* Tue Jul 14 2009 Boris Savelev 0.7.4-alt18.4 +- add additional conf for mount share and CUPS + +* Sat Jun 13 2009 Boris Savelev 0.7.4-alt18.3 +- xrdb merge /etc/X11/Xresources on startup + +* Tue Jun 09 2009 Boris Savelev 0.7.4-alt18.2 +- use %_bindir/xvt if possible for ALT (ALT#20381) + +* Sat Jun 06 2009 Boris Savelev 0.7.4-alt18.1 +- add requires Xdialog (ALT#20325) + +* Sat Apr 11 2009 Boris Savelev 0.7.4-alt18 +- include patch from Jeffrey J. Kosowsky for CUPS + +* Thu Apr 09 2009 Boris Savelev 0.7.4-alt17 +- 2 small fixes +- move fixkeyboard and etc to /etc/nxserver + +* Tue Mar 10 2009 Boris Savelev 0.7.4-alt16.1 +- fix COMMAND_SMBMOUNT redifines + +* Tue Mar 10 2009 Boris Savelev 0.7.4-alt16 +- build with for new nx + +* Sat Mar 07 2009 Boris Savelev 0.7.4-alt15 +- force umount +- merge with teambzr upstream + +* Fri Feb 27 2009 Boris Savelev 0.7.4-alt14 +- fix export CUPS_SERVER with Win-client + +* Thu Feb 26 2009 Boris Savelev 0.7.4-alt13 +- don't use Xsession for start desktop + +* Wed Feb 25 2009 Boris Savelev 0.7.4-alt12 +- move libnxredir to %%_libdir/%name +- check for first run in init-script + +* Wed Feb 25 2009 Boris Savelev 0.7.4-alt11 +- add bungle for fixkeyboard +- fix perm on libnxredir (hack, will be fixed soon) + +* Sun Feb 22 2009 Boris Savelev 0.7.4-alt10 +- logrotate rule. +- add LSB header. +- patches from Ubuntu. +- implementation of guest login. +- nx-session-launcher: + + add DBUS rules + + fix permission on nx-session-launcher-suid + + add README for nx-session-launcher + +* Fri Feb 20 2009 Boris Savelev 0.7.4-alt9 +- fix nxloadconfig for Etersoft SHARE_FAST_MOUNT + +* Thu Feb 19 2009 Boris Savelev 0.7.4-alt8 +- fix eterbug #3226 (patch from horch) +- add sleeping wait for valid display (fixkeyboard fails) + +* Thu Jan 08 2009 Boris Savelev 0.7.4-alt7 +- fix path to cups backends on x86_64 (alt bug #18462) +- fix path to LOCKDIR on Debian (eter bug #3094) + +* Tue Dec 16 2008 Boris Savelev 0.7.4-alt6 +- fix path to cups +- run "numlockx on" on session start + +* Sun Nov 23 2008 Boris Savelev 0.7.4-alt5 +- fix permission on nx homedir + +* Sat Nov 22 2008 Boris Savelev 0.7.4-alt4 +- add support nx 3.3 + +* Tue Nov 11 2008 Boris Savelev 0.7.4-alt3 +- add /var/lib/nxserver + +* Fri Sep 05 2008 Boris Savelev 0.7.4-alt2 +- Fixed non-encrypted session mode. You might need to set EXTERNAL_PROXY_IP in node.conf. + +* Thu Aug 28 2008 Boris Savelev 0.7.4-alt1 +- Opened the 0.7.4 development. +- Fixed missing export of NX_ETC_DIR in Makefile, so node.conf.sample is installed correctly. +- Fixed broken round-robin load balance algorithm. +- Fixed --terminate|--suspend|--force-terminate for load balancing case. +- Fixed --terminate|--suspend|--force-terminate for usermode case. + +* Sat Aug 23 2008 Boris Savelev 0.7.3-alt3 +- Changed type for external agents to windows-helper or vnc-helper so that those sessions can be mirrored / shadowed as well. +- Added nxshadowacl.sample component to be able to shadow foreign sessions. +- Prepared shadowing foreign users for VNC-shadowing. +- Added shadow support to --listsession command. +- Added shadow mode as nxagent target. +- Fixed shadow mode and made it usable. + +* Mon Aug 18 2008 Boris Savelev 0.7.3-alt2 +- Build from git +- Finally checked for all service ports. (cups, media, samba) and also checked it on the host where the load balancing actually leads to. +- Fixed broken fallback logic if SSH_CLIENT variables cannot be read correctly. +- Overhauled the usermode: +- There are now two modes of operation. +- One statically setting the ENABLE_USERMODE_AUTHENTICATION key in node.conf. (old behavior) +- Or using nxserver-usermode as startup binary, which directly goes into the 103 stage. +- Fixed using commandline parameters like --cleanup for static usermode. +- Enabled the root commandline parameters in usermode. +- Fixed usage of "nx" user as normal user in usermode. +- Disabled slave mode and load balancing for usermode. +- Fixed creation of the logfile directory. +- Fixed nxnode usage of SSH_CLIENT using fallback mechanism. +- Added disabled nxserver-suid wrapper with help from Google. To enable it uncomment the suid_install target in Makefile. +- Automatically disabled slave mode, when load balancing is activated. +- Made ENABLE_SLAVE_MODE="1" the new default as its faster and more reliable. If you encounter any problems with it, disable it in node.conf. + +* Mon Aug 11 2008 Boris Savelev 0.7.3-alt1 +- svn update to r565 +- fix x86_64 build + +* Tue Jul 15 2008 Boris Savelev 0.7.2-alt2 +- svn update to r546 + +* Fri Jun 13 2008 Boris Savelev 0.7.2-alt1 +- new version +- fix altbug #16049 +- new init-script + +* Mon Jan 14 2008 Igor Zubkov 0.7.2-alt5.r430 +- fix path for libXrender + +* Sun Jan 06 2008 Igor Zubkov 0.7.2-alt4.r430 +- fix font path (#13830) + +* Thu Jan 03 2008 Igor Zubkov 0.7.2-alt3.r430 +- update from svn + +* Fri Dec 28 2007 Igor Zubkov 0.7.2-alt2.r427 +- mark %_sysconfdir/nxserver/node.conf a config(noreplace) +- own %_sysconfdir/nxserver dir +- add requires nx + +* Mon Dec 24 2007 Igor Zubkov 0.7.2-alt1.r427 +- build for Sisyphus + diff --git a/dists/gentoo/files/70-gentoo.conf b/dists/gentoo/files/70-gentoo.conf new file mode 100644 index 0000000..a68e1af --- /dev/null +++ b/dists/gentoo/files/70-gentoo.conf @@ -0,0 +1,14 @@ +ENABLE_SLAVE_MODE="0" +ENABLE_SHOW_RUNNING_SESSIONS="0" +#NX_ACL_DIR="/etc/nxserver/acls" +KDE4_ENABLE="0" +COMMAND_START_KDE=/bin/false +COMMAND_START_CDE=/bin/false +COMMAND_START_KDE4=/bin/false +ENABLE_KDE_CUPS="0" +ENABLE_CUPS_SERVER_MODE="1" +SAMBA_MOUNT_SHARE_PROTOCOL="cifs" +ENABLE_SHARE_MULTIMOUNT="1" +COMMAND_SMBMOUNT=/bin/false +COMMAND_SMBUMOUNT=/bin/false +COMMAND_SMBUMOUNT_CIFS="/bin/umount" diff --git a/dists/gentoo/files/nxserver-freenx-0.7.4-nxloadconfig.patch b/dists/gentoo/files/nxserver-freenx-0.7.4-nxloadconfig.patch new file mode 100644 index 0000000..1e613dd --- /dev/null +++ b/dists/gentoo/files/nxserver-freenx-0.7.4-nxloadconfig.patch @@ -0,0 +1,68 @@ +--- freenx-server/nxloadconfig.orig 2012-07-18 17:45:54.624000000 +0400 ++++ freenx-server/nxloadconfig 2012-07-18 17:43:42.454003648 +0400 +@@ -58,7 +58,7 @@ + # Where can different nx components be found + NX_DIR=/usr + PATH_BIN=$NX_DIR/bin # if you change that, be sure to also change the public keys +-PATH_LIB=$NX_DIR/lib ++PATH_LIB=$NX_DIR/lib/NX/lib + NX_ETC_DIR=/etc/nxserver + NX_SESS_DIR=/var/lib/nxserver/db + NX_HOME_DIR=/var/lib/nxserver/home +@@ -183,7 +183,7 @@ + #JJK: added the following path referenced in nxprint + PPD_DIR="/usr/share/cups/model" #JJK: Note /usr/share/ppd on some systems + +-CUPS_BACKEND="/usr/lib/cups/backend" ++CUPS_BACKEND="/usr/libexec/cups/backend" + CUPS_IPP_BACKEND="$CUPS_BACKEND/ipp" + CUPS_DEFAULT_SOCK="/var/run/cups/cups.sock" + CUPS_ETC="/etc/cups/" +@@ -202,15 +202,15 @@ + KILL_DEFAULT_X_WM="1" + BOOTSTRAP_X_SESSION="0" + USER_X_STARTUP_SCRIPT=.Xclients +-DEFAULT_X_SESSION=/etc/X11/xdm/Xsession ++DEFAULT_X_SESSION=/etc/X11/Sessions/Xsession + COMMAND_GDM_X_SESSION="/etc/X11/gdm/Xsession custom" + if [ ! -x "$COMMAND_GDM_X_SESSION" ] + then +- COMMAND_GDM_X_SESSION="/etc/X11/Xsession" ++ COMMAND_GDM_X_SESSION="/etc/X11/Sessions/Xsession" + fi + COMMAND_START_KDE="startkde" + COMMAND_START_KDE4="startkde4" +-COMMAND_START_GNOME="gnome-session" ++COMMAND_START_GNOME="/etc/X11/Sessions/Gnome" + COMMAND_START_CDE=cdwm + COMMAND_XTERM=xterm + COMMAND_XAUTH=/usr/bin/xauth +@@ -234,14 +234,15 @@ + COMMAND_NXSHADOWACL="$PATH_BIN/nxshadowacl" + COMMAND_NXACL="$PATH_BIN/nxacl" + COMMAND_NXCHECKLOAD="$PATH_BIN/nxcheckload" +-COMMAND_NXAGENT="$PATH_BIN/nxagent" ++COMMAND_NXAGENT="REAL_PATH_LIB/nxagent" + + # Guest directives + ENABLE_GUEST_LOGIN="0" +-COMMAND_GUEST_LOGIN="/usr/lib/nx/guest/nxnode" ++COMMAND_GUEST_LOGIN="/usr/lib/NX/guest/nxnode" + # Try to use protected enviroment for guest sessions +-COMMAND_GUEST_X_SESSION="/usr/share/gdm/guest-session/Xsession custom" +-if [ ! -x "/usr/share/gdm/guest-session/Xsession" ] ++COMMAND_GUEST_X_SESSION="/usr/lib/NX/guest/Gnome" ++ ++if [ ! -x "/usr/lib/NX/guest/Gnome" ] + then + COMMAND_GUEST_X_SESSION=$COMMAND_GDM_X_SESSION + fi +@@ -406,7 +407,7 @@ + [ -z "$PROXY_LIBRARY_PATH" ] && PROXY_LIBRARY_PATH=$PATH_LIB + + [ -z "$APPLICATION_LIBRARY_PATH" ] && APPLICATION_LIBRARY_PATH=$PATH_LIB +-[ -z "$APPLICATION_LIBRARY_PRELOAD" ] && APPLICATION_LIBRARY_PRELOAD="$APPLICATION_LIBRARY_PATH/libX11-nx.so.6:$APPLICATION_LIBRARY_PATH/libXext-nx.so.6:$APPLICATION_LIBRARY_PATH/libXcomp.so.3:$APPLICATION_LIBRARY_PATH/libXcompext.so.3:$APPLICATION_LIBRARY_PATH/libXrender.so.1" ++[ -z "$APPLICATION_LIBRARY_PRELOAD" ] && APPLICATION_LIBRARY_PRELOAD="$APPLICATION_LIBRARY_PATH/libX11.so:$APPLICATION_LIBRARY_PATH/libXext.so:$APPLICATION_LIBRARY_PATH/libXcomp.so:$APPLICATION_LIBRARY_PATH/libXcompext.so:$APPLICATION_LIBRARY_PATH/libXrender.so" + + NX_BACKEND_VERSION=$(strings $COMMAND_NXAGENT 2>/dev/null | egrep 'NXAGENT - Version' | sed 's/.*Version //g') + diff --git a/dists/gentoo/files/nxserver-freenx-0.7.4-pam_ssh.patch b/dists/gentoo/files/nxserver-freenx-0.7.4-pam_ssh.patch new file mode 100644 index 0000000..8d123b0 --- /dev/null +++ b/dists/gentoo/files/nxserver-freenx-0.7.4-pam_ssh.patch @@ -0,0 +1,10 @@ +--- freenx-server/nxnode-login.orig 2009-04-20 16:54:24.000000000 +0200 ++++ freenx-server/nxnode-login 2009-04-20 16:54:27.000000000 +0200 +@@ -73,6 +73,7 @@ + expect { + "Are you sure you want to continue connecting (yes/no)?" { send "yes\r" } + "assword*:" { sleep 0.3; send "$password\r" } ++ "SSH passphrase:" { sleep 0.3; send "$password\r" } + "Permission denied*" { exit 1 } + "su: Authentication failure" { exit 1 } + "NX> 1000 NXNODE - Version" { diff --git a/dists/gentoo/gentoo.postinst b/dists/gentoo/gentoo.postinst new file mode 100755 index 0000000..94da497 --- /dev/null +++ b/dists/gentoo/gentoo.postinst @@ -0,0 +1,7 @@ +#!/bin/bash +chmod 711 "/usr/libexec/cups/backend/ipp" +chmod 755 "/usr/sbin/cupsd" +chmod 4711 "/sbin/mount.cifs" +ln -s /usr/share/cups/mime/mime.convs /etc/cups +ln -s /usr/share/cups/mime/mime.types /etc/cups + diff --git a/dists/gentoo/nxserver-freenx-0.7.4-r665.ebuild b/dists/gentoo/nxserver-freenx-0.7.4-r665.ebuild new file mode 100644 index 0000000..51c168d --- /dev/null +++ b/dists/gentoo/nxserver-freenx-0.7.4-r665.ebuild @@ -0,0 +1,162 @@ +# Copyright 1999-2011 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/net-misc/nxserver-freenx/nxserver-freenx-0.7.3_p104-r6.ebuild,v 1.4 2011/11/24 21:00:12 voyageur Exp $ + +EAPI=4 + +inherit git-2 multilib eutils toolchain-funcs versionator + +MAJOR_PV="$(get_version_component_range 1-3)" +PATCH_VER="$(get_version_component_range 4)" +MY_PN="freenx-server" + +DESCRIPTION="Free Software Implementation of the NX Server" +HOMEPAGE="http://freenx.berlios.de/ https://launchpad.net/~freenx-team" +EGIT_REPO_URI="git://git.etersoft.ru/people/dimbor/packages/freenx-server.git" +#EGIT_BOOTSTRAP="autogen.bash" +SRC_URI="" +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="amd64 x86" +IUSE="nxclient rdesktop vnc" + +DEPEND="x11-misc/gccmakedep + x11-misc/imake" +RDEPEND="dev-tcltk/expect + media-fonts/font-cursor-misc + sys-devel/bc + media-fonts/font-misc-misc + net-analyzer/gnu-netcat + >=net-misc/nx-2.1.0 + sys-apps/gawk + virtual/ssh + x11-apps/xauth + x11-apps/xrdb + x11-apps/sessreg + x11-terms/xterm + nxclient? ( net-misc/nxclient ) + !nxclient? ( !net-misc/nxclient + || ( x11-misc/xdialog + x11-apps/xmessage + gnome-extra/zenity ) ) + rdesktop? ( net-misc/rdesktop ) + vnc? ( x11-misc/x11vnc + net-misc/tightvnc )" + +S=${WORKDIR} + +export NX_HOME_DIR=/var/lib/nxserver/home + +pkg_setup () { + enewuser nx -1 -1 ${NX_HOME_DIR} +} + +src_prepare() { + cd ${S} + epatch "${FILESDIR}"/nxserver-freenx-0.7.4-pam_ssh.patch + epatch "${FILESDIR}"/nxserver-freenx-0.7.4-nxloadconfig.patch + + # Path to net-misc/nx files, support for nx >= 3.4.0 + sed -e "/PATH_LIB=/s/lib/$(get_libdir)/g" \ + -e "s#REAL_PATH_LIB#/usr/$(get_libdir)/NX/bin#" \ + -i ${MY_PN}/nxloadconfig || die "nxloadconfig sed failed" +} + +src_compile() { + cd ${MY_PN} + emake CC=$(tc-getCC) CDEBUGFLAGS="${CFLAGS}" || die "compilation failed" +} + +src_install() { + export NX_ETC_DIR=/etc/nxserver + export NX_SESS_DIR=/var/lib/nxserver/db + + cd ${MY_PN} + emake DESTDIR="${D}" install || die "install failed" + +# LIBREDIR_DIR="${D}""usr/lib/freenx-server" +# dodir "/usr/lib/freenx-server" +# OLDREDIR_DIR="${D}""usr/$(get_libdir)/NX/$(get_libdir)/freenx-server" +# mv ${OLDREDIR_DIR}/libnxredir.so.0 ${LIBREDIR_DIR} +# [[ $(get_libdir) == "lib64" ]] && rm -r "${D}""usr/$(get_libdir)" || \ +# rm -r "${D}""usr/$(get_libdir)/NX" + + + # This should be renamed to remove the blocker on net-misc/nxclient + use nxclient && rm "${D}"/usr/bin/nxprint + + dodir ${NX_ETC_DIR} + for x in passwords passwords.orig ; do + touch "${D}"${NX_ETC_DIR}/$x + chmod 600 "${D}"${NX_ETC_DIR}/$x + done + + + insinto ${NX_ETC_DIR} + for x in Xkbmap Xsession fixkeyboard ; do + doins "${S}/${MY_PN}/data/$x" + [[ $x == "Xkbmap" ]] && continue + chmod 755 "${D}"${NX_ETC_DIR}/$x + done + + CONF_DIR="${NX_ETC_DIR}"/node.conf.d + dodir ${CONF_DIR} + insinto ${CONF_DIR} + + doins "${S}/${MY_PN}/conf/conf.d"/* + cp "${FILESDIR}"/70-gentoo.conf "${D}"${CONF_DIR} + + ACL_DIR="${NX_ETC_DIR}/acls" + dodir "${ACL_DIR}" + insinto "${ACL_DIR}" + doins "${S}/${MY_PN}/conf/acls"/* + + dodir "${NX_ETC_DIR}/ppd" + + SUDO_DIR=/etc/sudoers.d + dodir ${SUDO_DIR} + insinto "${SUDO_DIR}" + newins "${S}/sudoers.conf" nxserver + chmod 440 "${D}"${SUDO_DIR}/nxserver + + LOGR_DIR=/etc/logrotate.d + dodir ${LOGR_DIR} + insinto "${LOGR_DIR}" + newins "${S}/${MY_PN}/data/logrotate" nxserver + + dodir ${NX_HOME_DIR} + + for x in closed running failed ; do + keepdir ${NX_SESS_DIR}/$x + fperms 0700 ${NX_SESS_DIR}/$x + done + + newinitd "${FILESDIR}"/nxserver.init nxserver +} + +pkg_postinst () { + # Other NX servers ebuilds may have already created the nx account + # However they use different login shell/home directory paths + if [[ ${ROOT} == "/" ]]; then + usermod -s /usr/bin/nxserver nx || die "Unable to set login shell of nx user!!" + usermod -d ${NX_HOME_DIR} nx || die "Unable to set home directory of nx user!!" + usermod -a -G utmp nx || die "Unable to add nx user to utmp group!!" + else + elog "If you had another NX server installed before, please make sure" + elog "the nx user account is correctly set to:" + elog " * login shell: /usr/bin/nxserver" + elog " * home directory: ${NX_HOME_DIR}" + elog " * supplementary groups: utmp" + fi + + elog "To complete the installation, run:" + elog " nxsetup --install --setup-nomachine-key" + elog "This will use the default Nomachine SSH key" + elog "If you had older NX servers installed, you may need to add \"--clean --purge\" to the nxsetup command" + + if has_version net-misc/openssh[-pam]; then + elog "" + elog "net-misc/openssh was not built with PAM support" + elog "You will need to unlock the nx account by setting a password for it" + fi +} diff --git a/node.conf.def/00--internal.cnf b/node.conf.def/00--internal.cnf new file mode 100644 index 0000000..c6a4fa1 --- /dev/null +++ b/node.conf.def/00--internal.cnf @@ -0,0 +1,62 @@ +######################################################################### +# INTERNAL STUFF DEFAULTS +# DO NOT TOUCH unless you REALLY know what you are doing +######################################################################### + +#@ type: string +#@ check: notempty error +NX_VERSION=3.5.0-2.1.3-CE + +#@ type: string +#@ check: advanced error +NX_LICENSE="OS (GPL, using backend: %BACKEND%)" + +# Where can different nx components be found + +#@ type: string +#@ check: dir error +NX_DIR=/usr + +# if you change that, be sure to also change the public keys +#@ type: string +#@ check: dir error +PATH_BIN=$NX_DIR/bin + +#@ type: string +#@ check: dir error +PATH_LIB=$NX_DIR/lib + +#@ type: string +#@ check: dir nx:nx 770 perform +NX_SESS_DIR=/var/lib/nxserver/db + +#@ type: string +#@ check: dir nx:nx 700 perform +NX_HOME_DIR=/var/lib/nxserver/home + +# Advanced users ONLY + +#@ type: string +#@ depend: SET_LD_LIBRARY_PATH +#@ check: dir error +AGENT_LIBRARY_PATH="$PATH_LIB" + +#@ type: string +#@ depend: SET_LD_LIBRARY_PATH +#@ check: dir error +PROXY_LIBRARY_PATH="$PATH_LIB" + +#@ type: string +#@ depend: SET_LD_LIBRARY_PATH +#@ check: dir error +APPLICATION_LIBRARY_PATH="$PATH_LIB" + +#@ type: string +#@ depend: SET_LD_LIBRARY_PATH +#@ check: advanced +APPLICATION_LIBRARY_PRELOAD="" + +# the name of the authorized keys file for ssh +#@ type: string +#@ check: advanced +SSH_AUTHORIZED_KEYS="authorized_keys2" diff --git a/node.conf.def/00-general.conf b/node.conf.def/00-general.conf new file mode 100644 index 0000000..d4ccbc4 --- /dev/null +++ b/node.conf.def/00-general.conf @@ -0,0 +1,15 @@ +######################################################################### +# General FreeNX directives +######################################################################### + +# The host name which is used by NX server. It's should be used if it's +# different than the default hostname (as returned by `hostname`) +#@ type: string +#@ check: notempty error +SERVER_NAME="$(hostname)" + +# The node ip which is used by NX Node in unecnrypted session mode. +# Set it if you want to use a specific external ip or the autodetection +# is not working. +#@ type: string +EXTERNAL_PROXY_IP="" diff --git a/node.conf.def/01-auth.conf b/node.conf.def/01-auth.conf new file mode 100644 index 0000000..a122ca5 --- /dev/null +++ b/node.conf.def/01-auth.conf @@ -0,0 +1,28 @@ +######################################################################### +# Authentication / Security directives +######################################################################### + +# If enabled forces the user to use encryption. This will bail out +# if the user does not have encryption enabled. +#@ type: bool +ENABLE_FORCE_ENCRYPTION=0 + +# Refuse the NX client connection if SSHD does not export the +# SSH_CONNECTION and SSH_CLIENT variables in the environment +# passed to the NX server. +# 1: Will check the remote IP and will not accept the +# connection if it can't be determined. +# 0: Will accept the connection even if the remote IP +# is not provided. +#@ type: bool +SSHD_CHECK_IP=0 + +# If ENABLE_LOG_FAILED_LOGINS=1 then failed login attempts are logged to the system +# auth.log. +# +# This is useful in combination with tools like fail2ban. +# +# The default is to log failed login attemps via syslog (3). +# +#@ type: bool +ENABLE_LOG_FAILED_LOGINS=1 diff --git a/node.conf.def/02-restriction.conf b/node.conf.def/02-restriction.conf new file mode 100644 index 0000000..7cfa134 --- /dev/null +++ b/node.conf.def/02-restriction.conf @@ -0,0 +1,129 @@ +######################################################################### +# Restriction directives +######################################################################### + +# The base display number from which sessions are started. +#@ type: int +#@ check: 1500 error +DISPLAY_BASE=2000 + +# The maximum number of contemporary sessions that can be run on FreeNX +#@ type: int error +SESSION_LIMIT=200 + +# The maximum number of contemporary sessions that a single user can run +# on FreeNX. +#@ type: int +#@ check: 1 SESSION_LIMIT +SESSION_USER_LIMIT=20 + +# The number of displays reserved for sessions, it has to be greater or equal +# to the maximum number of contemporary sessions that a server can run. +#@ type: int +#@ check: SESSION_LIMIT +DISPLAY_LIMIT=200 + + +# User for which sessions should be persistent. Either the keyword "all" or a +# comma-separated list of usernames or groups in the @groupname syntax. +#@ type: string +ENABLE_PERSISTENT_SESSION="all" + +# Users and groups for whom persistent sessions should be disabled. +# Especially useful if ENABLE_PERSISTENT_SESSION="all" +#@ type: string +DISABLE_PERSISTENT_SESSION="" + +# General nx shadowing +# If ENABLE_SESSION_SHADOWING=1 nxserver will store in db shadow +# cookies +#@ type: bool +ENABLE_SESSION_SHADOWING=1 + +# +# When using NX 3.0 shadowing, this enables asking the user whether +# he authorizes another user to shadow his session +# +# 0: No authorization request will be presented, +# and the session will be shadowed as if the user had approved. +# 1: (default) Ask for authorization +# +#@ type: bool +ENABLE_SESSION_SHADOWING_AUTHORIZATION=1 + +# Allow session shadowing in interactive mode: +# +# 1: The shadowing user can interact with the shadowed session. +# +# 0: The shadowed session is view-only. No interaction with the +# shadowed session is possible. +# +#@ type: bool +ENABLE_INTERACTIVE_SESSION_SHADOWING=1 + +# +# Enable or disable clipboard: +# +# client: The content copied on the client can be pasted inside the +# NX session. +# +# server: The content copied inside the NX session can be pasted +# on the client. +# +# both: The copy&paste operations are allowed both between the +# client and the NX session and vice-versa. +# +# none: The copy&paste operations between the client and the NX +# session are never allowed. +# +#@ type: string +#@ check: list: %server, both, none% error +ENABLE_CLIPBOARD="both" + + +# +# Enable or disable the pulldown dialog, which provides a graphical +# way to suspend or terminate the rootless session: +# +# 1: Enabled. The pulldown menu is shown when the mouse pointer +# moves near the middle of the top boundary of a window and +# allows the user to suspend or terminate the session by means +# of an icon-click. +# +# 0: Disabled. The ctrl+alt+T key combination has to be issued +# to get the dialog for suspending or terminating the session. +# +#@ type: bool +ENABLE_PULLDOWN_MENU=1 + +# If you set ENABLE_ADVANCED_SESSION_CONTROL=1 you can start a new application +# in an already +# running rootless session by using "add " as session name. +# +# Note: The client will return a message on that. +# +#@ type: bool +ENABLE_ADVANCED_SESSION_CONTROL=0 + +# If you set ENABLE_SHOW_RUNNING_SESSIONS=0 then nxserver will only show +# suspended sessions and you will not be able to resume or terminate a running +# session. +# dimbor: for autoreconnect must set to 0 +# +#@ type: bool +ENABLE_SHOW_RUNNING_SESSIONS=0 + +# If value of this option not empty (valid dir) "run-acl" system is switch on: +# On session start (node_find_application) called acl check process. +# ACL-files in NX_ACL_DIR describes user/group permissions for given cmdstr. +# ACL filenames are usernames, groupnames and "all". Permissions search order: +# user - group - all. See $NX_ETC_DIR/acls/README for detail +# After change of NX_ACL_DIR running 'nxsetup --mkdb' is required +# Example: NX_ACL_DIR="/etc/nxserver/acls" +#@ type: string +NX_ACL_DIR="" + +# Default acl warning message. +#@type: string +#@depend NX_ACL_DIR +NX_ACL_WARN="Access denied!" diff --git a/node.conf.def/03-logging.conf b/node.conf.def/03-logging.conf new file mode 100644 index 0000000..a846105 --- /dev/null +++ b/node.conf.def/03-logging.conf @@ -0,0 +1,29 @@ +######################################################################### +# Logging directives +######################################################################### + +# This directives controls the verbosity of the server-wide log. +# 0/1: No Logging/Logging +#@ type: bool +NX_LOG_LEVEL=0 + +# Before turning logging on, please make sure that NX_LOGFILE is +# writeable for the "nx" user +#@ type: string +#@ check: path error +NX_LOGFILE=/var/log/nxserver.log + +# This directive controls if the temporary session directory +# ($HOME/.nx/C---) should be kept after a +# session has ended. A successfully terminated session will be saved as +# T-C--- while a failed session will be saved +# as F-C---. +# The default is to cleanup the directories. +#@ type: bool +SESSION_LOG_CLEAN=1 + +# Amount of seconds nxserver is to keep session history. The default of 2592000 +# is equivalent to 30 days. If this is 0 no session history will be kept +# and a negative value denotes infinity. +#@ type: int +SESSION_HISTORY=2592000 diff --git a/node.conf.def/04-balancing.conf b/node.conf.def/04-balancing.conf new file mode 100644 index 0000000..d0d9229 --- /dev/null +++ b/node.conf.def/04-balancing.conf @@ -0,0 +1,39 @@ + +# LOAD BALANCING +# ============== +# +# To do load balancing setup some hosts in LOAD_BALANCE_SERVERS and +# make: +# +# - either sure that all incoming connections are sent to the master +# server by using forwarding directives on the "slave" servers. +# +# - or share the session database space via NFS between the servers. +# (not recommended at the moment as race conditions for DISPLAYs can +# occur) +# + +#@ type: string +LOAD_BALANCE_SERVERS="" + +# The following load_balance_algorithms are available at the moment: +# +# "load", "round-robin", "random" +# +# For "load" you need a script called nxcheckload in PATH_BIN. +# +# A sample script, which you can change to your needs it shipped with +# FreeNX under the name nxcheckload.sample. + +#@ type: string +#@ depend: LOAD_BALANCE_SERVERS +#@ check: list: %load, round-robin, random% error +LOAD_BALANCE_ALGORITHM="random" + +# By setting ENABLE_LOADBALANCE=1 you can let users choose their +# preferred host, while being forwarded to another server. Of course +# this is just a preference. The loadbalancing algorithm can completely +# choose to ignore the users choice. + +#@ type: bool +ENABLE_LOAD_BALANCE_PREFERENCE=0 diff --git a/node.conf.def/05-sound.conf b/node.conf.def/05-sound.conf new file mode 100644 index 0000000..5fb2fcf --- /dev/null +++ b/node.conf.def/05-sound.conf @@ -0,0 +1 @@ +# is empty diff --git a/node.conf.def/06-path.conf b/node.conf.def/06-path.conf new file mode 100644 index 0000000..fc742ab --- /dev/null +++ b/node.conf.def/06-path.conf @@ -0,0 +1,186 @@ +######################################################################### +# Path directives +######################################################################### + +# Add the nx libraries to LD_LIBRARY_PATH before starting nx agents. +# WARNING: This will NOT (and should not) affect applications. ONLY Disable +# this if the nx libraries are in a standard system path (such as /usr/lib)! +#@ type: bool +SET_LD_LIBRARY_PATH=0 + + +# The command binary for the default window manager. If set it is run when a +# 'unix-custom' session is requested by the NX Client and an application +# to run is specified. It defaults to empty (ie no WM is run). +# If KILL_DEFAULT_X_WM is set the WM is terminated after the started +# application finishes. Else FreeNX will wait for the WM to complete. +#@ type: string +DEFAULT_X_WM="" + +#@ type: bool +KILL_DEFAULT_X_WM=1 + +# When a 'unix-default' session is requested by the client the user's X startup +# script will be run if pressent and executable, otherwise the default X +# session will be run. +# Depending on distribution USER_X_STARTUP_SCRIPT might be .Xclients, .xinitrc +# and .Xsession +# Depending on distribution DEFAULT_X_SESSION might be /etc/X11/xdm/Xsession, +# /etc/X11/Sessions/Xsession or /etc/X11/xinit/xinitrc +#@ type: string +#@ check: rt_expand +USER_X_STARTUP_SCRIPT=.Xclients + +#@ type: string +#@ check: exe +DEFAULT_X_SESSION=/etc/X11/Xsession + +#@ type: string +#@ check: advanced error +COMMAND_GDM_X_SESSION="/etc/X11/gdm/Xsession custom" + +# When the session is started some distros execute some scripts to get the +# environment ready. Set 1 if you want DEFAULT_X_SESSION to be called before +# executing the session. +#@ type: bool +BOOTSTRAP_X_SESSION=0 + +# The key that contains the name of the script that starts a KDE session. +# It's run when a 'unix-kde' session is requested by the client. +# Default is "startkde" +#@ type: string +#@ check: exe +COMMAND_START_KDE=startkde + +# The key that contains the name of the script that starts a gnome session. +# It's run when a 'unix-gnome' session is requested by the client. +# Default is "gnome-session" +#@ type: string +#@ check: exe +COMMAND_START_GNOME=gnome-session + +# The key that contains the name of the script that starts a CDE session. +# It's run when a 'unix-cde' session is requested by the client. +#@ type: string +#@ check: exe +COMMAND_START_CDE=cdwm + +#@ type: string +#@ check: exe 755 perform +COMMAND_NXAGENT=nxagent + +# The key that contains the name of the complete path of command name +# 'xterm'. It is run when a unix "xterm" session is requested by the +# client. +#@ type: string +#@ check: exe +COMMAND_XTERM=xterm + +# The key that contains the name of the complete path of command name +# 'xauth'. +#@ type: string +#@ check: exe error +COMMAND_XAUTH=xauth + +# The key that contains the name of the complete path of command name +# 'sudo'. +#@ type: string +#@ check: exe error +COMMAND_SUDO=sudo + +# The key that contains the name of the complete path of command name +# 'mount'. +#@ type: string +#@ check: exe +COMMAND_MOUNT_LIST=mount + +# The key that contains the name of the complete path of command name +# 'mount.cifs'. +#@ type: string +#@ check: exe +COMMAND_SMBMOUNT=mount.cifs + +# The key that contains the name of the complete path of command name +# 'umount.cifs'. +#@ type: string +#@ check: exe +COMMAND_SMBUMOUNT=umount + +# The key that contains the name of the complete path of the 'netcat' command. +#@ type: string +#@ check: exe error +COMMAND_NETCAT=netcat + +# The key that contains the name of the complete path of the 'ssh' and +# 'ssh-keygen' command. +#@ type: string +#@ check: exe error +COMMAND_SSH=ssh + +#@ type: string +#@ check: exe error +COMMAND_SSH_KEYGEN=ssh-keygen + +# The tool to generate md5sums with +#@ type: string +#@ check: exe error +COMMAND_MD5SUM=md5sum + +# The key that contains the name of the complete path of the 'rdesktop' command. +#@ type: string +#@ check: exe +COMMAND_RDESKTOP=xfreerdp + +# The key that contains the name of the complete path of the 'vncviewer' command. +#@ type: string +#@ check: exe +COMMAND_VNCVIEWER=vncviewer + +#@ type: string +#@ depend: LOAD_BALANCE_SERVERS +#@ check: exe +COMMAND_NXCHECKLOAD="nxcheckload" + +# The key that contains the name of the complete path of the 'vncpasswd' command. +# By default the builtin nxpasswd is used. +#@ type: string +#@ check: exe +COMMAND_VNCPASSWD=nxpasswd + +#@ type: string +#@ depend: ENABLE_USESSION +#@ check: exe error +COMMAND_SESSREG=sessreg + +# Command for cp converting +#@ type: string +#@ check: exe error +COMMAND_ICONV=iconv + +# Commands for hiding/unhiding passwords +#@ type: string +#@ check: exe error +COMMAND_HIDE=base64 + +#@ type: string +#@ check: exe error +COMMAND_UNHIDE="base64 -d" + +# Command to get process list +#@ type: string +#@ check: exe error +COMMAND_PS=ps + +# Commands to pulseaudio control +#@ type: string +#@ check: exe +COMMAND_PA=pulseaudio + +#@ type: string +#@ check: exe +COMMAND_PACTL=pactl + +# Application to display X message. +#@ type: string +#@ check: exe error +COMMAND_XMSG="nxdialog --dialog ok --caption 'freenx server' --message" diff --git a/node.conf.def/07-misc.conf b/node.conf.def/07-misc.conf new file mode 100644 index 0000000..90db566 --- /dev/null +++ b/node.conf.def/07-misc.conf @@ -0,0 +1,57 @@ +######################################################################### +# Misc directives +######################################################################### + +# When set to 1 this will automatically resume started sessions +#@ type: bool +ENABLE_AUTORECONNECT=1 + +# When set to 1 exports NXUSERIP / NXSESSIONID in nxnode +#@ type: bool +EXPORT_USERIP=1 + +#@ type: bool +EXPORT_SESSIONID=1 + +# This can be set to any executable, which is started after session startup +# like: $NODE_AUTOSTART {start|restore} +#@ type: string +#@ check: rt_expand +NODE_AUTOSTART="" + +# When set to 1 will start nxagent in rootless mode. +#@ type: bool +ENABLE_ROOTLESS_MODE=1 + +# If enabled writes entries via the COMMAND_SESSREG program +# into utmp/wtmp/lastlog database. +# Note: You have to make sure that you add the nx user to the +# utmp or tty group or how its called on your system +# before this directive works. +#@ type: bool +ENABLE_USESSION=1 + +# Extra options to vncviewer command. Default are for tigervnc-viewer +#@ type: string +EXTRA_OPTIONS_RFB="-Shared -SecurityTypes VncAuth" + +# Extra options to rdesktop command. Default are for xfreerdp +#@ type: string +EXTRA_OPTIONS_RDP="/cert-ignore /kbd:0x00000409 /home-drive +clipboard" + +# Time to sleep before calling terminate nxagent +#@ type: int +#@ check: 0 30 +NODE_APP_WAIT_TIMEOUT=3 + +# Force terminate session if NODE_APP_WAIT_TIMEOUT ends +#@ type: bool +ENABLE_ROOTLESS_TERMINATE_SESSION=0 + +# In case ENABLE_ROOTLESS_TERMINATE_SESSION=1 if starting apps found +# in APP_WAIT_MAP then appropriate processes will be controlled of. +# Further nxnode will wait for them completion after main app finished. +# Format: "app_name1:sname1[,sname2...][;app_name2:sname3[,sname4...][;...]]" +#@ type: string +#@ depend: ENABLE_ROOTLESS_TERMINATE_SESSION +APP_WAIT_MAP="" diff --git a/node.conf.def/08-bash.conf b/node.conf.def/08-bash.conf new file mode 100644 index 0000000..c28efb7 --- /dev/null +++ b/node.conf.def/08-bash.conf @@ -0,0 +1,14 @@ +# If SOURCE_SYS_PROFILE is not empty and readable FreeNX will source +# it before application startup as we are kind of a login shell. +# default: /etc/profile +#@ type: string +#@ check: file +SOURCE_SYS_PROFILE="/etc/profile" + +# If SOURCE_BASH_USER_PROFILE is not empty and readable FreeNX will source +# it before application startup as we are kind of a login shell. +# Please use absolute path or short file name. +# default: .profile +#@ type: string +SOURCE_USER_PROFILE=".profile" + diff --git a/node.conf.def/09-cups.conf b/node.conf.def/09-cups.conf new file mode 100644 index 0000000..e70029a --- /dev/null +++ b/node.conf.def/09-cups.conf @@ -0,0 +1,44 @@ +# System CUPS with sudo is used. +# put drivers to /etc/nxserver/ppd dir (more info in +# http://unixforum.org/index.php?showforum=89) + +# Our own CUPS ppd dir +#@ type: string +#@ check: dir root:users 775 perform +NX_PPD_DIR=$NX_ETC_DIR/ppd + +# Commands to CUPS control + +#@ type: string +#@ check: exe +COMMAND_LPINFO=lpinfo + +#@ type: string +#@ check: exe +COMMAND_LPSTAT=lpstat + +#@ type: string +#@ check: exe +COMMAND_LPADMIN=lpadmin + +#@ type: string +#@ check: exe +COMMAND_PPDCAT=/usr/lib/cups/daemon/cups-driverd + +#@ type: string +#@ check: path +CUPS_DEFAULT_SOCK=/var/run/cups/cups.sock + +# for check cups backends only + +#@ type: string +#@ check: dir +CUPS_BACKEND=/usr/lib/cups/backend + +#@ type: string +#@ check: exe +CUPS_IPP_BACKEND=$CUPS_BACKEND/ipp + +#@ type: string +#@ check: exe +CUPS_NXSMB_BACKEND=$CUPS_BACKEND/nxsmb diff --git a/node.conf.def/10-samba.conf b/node.conf.def/10-samba.conf new file mode 100644 index 0000000..69bd3e8 --- /dev/null +++ b/node.conf.def/10-samba.conf @@ -0,0 +1,19 @@ +# FreeNX with ENABLE_SAMBA_PRELOAD=1 will automatically setup +# port 445 and 139 and forward them to the used samba port. +# +# This enables samba browsing to the local subnet in for example +# konqueror. +# +#@ type: bool +ENABLE_SAMBA_PRELOAD=0 + +# Additional mount options for mount command (mount.cifs) +#@ type: string +SMB_MOUNT_OPTIONS="vers=2.1,iocharset=utf8,file_mode=0660,dir_mode=0770" + +# How to inteprete international symbols in win-client resource-names. +# Contains none,one or more charsets pairs - arguments "[from]>[to]" of iconv command. +# if none, it's equivalent of system charset, +# eg ">cp1252 cp1251>" == "latin1>cp1252 cp1251>UTF-8" +#@ type: string +WIN_CP_CONVERT_CHAIN="" diff --git a/node.conf.def/11-nxagent.conf b/node.conf.def/11-nxagent.conf new file mode 100644 index 0000000..71b19e8 --- /dev/null +++ b/node.conf.def/11-nxagent.conf @@ -0,0 +1,13 @@ +#@ type: string +AGENT_EXTRA_OPTIONS_X="-nolisten tcp -dpi 96" + +# The number of seconds we wait for the nxagent to start before +# deciding startup has failed +#@ type: int +AGENT_STARTUP_TIMEOUT=15 + +# The font server the agent will use. If set to "" no font server is used. +# For this to do any good, the client has to have the same font server set +# in /etc/X11/XF86Config +#@ type: string +AGENT_FONT_SERVER="" diff --git a/node.conf.def/12-nxproxy.conf b/node.conf.def/12-nxproxy.conf new file mode 100644 index 0000000..e5a37f3 --- /dev/null +++ b/node.conf.def/12-nxproxy.conf @@ -0,0 +1,12 @@ +# Disable or enable use of 'tcp nodelay' on proxy. Old versions of Linux +# kernels have problems using this option on sockets that will cause a loss +# of TCP connections. This option is not set by default to allow clients to +# specify whether to enable or disable TCP nodelay. Setting this option to +# the value of 0 NX proxy avoids using 'tcp nodelay' but it will cause a +# loss of interaction in sessions. +#@ type: string +PROXY_TCP_NODELAY="" + +# Extra options to nxproxy. See !M documentation for useful parameters. +#@ type: string +PROXY_EXTRA_OPTIONS="" diff --git a/node.conf.def/50-numlockx.conf b/node.conf.def/50-numlockx.conf new file mode 100644 index 0000000..8e74deb --- /dev/null +++ b/node.conf.def/50-numlockx.conf @@ -0,0 +1,12 @@ +# Binary filename provides numlockx +#@ type: string +#@ check: exe +NUMLOCKX=numlockx + +# numlockx run strategy. valid value are: +# 'on' -- run 'numlockx on' at session startup +# 'off' -- run 'numlockx off' at session startup +# 'system' -- default. don't run numlockx +#@ type: string +#@ check: list: %on, off, system% +NUMLOCK_METHOD="system" diff --git a/node.conf.def/README b/node.conf.def/README new file mode 100644 index 0000000..df60fd7 --- /dev/null +++ b/node.conf.def/README @@ -0,0 +1,2 @@ +# Do not modify the files here please. +# They are used to set default values by nxsetup. diff --git a/nx-session-launcher/ConsoleKit-NX.conf b/nx-session-launcher/ConsoleKit-NX.conf new file mode 100644 index 0000000..5cdc5c7 --- /dev/null +++ b/nx-session-launcher/ConsoleKit-NX.conf @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + diff --git a/nx-session-launcher/Makefile b/nx-session-launcher/Makefile new file mode 100644 index 0000000..efdbd0a --- /dev/null +++ b/nx-session-launcher/Makefile @@ -0,0 +1,17 @@ +.PHONY: all install + +CC=gcc +CFLAGS=-g -O2 -Wall -fPIC + +SOURCES = nx-session-launcher-suid.c +PROGRAMS = nx-session-launcher-suid + +ifneq ($(NX_VERSION),) +CFLAGS+=-DNXSERVER_COMMAND="\"$(PATH_BIN)/nx-session-launcher\"" +endif + +all: $(PROGRAMS) + +clean: + rm -f $(PROGRAMS) + diff --git a/nx-session-launcher/README b/nx-session-launcher/README new file mode 100644 index 0000000..ed8f7b9 --- /dev/null +++ b/nx-session-launcher/README @@ -0,0 +1,12 @@ +The unlock buttons on Users and Groups or Network are greyed out and un-accessible. +Running from a term 'sudo users-admin' should work the same way. (Not in Ubuntu due +to bug https://bugs.edge.launchpad.net/ubuntu/+source/policykit/+bug/210897) + +If you are not using a packed version, correct the problem by following this steps: + - Copy nx-session-launcher and nx-session-launcher-suid to /usr/bin + - Execute $ chown nx /usr/bin/nx-session-launcher-suid + - Execute $ chmod 4755 /usr/bin/nx-session-launcher-suid + - Copy ConsoleKit-NX.conf to /etc/dbus-1/system.d/ + - Reload dbus by issuing /etc/init.d/dbus reload + - Edit /etc/nxserver/node.conf and change '#COMMAND_START_GNOME=gnome-session' + to 'COMMAND_START_GNOME=/usr/bin/nx-session-launcher-suid gnome-session' diff --git a/nx-session-launcher/freenx.session.policy b/nx-session-launcher/freenx.session.policy new file mode 100644 index 0000000..15847f4 --- /dev/null +++ b/nx-session-launcher/freenx.session.policy @@ -0,0 +1,19 @@ + + + + + + + Create a new FreeNX session + System policy allows to create a new session + + no + no + yes + + + + + diff --git a/nx-session-launcher/nx-session-launcher b/nx-session-launcher/nx-session-launcher new file mode 100644 index 0000000..7d25a89 --- /dev/null +++ b/nx-session-launcher/nx-session-launcher @@ -0,0 +1,170 @@ +#!/usr/bin/env python + +import xml.parsers.expat as expat +import os +import gobject +import dbus +import sys +import logging + +logging.basicConfig (level=logging.ERROR, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', stream=sys.stderr) +log = logging.getLogger ("nx-session-launcher") +log.debug ("Starting nx-session-launcher") + +# Getting the system dbus +bus = dbus.SystemBus () + +USE_PK_CREDENTIALS = False + +# ------------------- ConsoleKit integration ------------------------ + +# Getting the ConsoleKit object +ck_manager_obj = bus.get_object ('org.freedesktop.ConsoleKit', '/org/freedesktop/ConsoleKit/Manager') +ck_manager = dbus.Interface (ck_manager_obj, 'org.freedesktop.ConsoleKit.Manager') +objs = ck_manager.GetSeats () + +nx_create_session = os.getenv('NX_CREATE_CK_SESSION') +create_session = True +if nx_create_session == "false": + create_session = False + +nx_session_type = os.getenv('NX_SESSION_TYPE') +if nx_session_type == None: + nx_session_type = "nx" +display = os.getenv('DISPLAY') + +# Get the current session +current_cookie = os.getenv('XDG_SESSION_COOKIE') +current_session = None +if current_cookie != None: + current_session = ck_manager.GetSessionForCookie (current_cookie) + +def takeOwnership(): + log.debug ("NX_CREATE_CK_SESSION = " + current_cookie) + log.debug ("Not creating a CK session") + + session_obj = bus.get_object ('org.freedesktop.ConsoleKit', current_session) + session = dbus.Interface (session_obj, 'org.freedesktop.ConsoleKit.Session') + + properties = dbus.Interface (session_obj, 'org.freedesktop.DBus.Properties') + try: + properties.Set ("org.freedesktop.DBus.Properties", "active", dbus.Boolean (True, variant_level=1)) + properties.Set ("org.freedesktop.DBus.Properties", "is-local", dbus.Boolean (True, variant_level=1)) + properties.Set ("org.freedesktop.DBus.Properties", "session-type", dbus.String (nx_session_type, variant_level=1)) + if display != None: + properties.Set ("org.freedesktop.DBus.Properties", "x11-display", dbus.String (display, variant_level=1)) + log.debug ("Ownership taken") + return True + except expat.ExpatError, e: + error_string = str(e) + log.error ("Error: " + error_string) + log.error ("Falling back to create a new session") + return False + except dbus.DBusException, e: + error_string = str(e) + log.error ("Error: " + error_string) + log.error ("Falling back to create a new session") + return False + except Exception, e: + error_string = str(e) + log.error ("Error: " + error_string) + log.error ("Falling back to create a new session") + return False + +def createSession(): + try: + # Defining the session attributes + params = dbus.Array ([], signature = "(sv)") + params.append (("unix-user", dbus.Int32 (os.getuid(), variant_level=1))) + params.append (("session-type", dbus.String (nx_session_type, variant_level=1))) + if display != None: + params.append (("x11-display", dbus.String (display, variant_level=1))) + params.append (("is-local", dbus.Boolean (True, variant_level=1))) + + # Create the ConsoleKit session + cookie = ck_manager.OpenSessionWithParameters (params) + log.debug ("Session " + cookie + " created") + + # Exporting the XDG_SESSION_COOKIE variable + os.environ['XDG_SESSION_COOKIE'] = cookie + + # Getting the ConsoleKit session + current_session = ck_manager.GetSessionForCookie (cookie) + session_obj = bus.get_object ('org.freedesktop.ConsoleKit', current_session) + session = dbus.Interface (session_obj, 'org.freedesktop.ConsoleKit.Session') + + # Setting the session as active + properties = dbus.Interface (session_obj, 'org.freedesktop.DBus.Properties') + properties.Set ("org.freedesktop.DBus.Properties", "active", dbus.Boolean (True, variant_level=1)) + + except dbus.DBusException, e: + # Dbus error problably you don't have the dbus rule installed or your launcher is not suid nx + # Open session without the parameters + log.error ("Failed to create a CK session using parameters") + + error_string = str(e) + log.error ("Error: " + error_string) + + # Create the ConsoleKit session + cookie = ck_manager.OpenSession () + log.debug ("Session " + cookie + " created") + + # Exporting the XDG_SESSION_COOKIE variable + os.environ['XDG_SESSION_COOKIE'] = cookie + +def checkPermission (): + if USE_PK_CREDENTIALS == False: + return True + + policykit = bus.get_object ('org.freedesktop.PolicyKit', '/', "org/freedesktop/PolicyKit") + + if(policykit == None): + log.error ("Error: Could not get PolicyKit D-Bus Interface\n") + else: + polkit_interface = dbus.Interface (policykit, 'org.freedesktop.PolicyKit') + + try: + granted = polkit_interface.IsProcessAuthorized ("freenx.session.create", os.getpid(), "false") + + if granted == "yes": + return True + else: + return False + + except dbus.DBusException, e : + # Dbus error problably you don't have the PolicyKit rule installed + error_string = str(e) + log.error ("Error: " + error_string) + + +if create_session and ( current_session == None or not takeOwnership () ): + log.debug("Creating a new session") + createSession () + pid = os.fork () + if pid == -1: + log.rrror ("error forking child") + elif pid == 0: + log.debug ("Forked") + else: + # Parent + status = os.waitpid (pid, 0) + os._exit (0) + +if os.geteuid () != os.getuid (): + # Drop setuid privilege + os.setreuid(os.getuid(), os.getuid()) + + os.environ ['NX_CREATE_CK_SESSION'] = "false" + + # Reexecute this script to really drop euid privilege +# os.spawnvp (os.P_WAIT, sys.argv[0], sys.argv) +# sys.exit() + +args = sys.argv +args.pop(0) +log.info ("Launching the program\n") +if checkPermission (): + os.execvp(args[0], args) +else: + log.error ("You don't have permission to execute the action\n") + diff --git a/nx-session-launcher/nx-session-launcher-suid.c b/nx-session-launcher/nx-session-launcher-suid.c new file mode 100644 index 0000000..4174852 --- /dev/null +++ b/nx-session-launcher/nx-session-launcher-suid.c @@ -0,0 +1,54 @@ +/* + * Copyright 2007 Google Inc. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Authors: alriddoch@google.com (Alistair Riddoch) + * freenx@fabian-franz.de (Fabian Franz) + */ + +#include +#include +#include + +#ifndef SESSION_LAUNCHER_COMMAND +#define SESSION_LAUNCHER_COMMAND "/usr/bin/nx-session-launcher" +#endif + +#define CK_LAUNCH_SESSION_COMMAND "/usr/bin/ck-launch-session" + +int main(int argc, char ** argv) +{ + char ** new_argv; + new_argv = calloc(argc + 1, sizeof(char *)); + int i; + + for (i = 1; i < argc; ++i) { + new_argv[i] = argv[i]; + } + + uid_t calling_uid = getuid(); + + if (geteuid() == calling_uid) { + printf("Not running suid. Executing ck-launch-session.\n"); + + new_argv[0] = CK_LAUNCH_SESSION_COMMAND; + + }else{ + new_argv[0] = SESSION_LAUNCHER_COMMAND; + } + + return execv(new_argv[0], new_argv); +} diff --git a/nxcheckload.sample b/nxcheckload.sample new file mode 100755 index 0000000..bdbad6c --- /dev/null +++ b/nxcheckload.sample @@ -0,0 +1,67 @@ +#!/bin/bash +# +# nxcheckload - sample script for calculation of the load for a node. +# +# Version 0.5 +# +# Under GPL +# +# Jonathan "Arrouan" ROUZAUD-CORNABAS (rouzaud.jonathan@gmail.com) +# +# Fabian Franz +# +# 0.5 +# - Rewrote huge parts +# +# Change between 0.3 and 0.4 +# - Add of TMP_FILE +# - Add of lock file to avoid two run at once. +# +# Change between 0.2 and 0.3 +# - SMP support. +# + +if [ "$1" != "" ]; then + # Connect to a remote node + + # Note: This is a ssh sample, you'll need to tweak it for your setup + # and setup the secret keys for yourself. + + #exec $COMMAND_SSH nxcal@"$1" "$PATH_BIN/nxcheckload" + + # Note: This is a netcat example. You need to have nxcheckload running through + # netpipes or netcat like follows: + # node1:~$ faucet 9876 -io $PATH_BIN/nxcheckload + # + # Connect to another node running the load-service on some port. + # + + #exec $COMMAND_NETCAT "$1" 9876 + + # Same as loadbalance_rr_random + # pick a node by random. + + echo $RANDOM + exit 0 +fi + +# Be sure to use C numeric for calculations +export LC_NUMERIC=C + +# The 3 variables of load from uptime +LOADXX=$(awk '{ printf("(100-%s)+(100-%s)+(100-%s)\n", $1, $2, $3); }' /proc/loadavg | bc -q) #" + +# Add of total memory and free memory +Mt=$(awk 'BEGIN { N=0 } /MemTotal|MemFree/ { N+=$2; } END { print N }' /proc/meminfo) + +# NBCPU = number of CPU +NBCPU=$(cat /proc/cpuinfo | grep ^processor | wc -l) + +# CPU = Mhz of the CPU +CPU=$(cat /proc/cpuinfo | grep "cpu MHz" | head -n1 | cut -d':' -f2 | cut -d' ' -f2) + +# Number of Xorg already launch and running. +UNB=$(ps aux | grep Xorg | grep -v grep | wc -l) + +# Final calcul of the number of load. +echo "100 * $LOADXX + $Mt + ( $NBCPU * $CPU ) / 100 + $UNB * 100" | bc -q | cut -d. -f1 diff --git a/nxdialog.freenx b/nxdialog.freenx new file mode 100755 index 0000000..682ec83 --- /dev/null +++ b/nxdialog.freenx @@ -0,0 +1,298 @@ +#!/bin/bash +# +# Copyright (c) 2004 by Fabian Franz +# (c) 2004 by Rick Stout +# +# License: GPL, version 2 +# +# Note: NX does not check the exit-code from nxclient, +# but we set it to a "good value" anyway in case +# it does check it someday. +# +# SVN: $Id: nxdialog 512 2008-03-10 23:01:03Z fabianx $ +# +# ======================================================================== + +#JJK: borrowed from Aron Griffis + +function requote { + declare arg + for arg; do + arg=$(printf '%q' "$arg") + printf '%s ' "${arg:-''}" + done +} + +PARAMS=( "$@" ) +INPUTS=$(requote "$@") #JJK: Save input parameter line... + +TEMP=`getopt -a -o d: --long local,noautokill,dialog:,caption:,message:,display:,parent: -n $(basename $0) -- "$@"` + +if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi + +# Note the quotes around `$TEMP': they are essential! +eval set -- "$TEMP" + +DIALOG_TYPE="ok"; +DIALOG_CAPTION="" +DIALOG_MESSAGE="" +DIALOG_LOCAL="" +DIALOG_NOAUTOKILL="" +DIALOG_PARENT="$PPID" + +while true; do + case "$1" in + --dialog) DIALOG_TYPE="$2"; shift 2 ;; + --caption) DIALOG_CAPTION="$2"; shift 2 ;; + --message) DIALOG_MESSAGE="$2"; shift 2 ;; + --local) DIALOG_LOCAL="yes"; shift ;; + --noautokill) DIALOG_NOAUTOKILL="yes"; shift ;; + --display) DISPLAY="$2"; shift 2 ;; + --parent) DIALOG_PARENT="$2"; shift 2 ;; + --) shift ; break ;; + *) echo "Internal error!" ; exit 1; ;; + esac +done + +export DISPLAY + +# First check if the commercial nxclient is available and use it +# but check that it isn't this script to prevent a loop! +# +# Also check that not --printer was used, because the commercial +# client does not like large databases like used when ENABLE_FOOMATIC=1. +# +# This seems to be because the used sorting algorithm scales in O(n^2). +# +# This is now fixed in NXClient 3.0.0, but still people sometimes use +# older clients. + +[ -x "/usr/bin/nxclient" ] && NXCLIENT="/usr/bin/nxclient" +[ -x "/usr/NX/bin/nxclient" ] && NXCLIENT="/usr/NX/bin/nxclient" +[ -z "$NXCLIENT" ] && NXCLIENT="/usr/NX/bin/nxclient" +[ -x "$NXCLIENT" ] && exec ${NXCLIENT} "${PARAMS[@]}" + +if [ -x "/usr/bin/xvt" ] ; then + xterm_command="/usr/bin/xvt" +else + xterm_command=`which xterm` +fi + +if [ -x /usr/bin/zenity ]; then + dialog_interface="zenity" + DIALOG=/usr/bin/zenity +# FIXME: This should be COMMAND_XDIALOG, ... +elif [ -x /usr/bin/Xdialog ]; then + dialog_interface="xdialog" + DIALOG=/usr/bin/Xdialog # just in case that we have no good path +elif [ -x /usr/bin/dialog ]; then + #JJK: Added 'dialog_interface=dialog' option because Xdialog not standard + #JJK: on some distros such as Fedora and xmessage won't handle long + #JJK: lists of ppd files while the combination of 'dialog' and 'xterm' + #JJK: should be present on most setups. + + dialog_interface="dialog" + DIALOG=/usr/bin/dialog + if [ -z "$NXCLIENT_FIRST_TIME" ]; then + # Run only once in case of subdialogs. Capture result in tempfile + TMPFILE=$(mktemp /tmp/nxclient.XXXXX) + export NXCLIENT_FIRST_TIME=1 + $xterm_command -geometry 120x24+100+100 +sb -title "NXclient" -e \ + /bin/bash -c "$DIALOG --infobox 'Please wait...' 3 25; $0 $INPUTS | tee $TMPFILE" \ + || exit 1 + #Need to recover the last line output (and not remove non-printing chars, because --stdout is used) + tail -1 $TMPFILE + rm -f $TMPFILE + exit 0 + fi +else + dialog_interface="xmessage" + xmessage=$(which xmessage 2>/dev/null) + [ -z "$xmessage" ] && xmessage="/usr/X11R6/bin/xmessage" +fi + +# +# xmessage dialog interface +# + +xmessage_ok() { + $xmessage -buttons "Ok:0" -center "$DIALOG_MESSAGE" + return 0 # Give cancel on close ... +} + +xmessage_yesno() { + $xmessage -buttons "Yes:2,No:0" -center "$DIALOG_MESSAGE" +} + +xmessage_yesnosuspend() { + $xmessage -buttons "Suspend:3,Terminate:2,Cancel:0" -center "$DIALOG_MESSAGE" +} + +xmessage_panic() { + $xmessage -buttons "Terminate:2,Cancel:0" -center "$DIALOG_MESSAGE" +} + +xmessage_quit() { + $xmessage -buttons "Quit:0" -center "$DIALOG_MESSAGE" + return 0 # Give cancel on close ... +} + +# +# zenity interface +# + +zenity_ok() { + $DIALOG --info --title="$DIALOG_CAPTION" --text="$DIALOG_MESSAGE" + return 0 # Give cancel on close ... +} + +zenity_yesno() { + $DIALOG --question --title="$DIALOG_CAPTION" --text="$DIALOG_MESSAGE" + RC=$? + [ $RC -eq 0 ] && return 2 + [ $RC -eq 1 ] && return 0 +} + +zenity_yesnosuspend() { + Suspend="Disconnect (Suspend session)" + Terminate="Terminate (Log Out)" + ans=$($DIALOG --title="$DIALOG_CAPTION" \ + --text="$DIALOG_MESSAGE Close this dialog to cancel." \ + --list --radiolist --column "" --column "" \ + TRUE "$Terminate" FALSE "$Suspend") + RC=$? + case $ans in + $Terminate) + return 2; + ;; + $Suspend) + return 3; + esac + [ $RC -eq 1 ] && return 0 +} + +zenity_panic() { + $DIALOG --question --no-wrap --title="$DIALOG_CAPTION" \ + --ok-label="Terminate" --cancel-label="Cancel" \ + --text="$DIALOG_MESSAGE" + RC=$? + [ $RC -eq 0 ] && return 2 + [ $RC -eq 1 ] && return 0 +} + +zenity_quit() { + $DIALOG --info --title="$DIALOG_CAPTION" --text="$DIALOG_MESSAGE" + return 0 # Give cancel on close ... +} + +#" +# xdialog interface +# + +xdialog_ok() { + $DIALOG --title "$DIALOG_CAPTION" --msgbox "$DIALOG_MESSAGE" 0 0 + return 0 # Give cancel on close ... +} + +xdialog_yesno() { + $DIALOG --title "$DIALOG_CAPTION" --yesno "$DIALOG_MESSAGE" 0 0 + RC=$? + [ $RC -eq 0 ] && return 2 + [ $RC -eq 1 ] && return 0 +} + +xdialog_yesnosuspend() { + $DIALOG --title "$DIALOG_CAPTION" --buttons-style text \ + --ok-label "Suspend" --cancel-label "Terminate" \ + --yesno "$DIALOG_MESSAGE Close this dialog to cancel." 400x150 + RC=$? + [ $RC -eq 0 ] && return 3 + [ $RC -eq 1 ] && return 2 +} + +xdialog_panic() { + $DIALOG --title "$DIALOG_CAPTION" --buttons-style text --default-no \ + --ok-label "Terminate" --cancel-label "Cancel" \ + --yesno "$DIALOG_MESSAGE" 0x0 + RC=$? + [ $RC -eq 0 ] && return 2 + [ $RC -eq 1 ] && return 0 +} + +xdialog_quit() { + $DIALOG --buttons-style text --ok-label "Quit" --title "$DIALOG_CAPTION" \ + --msgbox "$DIALOG_MESSAGE" 0 0 + return 0 # Give cancel on close ... +} + +#JJK: dialog interface " +# These are analogous to the Xdialog functions with a few subtle +# syntax differences +# + +dialog_ok() { + $DIALOG --stdout --title "$DIALOG_CAPTION" --msgbox "$DIALOG_MESSAGE" 0 0 + return 0 # Give cancel on close ... +} + +dialog_yesno() { + $DIALOG --stdout --title "$DIALOG_CAPTION" --yesno "$DIALOG_MESSAGE" 0 0 + RC=$? + [ $RC -eq 0 ] && return 2 + [ $RC -eq 1 ] && return 0 +} + +dialog_yesnosuspend() { + $DIALOG --stdout --title "$DIALOG_CAPTION" --yes-label "Suspend" \ + --no-label "Terminate" \ + --yesno "$DIALOG_MESSAGE\n\nPress 'Esc' to cancel." 8 60 + RC=$? + [ $RC -eq 0 ] && return 3 + [ $RC -eq 1 ] && return 2 +} + +dialog_panic() { + $DIALOG --stdout --title "$DIALOG_CAPTION" --defaultno \ + --yes-label "Terminate" --no-label "Cancel" \ + --yesno "$DIALOG_MESSAGE" 0 0 + RC=$? + [ $RC -eq 0 ] && return 2 + [ $RC -eq 1 ] && return 0 +} + +dialog_quit() { + $DIALOG --stdout --ok-label "Quit" --title "$DIALOG_CAPTION" \ + --msgbox "$DIALOG_MESSAGE" 0 0 + return 0 # Give cancel on close ... +} + +# +# main case statement +# + +case $DIALOG_TYPE in + ok) + ${dialog_interface}_ok + ;; + yesno) + ${dialog_interface}_yesno + ;; + yesnosuspend) + ${dialog_interface}_yesnosuspend + ;; + panic) + ${dialog_interface}_panic + ;; + quit) + ${dialog_interface}_quit + ;; +esac + +# +# Time for exit code checks :) +# + +RC=$? +[ $RC -eq 2 ] && kill -TERM $DIALOG_PARENT +[ $RC -eq 3 ] && kill -HUP $DIALOG_PARENT +exit 0 diff --git a/nxfuncs b/nxfuncs new file mode 100644 index 0000000..bd4a7d5 --- /dev/null +++ b/nxfuncs @@ -0,0 +1,437 @@ +#!/bin/bash +# +# Copyright (c) 2020 by Dmitry Borisov +# +# License: GPL, version 2 +# +# ======================================================================== + +ip4_pattern='[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+' +num_pattern='[+-]?[0-9]+([.][0-9]+)?' + +# setup NX_ETC_DIR here because we allways should to read settings first +NX_ETC_DIR="/etc/nxserver" +sq_settings_fn="$NX_ETC_DIR/nxsettings.sq3" + +# following two functions are Copyright by Klaus Knopper +stringinstring() { case "$2" in *$1*) return 0;; esac; return 1; } + +getparam() { +#args: [recode_hex_%NN] [delimiter='&'] +# Reread given line; echo last parameter's argument or return false. + local d='&'; [ -n "$4" ] && d="$4" + local pattern=".*$d$2=([^$d]*)" str="$d$1" r; + [[ "$str" =~ $pattern ]]; r=${BASH_REMATCH[1]} + [ -n "$3" ] && echo -e "${r//\%/\\x}" || echo "$r" + [ "$BASH_REMATCH" != "" ] +} + +delparam() { +#args: [delimiter='&'] +# Delete parameter with value. + local d='&'; [ -n "$3" ] && d="$3" + local pat=".*($d$2=[^$d]*)" str="$1" r; + [ "${str:0:1}" = "$d" ] || str="$d$str" + [[ "$str" =~ $pat ]]; r=${BASH_REMATCH[1]} + echo "${str/$r/}" +} + +trim() { + local v="$*"; v=${v#${v%%[![:space:]]*}}; + v=${v%${v##*[![:space:]]}}; echo -n "$v" +} + +fcount() { +#args: [delim=$'\n'] +#ret: count of fields (lines by default) + local IFS=$'\n'; [ -n "$2" ] && IFS="$2" + local a=($1); echo "${#a[@]}" +} + +cutfn() { +#args: line field_num_start_at_0 [delim=$IFS] + set -f + if [ -n "$3" ]; then local IFS="$3"; fi + local a=($1); + #echo "${a[($2)]}" # negative values works on all systems? + echo "${a[@]:($2):1}" + set +f +} + +rematchfn(){ +#args: (pattern) [match_num=0] [reversive] +# if match_num == "all" returns all found matches delimited by newlines + local pat n OIFS a ntl nr a r r1 res; + pat="$1"; [ -z "$3" -o "$3" = "all" ] && n=0 || n="$3" + OIFS=$IFS; local IFS=$'\n'; a=($2); IFS=$OIFS; + ntl=${#a[@]}; nr=0; r=(); res=""; + if [ -z "$4" ]; then + for ((i=0;i<$ntl;i++)) { + [[ "${a[$i]}" =~ $pat ]] || continue + ((nr++)); r+=(${BASH_REMATCH[1]}) + [ "$nr" = "$n" ] && break + } + else + for ((i=$ntl;i>=0;i--)) { + [[ "${a[$i]}" =~ $pat ]] || continue + ((nr++)); r+=(${BASH_REMATCH[1]}) + [ "$nr" = "$n" ] && break + } + fi + if [ "$3" = "all" ]; then + for r1 in ${r[@]}; do res+="${res:+$'\n'}$r1"; done + echo "$res" + else echo "${r[($n)]}" + fi + [ "$nr" != "0" ] +} + +set_vars_from_params() { +#args: [var_prefix=""] [%hex_recode=""] +# varnames_list_delimited_by_spaces_or_commas + local vnames vn vv; + vnames="${2//,/ }" + for vn in $vnames; do + vv=$(getparam "$1" $vn $4); #[ -z "$vv" ] && continue; + declare -g $3$vn="$vv" + done +} + +set_vars_from_ampstr() { +#param: [var_prefix=""] [%hex_recode=""] + local kv vn vv; + local IFS='&'; local -a a=($1) a2; + for kv in ${a[@]}; do + IFS='=' a2=($kv); vn=${a2[0]}; [ -z "$vn" ] && continue; + vv=${a2[1]}; [ -n "$3" ] && vv=$(echo -e "${vv//\%/\\x}") + declare -g $2$vn=$vv + done +} + +set_vars_from_ampvals() { +#args: [var_prefix=""] [%hex_recode=""] +# varnames_list_delimited_by_spaces_or_commas, values delimited by '&' + local vnames vn vv i=0 + local OIFS=$IFS IFS='&' a + a=($1); IFS=$OIFS; vnames="${2//,/ }" + for vn in $vnames; do + vv=${a[$i]}; declare -g $4$vn="$vv"; ((i++)) + done +} + +port_is_listening() { +#args: [host=127.0.0.1] [proto=tcp] + local hip="127.0.0.1"; [ -n "$3" ] && hip=$2 + local proto="tcp"; [ -n "$3" ] && proto=$3 + 2>/dev/null > /dev/$proto/$hip/$1 +} + +# =========================================================================== +# sqlite3 functions +declare -g sq_cmd="/usr/bin/sqlite3"; +declare -g DBE_PID="" DBE_PIDS_FILE=""; + +lock_dbe() { +#arg: [wait_cycles=80] [whit_step=0.05s] + local i rc ccls=60; [ -n "$1" ] && ccls=$1 + local step=0.05; [ -n "$2" ] && step=$2 + for (( i=0; i<=ccls; i++ )); do + mkdir "$DBE_PIDS_FILE.lock" &>/dev/null; rc=$? + [ $rc -eq 0 ] && break + sleep $step"s" + done + return $rc +} + +unlock_dbe() { rmdir "$DBE_PIDS_FILE.lock" &>/dev/null; return 0; } + +q_dbe0() { + local rc + echo -e "$@" >/proc/$DBE_PID/fd/0; rc=$? + return $rc +} + +q_dbe() { + local rc; lock_dbe || return 1 + q_dbe0 "$@"; rc=$? + unlock_dbe; return $rc +} + +qa_dbe0() { +#args: ... + local qstr="$@" r res=""; qstr+="SELECT '{end}';" + echo -e "$qstr" >/proc/$DBE_PID/fd/0 + while read r ... + local rc + lock_dbe || return 1 + local res=$(qa_dbe0 "$@"); rc=$? + echo "$res"; unlock_dbe; return $rc +} + +ctl_dbe() { +#arg: + #coproc /usr/bin/stdbuf -i0 -o0 $sq_cmd -batch 2>/tmp/dbe_stderr-$$.log + coproc /usr/bin/stdbuf -i0 -o0 $sq_cmd -batch 2>/dev/null + echo "$COPROC_PID" > "$DBE_PIDS_FILE" + wait $COPROC_PID +} + +open_dbe() { +#arg: +#ret: 0 if dbe started, 1 - dbe connected, 2 - error; + #echo "open dbe start $1" + local new_dbe="" pids cntr; + [ "$USER" != "nx" ] && DBE_PIDS_FILE="/var/lock/nxdbe-$USER" + if [ -z "$DBE_PID" ]; then + if [ -r "$DBE_PIDS_FILE" ]; then + pids=($(< "$DBE_PIDS_FILE")); DBE_PID=${pids[0]}; + else new_dbe="1" + fi + fi + if [ -n "$DBE_PID" ]; then + if kill -0 $DBE_PID 2>/dev/null; then + echo "$1" >> "$DBE_PIDS_FILE" + return 1 + else + DBE_PID=""; rm -f "$DBE_PIDS_FILE"; new_dbe="1"; + #echo "rm old pidfile"; + fi + fi + if [ -n "$new_dbe" ]; then + local dbc_pid=""; + [ "$USER" = "nx" ] && DBE_PIDS_FILE="/var/lock/nxdbe-$1" + (ctl_dbe $1) & + dbc_pid=$!; disown $dbc_pid; + cntr=200; + while [ ! -e "$DBE_PIDS_FILE" ]; do sleep 0.01s; ((cntr--)); ((cntr<=0)) && break; done + #echo "create dbe $((200-cntr))0 ms" + DBE_PID=$(< "$DBE_PIDS_FILE"); echo "$1" >> "$DBE_PIDS_FILE" + q_dbe ".timeout 500\n.separator '&'" # not work with later attached tables after '.mode csv tname' + #q_dbe "PRAGMA journal_mode = WAL;" # causes error on keyslst_for_user() now + return 0 + fi + return 2 +} + +attach_db() { +#args: [ro=""] + local dbname=${1##*\/}; dbname=${dbname%.*} + local db=$1; [ -n "$2" ] && db="file:$1?mode=ro" + q_dbe "ATTACH DATABASE '$db' AS $dbname;" +} + +close_dbe() { +#arg: +# if arg empty close ultimately + #echo "dbe close start - $1; $DBE_PIDS_FILE; $DBE_PID" + [ -z "$DBE_PID" ] && return + [ ! -e "$DBE_PIDS_FILE" ] && return + local pids=($(< "$DBE_PIDS_FILE")) + local chgfl="" i; + for ((i=1; i<${#pids[@]}; i++)) do + if kill -0 ${pids[i]} &>/dev/null; then + [ "$1" = "${pids[$i]}" ] && { unset pids[i]; chgfl="1"; } + else + unset pids[i]; chgfl="1" + fi + done + if ((${#pids[@]}>1)); then + [ -n "$chgfl" ] && echo ${pids[@]} > "$DBE_PIDS_FILE" + return 1 + fi + q_dbe ".quit"; unset DBE_PID; rm -f "$DBE_PIDS_FILE" + return 0 +} + +exit_proc() { + close_dbe $$; exit $1; +} + +s2sq() { + local res="$1" v + v=${res:0:1}; stringinstring "$v" "'\"" && res=${res:1:-1} + res=${res//&/%26}; res="${res//\"/%22}"; res="${res//\'/%27}" + echo "$res" +} + +sq2s() { + local res="$1"; [ "$res" = "\"\"" ] && return + res=${res//%26/&}; res="${res//%22/\"}"; res="${res//%27/\'}" + echo "$res" +} + +colval_set_or_cond() { +#args: [cond] [values_delim='&'] +#ret: string of columns and values for SET or for WHERE +# if cond='INS' returns list_cols&list_vals for INSERT env + local delim="&"; [ -n "$4" ] && delim="$4" + local ret="" r2="" key val keys=(${1//,/ }); + OIFS=$IFS; IFS=$delim; local -a vals=($2); IFS=$OIFS + for idx in ${!keys[*]}; do + key=${keys[$idx]}; val=${vals[$idx]} + if [ -z "$3" ]; then # set env + [ "$val" = "NULL" -o "$val" = "null" ] && continue + ret+="${ret:+,}$key='$val'" + elif [ "$3" = "INS" ]; then # ins env + [ "$val" = "NULL" -o "$val" = "null" ] && continue + ret+="${ret:+,}$key"; r2+="${r2:+,}'$val'" + else # cond env + if [ "$val" = "NULL" -o "$val" = "null" ]; then + ret+="${ret:+ $4 }$key IS NULL" + else ret+="${ret:+ $4 }$key='$val'" + fi + fi + #echo "\"$key\" = \"$val\"" + done + [ "$3" = "INS" ] && ret+="&$r2" + echo "$ret" +} + +q_row_ins() { +#args: [values_delim='&'] + local colvals=$(colval_set_or_cond "$2" "$3" "INS" "$4") + local keys=${colvals%%&*} vals=${colvals#*&} + q_dbe "INSERT INTO $1($keys) VALUES($vals);" +} + +q_rows_upd() { +#args: [values_delim='&'] + local setls=$(colval_set_or_cond "$3" "$4" "" "$5") + q_dbe "UPDATE $1 SET $setls WHERE $2;" +} + +q_vals_str_get() { +#args: [values_delim='&'] + local d="&"; [ -n "$4" ] && d="$4"; + local mode=".mode csv $1\n.separator '$d'\n" + local rs=$(qa_dbe "$mode" "SELECT count(*),$3 FROM $1 WHERE $2 LIMIT 1;") #" + [ "${rs%%$d*}" -gt "0" 2>/dev/null ] || { echo; return 1; } + local ret=${rs#*$d}; ret=${ret//\"/} + echo "$ret" +} + +q_vals_strs_get() { +#args: [query_tail_str] [values_delim='&'] + local d="&"; [ -n "$5" ] && d="$5"; + local mode=".mode csv $1\n.separator '$d'\n" + local rs=$(qa_dbe "$mode" "SELECT $3 FROM $1 WHERE $2 $4;") #" + local ret=${rs//\"/} + echo "$ret" +} + +str_eq_cond() { +#args: expr vals_str [vals_delim='|'] [NOT=""] +#ret: "expr IN ('A','B','C'...)" or "expr='A'" + local delim="|"; [ -n "$3" ] && delim="$3"; + local comma="" ivs="$2" val vals=""; + local inv1="" inv2="" + [ -n "$4" ] && { inv1="!"; inv2=" NOT"; } + [ -z "$ivs" ] && ivs="NULL" || ivs=${ivs//$delim/$'\n'} + while read val; do comma="${vals:+,}"; vals+="$comma'$val'"; done <<< "$ivs" + if [ -n "$comma" ]; then echo "$1$inv2 IN ($vals)" + elif [ "$ivs" = "NULL" ]; then echo "$1 IS$inv2 NULL" + else echo "$1$inv1=$vals" + fi +} + +q_where_str() { +#arg: term1[&term2...]; term: +#cond: = != > < >= <= ; val_str: val1[|val2...] or val_start,val_end +#ret: formated string for sqlite WHERE + local oifs=$IFS IFS='&' terms i res; terms=($1); IFS=$oifs + local pat exp cond inv vals start_val stop_val s simple + for ((i=0;i<${#terms[@]};i++)) { + local pat="([[:alnum:]]+)([^[:alnum:]]+)(.+)" + [[ "${terms[$i]}" =~ $pat ]] || continue + exp=${BASH_REMATCH[1]}; cond=${BASH_REMATCH[2]}; vals=${BASH_REMATCH[3]} + #echo "$exp : $cond : $vals" #debug + [ "${cond:0:1}" = "!" ] && inv=" NOT" || inv="" + simple=0; stringinstring '>' "$cond" && simple=1 + [ "$simle" = "0" ] && stringinstring '<' "$cond" && simple=1 + if stringinstring ',' "$vals"; then + start_val=$(cutfn "$vals" 0 ','); stop_val=$(cutfn "$vals" 1 ',') + s="$exp$inv BETWEEN $start_val AND $stop_val" + elif [ "$simple" = "0" ]; then + s=$(str_eq_cond "$exp" "$vals" "" "$inv") + else + s="$exp$cond$vals" + fi + res+=${res:+ AND }$s + } + echo "$res" +} + +q_sort_str() { +#arg: exp1[!][,exp2...] +#if '!' present then DESC else ASC +#ret: formated string for sqlite ORDER BY + local oifs=$IFS IFS=',' terms i exp order res; terms=($1); IFS=$oifs + for ((i=0;i<${#terms[@]};i++)) { + exp=${terms[$i]} + if [ "${exp:(-1):1}" = "!" ]; then order="DESC"; exp=${exp::-1} + else order="ASC" + fi + res+="${res:+,}$exp $order" + } + echo "$res" +} + +qtxt2cmdstrs() { +#params: +#ret: nx command strings + local res="" fl="1" line k v; + while read line; do + [ -z "$line" ] && { res+=$'\n'; fl=1; continue; } + [ "$fl" = "1" ] && { res+="a=b&"; fl=0; } + k=$(trim "$(cutfn "$line" 0 '=')") #" + v=$(trim "$(cutfn "$line" 1 '=')") #" + res+="$k=$v&" + done <<< "$@" + echo "$res" +} + +# =========================================================================== +# functions to read settings + +set_vars_from_db() { +#args: [varnames_list_delimited_by_commas] [[username] [only_users_vars=""]] +# if varnames is empty str rquests all variables +# if username is empty str rquests all variables for NULL +# if username is not empty str rquests all variables user over NULL +# if username and only_users_vars are not empty str rquests users variables only + local mode=".mode csv settings\n.separator '&'\n" + local qstr0 qs_keys0="" qs_keys="" ts a qstr var value; + local keylist + [ -n "$1" ] && { + keylist="'${1//,/\',\'}'" + qs_keys0=" AND key IN ($keylist)" + qs_keys=" AND rs.key IN ($keylist)" + } + if [ -n "$2" ]; then + [ -n "$3" ] && \ + qstr="SELECT key,value FROM settings WHERE user='$2' $qs_keys0;" || \ + qstr="SELECT rs.key,coalesce(us.value,rs.value) \ + as value FROM settings AS rs LEFT JOIN settings AS us ON us.key=rs.key \ + AND us.user='$2' WHERE rs.user IS NULL $qs_keys;" + else + qstr="SELECT key,value FROM settings WHERE user IS NULL $qs_keys0;" + fi + #echo "$qstr" #debug + ts=$(qa_dbe "$mode" "$qstr"); #echo "$ts" #debug + while read line; do + [ -n "$line" ] || continue + local OIFS="$IFS"; local IFS='&'; a=($line); IFS="$OIFS" + var=${a[0]}; value=${a[1]}; value=${value//\"/}; value=$(sq2s "$value") + declare -g $var="$value"; + #echo "$var=\"$value\"" #debug + done <<< "$ts" +} diff --git a/nxkeygen b/nxkeygen new file mode 100755 index 0000000..711fafb --- /dev/null +++ b/nxkeygen @@ -0,0 +1,85 @@ +#!/bin/bash +# +# /usr/NX/bin/nxkeygen +# Create a new client/server key pair +# +# Originally written for Gentoo Linux +# +# Author Stuart Herbert +# (stuart@gentoo.org) +# +# Copyright (c) 2004 Gentoo Foundation +# Released under v2 of the GNU GPL +# +# SVN: $Id: nxkeygen 512 2008-03-10 23:01:03Z fabianx $ +# +# ======================================================================== + +# Read the config file +SHARED_CONFS="/usr/share/freenx-server" +. $SHARED_CONFS/nxfuncs +open_dbe $$ +attach_db "$sq_settings_fn" ro || { + echo "Unable to attach db file $sq_settings_fn"; exit 1; +} +set_vars_from_db + +[ -z "$NX_KEY_DIR" ] && NX_KEY_DIR="$NX_HOME_DIR/.ssh" +DATE="`date '+%Y%m%d-%H%M%S'`" +NX_CLIENT_KEY="${NX_KEY_DIR}/client.id_dsa.key" +NX_SERVER_KEY="${NX_KEY_DIR}/server.id_dsa.pub.key" + +main () { + # create a new key + umask 177 + $COMMAND_SSH_KEYGEN -q -t dsa -N '' -f ${NX_KEY_DIR}/local.id_dsa + + # backup the existing keys + + if [ -f "${NX_SERVER_KEY}" ]; then + echo "Backing up existing server key to ${NX_SERVER_KEY}.${DATE}" + mv -f "${NX_SERVER_KEY}" "${NX_SERVER_KEY}.${DATE}" + fi + + if [ -f "${NX_CLIENT_KEY}" ]; then + echo "Backing up existing client key to ${NX_CLIENT_KEY}.${DATE}" + mv -f "${NX_CLIENT_KEY}" "${NX_CLIENT_KEY}.${DATE}" + fi + + # put the new keys in place + + mv -f "${NX_KEY_DIR}/local.id_dsa" "${NX_CLIENT_KEY}" + mv -f "${NX_KEY_DIR}/local.id_dsa.pub" "${NX_SERVER_KEY}" + + for x in ${NX_CLIENT_KEY} ${NX_SERVER_KEY} ; do + chmod 600 $x + chown nx:root $x + done + + # copy the key to the authorized_keys2 file + rm -f $NX_KEY_DIR/$SSH_AUTHORIZED_KEYS + echo -n "no-port-forwarding,no-agent-forwarding,command=\"$PATH_BIN/nxserver\" " >$NX_KEY_DIR/$SSH_AUTHORIZED_KEYS + cat ${NX_SERVER_KEY} >> $NX_KEY_DIR/$SSH_AUTHORIZED_KEYS + + # Fix ownership of $SSH_AUTHORIZED_KEYS, just in case nxkeygen is run without nxsetup. + + chown nx:root $NX_KEY_DIR/$SSH_AUTHORIZED_KEYS + + # now tell the user what to do + + echo "Unique key generated; your users must install" + echo + echo " ${NX_CLIENT_KEY}" + echo + echo "on their computers." +} + +if [ -f "${NX_SERVER_KEY}" -a -f "${NX_CLIENT_KEY}" -a \ + ! -z "$NX_DONT_OVERRIDE" ]; then + echo "Not overriding the existing key" + exit +fi + +main "$@" + +close_dbe $$ diff --git a/nxnode b/nxnode new file mode 100755 index 0000000..669e42d --- /dev/null +++ b/nxnode @@ -0,0 +1,1487 @@ +#!/bin/bash + +# Free implementation of nxserver components +# Copyright (c) 2004 by Fabian Franz. +# (c) 2008-23 by Dmitry Borisov +# License: GNU GPL, version 2 + +shopt -s extglob + +SHARED_CONFS="/usr/share/freenx-server" +. $SHARED_CONFS/nxfuncs + +[ "$1" = "--admin" ] && { # simple wrapper to start nxserver in admin mode + if stringinstring " nxadmin " " $(groups) "; then + /usr/bin/sudo -p "" /bin/bash -c '/usr/bin/nxserver --admin' 2>&1 + exit $? + else + echo "NX> 2004 admin mode start failed" + exit 1 + fi +} + +# +# ----------------------------------------------------------------------------- +# Various helper functions +# ----------------------------------------------------------------------------- +# +nxlog() { + [ "$NX_LOG_LEVEL" != "0" ] || return + echo "$(date "+%T.%3N"): ${@/password=+([^&])&/password=*&}" >> "$nxuser_logfile" +} + +cp_conv() { +# arg: +# Used config vars: $COMMAND_ICONV $WIN_CP_CONVERT_CHAIN +# successively convert string charset + #local lp="$FUNCNAME ($$/$BASHPID):"; #debug + #nxlog "$lp starting with args \"$@\"" #debug + local res=${1//+/ } cp_pair cp_from cp_to; + [ -n "$COMMAND_ICONV" ] || { echo "$res"; return 1; } + for cp_pair in $WIN_CP_CONVERT_CHAIN ; do + cp_from=$(cutfn "$cp_pair" 0 '>'); [ -n "$cp_from" ] || cp_from="latin1" + cp_to=$(cutfn "$cp_pair" 1 '>'); [ -n "$cp_to" ] || cp_to="UTF-8" + res=$(echo "$res" | $COMMAND_ICONV -f $cp_from -t $cp_to) + #nxlog "$lp converting $cp_from > $cp_to == \"$res\"" #debug + done + #nxlog "$lp return res='$res'" #debug + echo "$res" +} + +# =================== sqlite3 stuff ===================== + +declare -g sqcols_usess="session_id, status, display, type, client,\ + agent_pid, cookie, tail_pid, userip, acc_ip, mmport, cupsport, smbport" + +declare -g sqcols_usvcs="svc, type, status, port, share, username, pass,\ + data, comp, addr" +#svc: internal service name +#type: smb-share | smb-prn | ipp-prn | media-pa | ... +#status: starting|on|stopping|off +#port: tunneled/remote port +#share: incomming share name +#data: options depended of service type eg mount dir... +#comp: remote computer name +#addr: ip address is 127.0.0.1 typically, another if remote connection used + +init_usessions_db() { + local usess_cols="session_id TEXT PRIMARY KEY, status TEXT, display TEXT,\ + type TEXT, client TEXT, agent_pid INT, cookie TEXT, tail_pid INT,\ + userip TEXT, acc_ip TEXT, mmport INT, cupsport INT, smbport INT" + local svcs_cols="svc TEXT PRIMARY KEY, type TEXT, status TEXT, port INT,\ + share TEXT, comp TEXT, addr TEXT, username TEXT, pass TEXT, data TEXT" + local qstr="CREATE TABLE IF NOT EXISTS usessions.usess($usess_cols);" + qstr+="CREATE TABLE IF NOT EXISTS usessions.usvcs($svcs_cols);" + q_dbe "$qstr" +} + +# ------------------ user session (usess) control -------- +usess_add() { q_row_ins "usess" "$1" "$2"; } +#usess_add() args: + +usess_set() { q_rows_upd "usess" "session_id='$1'" "$2" "$3"; } +#usess_set() args: + +usess_get() { q_vals_str_get "usess" "session_id='$1'" "$2" "$3"; } +#usess_get() args: [values_delim='&'] + +usess_close() { +#args: + if [ "$SESSION_LOG_CLEAN" = "1" ]; then + q_dbe "DELETE FROM usess WHERE session_id='$1';" + else + q_rows_upd "usess" "session_id='$1'" "status" "$2" + fi +} + +# -------------- user services (uservices) control -------- +#usvcs_add() args: +usvcs_add() { q_row_ins "usvcs" "$1" "$2"; } + +#usvcs_set() args: +usvcs_set() { q_rows_upd "usvcs" "svc='$1'" "$2" "$3"; } + +#usvcs_get() args: [values_delim='&'] +usvcs_get() { q_vals_str_get "usvcs" "svc='$1'" "$2" "$3"; } + +# +# ----------------------------------------------------------------------------- +# Node functions module +# ----------------------------------------------------------------------------- +# + +sess_lport_name() { +#arg: + case $1 in + smb-share|smb-prn) echo "smbport";; + ipp-prn) echo "cupsport";; + media-pa) echo "mmport";; + esac +} + +norm_dir() { +#args: [parent_dir] +# exclude potential parts to exec and set dir path from given parent_dir + local r=${1//\`/}; r=${r//\$[(\{]*[)\}]/$2}; r=${r/\.\.\//$2\/}; + r=${r/\.\//$2\/}; r=${r/\~\//$2\/} + [[ "${r:0:1}" =~ [[:alnum:]] ]] && r="$2/$r" + echo "$r" +} + +uservice_mounted() { +#args: [port] + local rc=0 txt="" pattern port="" + local patt_addr="127.0.0.1"; [ -n "$4" ] && patt_addr=$4 + case $1 in + smb-share) + # output of mount cmd not contains mount.cifs port option value + # because we need to port arg ($3) + txt=$(env LC_ALL=C $COMMAND_MOUNT_LIST 2>/dev/null) + if stringinstring "//" "$2"; then pattern="($2)" + elif ! stringinstring "/" "$2"; then pattern="//$patt_addr/($2)" + else pattern="($2)" + fi + [ -n "$(rematchfn "$pattern" "$txt")" ] || return 1 + if [ -n "$3" ]; then + port_is_listening $3 || rc=1 + fi + ;; + smb-prn|ipp-prn) + txt=$(env LC_ALL=C $COMMAND_LPSTAT -v 2>/dev/null) + pattern=".*$2.*//$patt_addr:(" + [ -n "$3" ] && pattern+="$3)" || pattern+="$num_pattern)" + port=$(rematchfn "$pattern" "$txt"); rc=$? + [ -n "$port" ] || return $rc + port_is_listening "$port" || rc=1 + ;; + media-pa) + case $2 in + pa) # tunneled pa + #$COMMAND_PA --check || return 1 + txt=$(env LC_ALL=C $COMMAND_PACTL list short 2>/dev/null) + pattern="server=$patt_addr:(" + [ -n "$3" ] && pattern+="$3)" || pattern+="[0-9]+)" + port=$(rematchfn "$pattern" "$txt"); rc=$? + #nxlog "$1 port=$port" #debug + [ -n "$port" ] || return $rc + port_is_listening "$port" || rc=1 + ;; + esac + ;; + esac + return $rc +} + +uservice_configure() { +#args: +# smb-share +# *-prn +# opts="model=;public=;defaultprinter=" +# media-pa <""> <""> + local lp="$FUNCNAME ($$/$BASHPID):"; + local cmdstr optstr comp rc=0 txt errstr uri + case $1 in + smb-share) + # create/check mountpoint + mkdir -p "$6" &>/dev/null + [ -d "$6" ] || { nxlog "$lp unable to create dir='$6'"; return 1; } + local egroup=$(id -gn "$USER") tmpopts=${SMB_MOUNT_OPTIONS//,/&} + local dir_mode=$(getparam "$tmpopts" dir_mode) + dir_mode=${dir_mode:(-3)}; [ -n "$dir_mode" ] || dir_mode="700" + [ "$(stat -c %a "$6")" != "$dir_mode" ] && chown "0$dir_mode" "$6" &>/dev/null + # mount options string + optstr="uid=$USER,gid=$egroup,ip=127.0.0.1,port=$3,username=$4" + [ -n "$5" ] && optstr+=",password=$5" + [ -n "$SMB_MOUNT_OPTIONS" ] && optstr+=",$SMB_MOUNT_OPTIONS" + cmdstr="$COMMAND_SUDO $COMMAND_SMBMOUNT $2 $6 -o $optstr" + echo "$cmdstr" + ;; + smb-prn|ipp-prn) + local model=$(getparam "$6" "model" "" ';') + [ "$model" = "NULL" ] && model="" + local ppdn=${2#$USER}; ppdn=${ppdn:1}; ppdn=${ppdn%#[0-9]*} + local ppdfn="$NX_PPD_DIR/$ppdn.ppd" + [ -r "$ppdfn" ] || { # ppd is not found, search for driver in CUPS + txt=$($COMMAND_LPINFO -m 2>/dev/null) + local str drv="" + [ -n "$model" ] && { + while read str; do + [[ "$str" =~ "$model" ]] && { drv="${str%% *}"; break; } + done <<< "$txt" + } + [ -n "$drv" ] || { + while read str; do + [[ "$str" =~ "$ppdn" ]] && { drv="${str%% *}"; break; } + done <<< "$txt" + } + [ -n "$drv" ] || { + nxlog "$lp '$svc'; CUPS driver for service is not found"; + return 1; } + $COMMAND_PPDCAT cat "$drv" > "$ppdfn" || { + nxlog "$lp Can't save $ppdfn"; return 1; } + } + [ "${1:0:3}" = "smb" ] && \ + uri="nxsmb://$4:$5@127.0.0.1:$3/cifs/$8" || \ + uri="ipp://$4:$5@127.0.0.1:$3/printers/$8" + cmdstr="$COMMAND_SUDO $COMMAND_LPADMIN -p $svc -P $ppdfn -v $uri -E" + echo "$cmdstr" + ;; + media-pa) + case $2 in + pa) # tunneled pa + local uri="127.0.0.1:$3" + # get sink and source from remote pa + local rmods=$(env LC_ALL=C $COMMAND_PACTL -s $uri list short 2>/dev/null) + [ -n "$rmods" ] || { + nxlog "$lp '$svc'; can't get module list from remote PA ($uri)"; + return 1; } + local rsink=$(rematchfn "(ts_receiver)" "$rmods") #" + local rsource=$(rematchfn "(ts_sender.monitor)" "$rmods") #" + [ -n "$rsink" -a -n "$rsource" ] || { + local rinfo=$(env LC_ALL=C $COMMAND_PACTL -s $uri info 2>/dev/null) + [ -n "$rsink" ] || \ + rsink=$(rematchfn "Default Sink:[[:blank:]]+(.+)" "$rinfo") #" + [ -n "$rsource" ] || \ + rsource=$(rematchfn "Default Source:[[:blank:]]+(.+)" "$rinfo") #" + } + echo "$rsink $rsource" + ;; + esac + ;; + esac + return $rc +} + +uservice_mount() { +#args: +# smb-share +# *-prn +# media-pa "" "" + local lp="$FUNCNAME ($$/$BASHPID):" rc=0 cmdstr errstr + local i ok="" step=0.25 timeo=28 #7sec + for (( i=0; i<=timeo; i++ )); do + port_is_listening $3 && { ok="1"; break; } + sleep $step"s" + done + [ -n "$ok" ] || \ + { nxlog "$lp '$svc'; port $3 is not listen after $((timeo/4))s"; + return 1; } + + cmdstr=$(uservice_configure "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8") || return 1 + case $1 in + smb-share) + #nxlog "$lp share cmdstr='$cmdstr'" #debug + errstr=$($cmdstr 2>&1) || \ + { nxlog "$lp $2 ($3) share mount failed: $errstr" + rmdir "$6" &>/dev/null; return 1; } + nxlog "$lp $2 ($3) share mounted" + ;; + smb-prn|ipp-prn) + #nxlog "$lp add printer cmdstr='$cmdstr'" #debug + errstr=$($cmdstr 2>&1) || \ + { nxlog "$lp $2 ($3) printer installing failed: $errstr"; return 1; } + # post-configure + local public=$(getparam "$6" "public" "" ';') + [ "$public" != "1" ] && { + errstr=$($COMMAND_SUDO $COMMAND_LPADMIN -p $svc -u allow:$USER,guest,root 2>&1) || \ + { nxlog "$lp $2 ($3) printer set permission failed: $errstr"; } + } + local defp=$(getparam "$6" "defaultprinter" "" ';') + [ "$defp" = "1" ] && { + errstr=$($COMMAND_SUDO $COMMAND_LPADMIN -d $svc 2>&1) || \ + { nxlog "$lp $2 ($3) printer set to default failed: $errstr"; } + } + nxlog "$lp $2 ($3) printer installed" + ;; + media-pa) + if ! $COMMAND_PA --check &>/dev/null; then + $COMMAND_PA --start --exit-idle-time=-1 &>/dev/null || { + #--log-target=file:$nx_dir/pa-$3.log --log-level=4 || { #debug + nxlog "$lp '$svc' can't start local pulseaudio server"; + return 1; } + # automatic null-sink will be disabled + # unload unnecessary local modules here too + local rmmods="module-always-sink module-rescue-streams module-systemd-login \ +module-device-restore module-stream-restore module-card-restore \ +module-default-device-restore module-switch-on-port-available \ +module-udev-detect module-suspend-on-idle module-console-kit" + local txt=$($COMMAND_PACTL list short 2>/dev/null) + local midpat="([0-9]+)[[:blank:]]+" mid rmod + for rmod in $rmmods; do + mid=$(rematchfn "$midpat$rmod" "$txt") && { + $COMMAND_PACTL unload-module $mid &>/dev/null + #nxlog "$lp ! $mid" #debug + } + done + else nxlog "$lp '$svc' local pulseaudio server already started" #debug + fi + case $2 in + pa) # tunneled pa + local rsink=$(cutfn "$cmdstr" 0) rsource=$(cutfn "$cmdstr" 1) + local mname="module-tunnel-sink" opts="server=127.0.0.1:$3" oo args ok2="" + oo=$(cutfn "$6" 1 '-'); [ -n "$oo" ] && opts+=" rate=$oo" + oo=$(cutfn "$6" 2 '-'); [ -n "$oo" ] && opts+=" channels=$oo" + [ "$oo" = "1" ] && opts+=" channel_map=mono" + if [ "$rsink" != "(null)" ]; then + args="sink_name=tcl_out sink=$rsink $opts" + errstr=$($COMMAND_PACTL load-module $mname $args 2>&1) + [ $? -eq 0 ] && ok="tcl_out" || \ + nxlog "$FUNCNAME ($$): $2 ($3) can't load $mname $args; '$errstr'" + [ -n "$ok" ] && $COMMAND_PACTL set-default-sink "tcl_out" &>/dev/null + else nxlog "$lp $2 ($3) can't load $name with rsink=$rsink" + fi + mname="module-tunnel-source" + if [ "$rsource" != "(null)" ]; then + args="source_name=tcl_in source=$rsource $opts" + errstr=$($COMMAND_PACTL load-module $mname $args 2>&1) + [ $? -eq 0 ] && ok2="tcl_in" || \ + nxlog "$FUNCNAME ($$): $2 ($3) can't load $mname $args; '$errstr'" + [ -n "$ok2" ] && $COMMAND_PACTL set-default-source "tcl_in" &>/dev/null + else nxlog "$lp $2 ($3) can't load $name with rsource=$rsource" + fi + if [ -n "$ok" -o -n "$ok2" ]; then + nxlog "$lp $2 ($3) tunnel modules loaded: $ok $ok2" + else rc=1 + fi + ;; + esac + ;; + esac + return $rc +} + +uservice_umount() { +#args: [data] [port] + local lp="$FUNCNAME ($$/$BASHPID):" errstr="" + local i ok="" step="0.5" ct=4 + case $1 in + smb-share) + local mdir=$3 res ffl="" + if stringinstring "//" "$2"; then res="$2" # svc + elif ! stringinstring "/" "$2"; then res="//127.0.0.1/$2" # sharename + else mdir="$2" res="$2" # dir + fi + #[ -z "$mdir" ] && { # get mount dir directly + # local txt=$(LC_ALL=C mount 2>/dev/null) + # pattern="$res""[[:blank:]]+on[[:blank:]]+([^[:blank:]]+)" + # mdir=$(remathfn "$pattern" "$txt") + # nxlog "$lp share $res: given empty mount dir, loaded mdir='$mdir' " + #} + for (( i=1; i<=ct; i++ )); do + (( i>=ct/2 )) && ffl="-f" + errstr+=$($COMMAND_SUDO $COMMAND_SMBUMOUNT $ffl "$res" 2>&1) && \ + { ok="1"; break; } + sleep $step"s" + done + [ -n "$ok" ] || \ + { nxlog "$lp $res share umount failed: $errstr"; return 1; } + [ -n "$mdir" ] && [ -d "$mdir" ] && rmdir "$mdir" &>/dev/null + nxlog "$lp $res share umounted" + ;; + smb-prn|ipp-prn) + for (( i=1; i<=ct; i++ )); do + errstr+=$($COMMAND_SUDO $COMMAND_LPADMIN -x "$2" 2>&1) && \ + { ok="1"; break; } + sleep $step"s" + done + [ -n "$ok" ] || \ + { nxlog "$lp $2 printer deleting failed: $errstr"; return 1; } + nxlog "$lp $2 printer deleted" + ;; + media-pa) + case $2 in + pa) # tunneled pa + local midpat="([0-9]+)[[:blank:]]+module-" uri="127.0.0.1" + [ -n "$4" ] && uri+=":$4" + txt=$(env LC_ALL=C $COMMAND_PACTL list short 2>/dev/null) + [ -n "$txt" ] || { + nxlog "$lp '$svc'; local PA already stopped"; return 0; } + local mid es mids=$(rematchfn "$midpat.+server=$uri" "$txt" all); + #nxlog "$lp '$2'; rmids: "$mids; #debug + for mid in $mids; do + es=$($COMMAND_PACTL unload-module $mid 2>&1) + [ $? -ne 0 ] && errstr+="\n$es" + done + [ -n "$errstr" ] && { + nxlog "$lp '$2'; unload some local PA modules failed: $errstr"; + } + nxlog "$lp $2 remote tunnel disconnected" + #nxlog "$lp $2 remote tunnel: $($COMMAND_PACTL list short 2>/dev/null)" #debug + ;; + esac + [ -n "$3" ] && { + $COMMAND_PA --kill || { + nxlog "$lp '$2'; unable to kill local PA"; return 0; } + } + ;; + esac + return 0 +} + +uservice_start() { +#args: +# [port] [type] [sharename] [username] [password] [data] [comp] +# [addr=127.0.0.1] +# if type is empty try to operate params from usess db +# if port not empty try to start on him +# Used config vars: COMMAND_HIDE COMMAND_UNHIDE + local lp="$FUNCNAME ($$/$BASHPID):" errstr="" qs svcport + local st startfl="" checkfl="" updvars="" updvals="" hpass + local svc="$1" port="$2" type="$3" share="$4" + local username="$5" pass="$6" data="$7" comp="$8" + local addr="$9"; [ -z "$addr" ] && addr="127.0.0.1"; + [ "$type" = "smb-share" -a -n "$data" ] && data=$(norm_dir "$data" $HOME) + + local i ok="" step="0.25" timeo="28" #4sec + [ -n "$type" -a -z "$port" ] && { + # starting no restarting - we wait for session listening port just in case + local lport_name=$(sess_lport_name $type) + local wstr="session_id='$session_id' AND $lport_name>0" + for (( i=0; i<=timeo; i++ )); do + port=$(q_vals_str_get "usess" "$wstr" "$lport_name") && break + sleep $step"s" + done + [ -n "$port" ] || { + nxlog "$lp $svc session $lport_name no declared after $((timeo/4)) s"; + return 1; } + } + + # waiting for suitable service status: on/off/"" + ok="" step="0.25" timeo="28" #7sec + for (( i=0; i<=timeo; i++ )); do + st=$(usvcs_get $svc "status") || { ok="1"; break; } + stringinstring "$st" "starting|stopping" || { ok="1"; break; } + sleep $step"s" + done + [ -n "$ok" ] || { + nxlog "$lp service $svc ($port) still set in \"$st\" state after $((timeo/4)) s"; + # FIXME! + [ "$st" = "stopping" ] || return 1; + nxlog "$lp service $svc ($port) set state 'off' ultimately"; + usvcs_set $svc "status" "off"; st="off" + } + + [ -z "$type" -a -z "$st" ] && { + nxlog "$lp '$svc': params for service are not found in usess db"; + return 1; } + [ -z "$type" ] && { #load params from usess db + qs="$(usvcs_get $svc "type,port,share,username,pass,data,comp,addr")" || { + nxlog "$lp '$svc': can't get service params from usess db"; return 1; } + type=$(cutfn "$qs" 0 '&'); + [ -z "$port" ] && port=$(cutfn "$qs" 1 '&'); + share=$(cutfn "$qs" 2 '&'); username=$(cutfn "$qs" 3 '&'); + pass=$(cutfn "$qs" 4 '&'); pass=$(echo "$pass" | $COMMAND_UNHIDE); + data=$(cutfn "$qs" 5 '&'); comp=$(cutfn "$qs" 6 '&'); + addr=$(cutfn "$qs" 7 '&'); + #nxlog "$lp service $svc ($st) load qs='$qs'" #debug + } + + if [ "$st" = "on" ]; then + if uservice_mounted $type $svc; then + nxlog "$lp service $svc is allready mounted, skipping"; return 0 + else + nxlog "$lp $svc service status is \"$st\", but it's not mounted. Try to start again"; + startfl=1; [ -n "$type" ] && checkfl=1; + st="starting"; usvcs_set $svc "status" $st + fi + else + if uservice_mounted $type $svc; then + usvcs_set $svc "status" "stopping" + nxlog "$lp $svc service status is \"$st\", but it's mounted. Try to stop"; + uservice_umount $type $svc $data || { return 1; } + fi + if [ "$st" = "off" ]; then + startfl=1; [ -n "$type" ] && checkfl=1; + st="starting"; usvcs_set $svc "status" $st + else # svc is not found in usess table + hpass=$(echo $pass | $COMMAND_HIDE) + usvcs_add "svc,type,status,port,share,comp,addr,username,pass,data" \ + "$svc&$type&starting&$port&$share&$comp&$addr&$username&$hpass&$data" + startfl=1; + fi + fi + + [ -n "$startfl" ] && { + [ -n "$checkfl" ] && { + local s_share s_username s_pass s_data s_comp s_addr + qs="$(usvcs_get $svc "share,username,pass,data,comp,addr")" || { + nxlog "$lp can't get service $svc params from usess _db"; return 1; } + s_share=$(cutfn "$qs" 0 '&'); s_username=$(cutfn "$qs" 1 '&'); + s_pass=$(cutfn "$qs" 2 '&'); s_pass=$(echo $s_pass | $COMMAND_UNHIDE); + s_data=$(cutfn "$qs" 3 '&'); s_comp=$(cutfn "$qs" 4 '&'); + s_addr=$(cutfn "$qs" 5 '&'); + [ "$share" != "$s_share" ] && { + nxlog "$lp $svc share strings are different '$s_share' > '$share'" + updvars+=",share"; updvals+="&$share"; } + [ "$username" != "$s_username" ] && { + nxlog "$lp $svc username strings are different '$s_username' > '$username'" + updvars+=",username"; updvals+="&$username"; } + [ "$pass" != "$s_pass" ] && { + nxlog "$lp $svc password strings are different" + hpass=$(echo $pass | $COMMAND_HIDE) + updvars+=",pass"; updvals+="&$hpass"; } + [ "$data" != "$s_data" ] && { + nxlog "$lp $svc share strings are different '$s_data' > '$data'" + updvars+=",data"; updvals+="&$data"; } + [ "$comp" != "$s_comp" ] && { + nxlog "$lp $svc comp strings are different '$s_comp' > '$comp'" + updvars+=",comp"; updvals+="&$comp"; } + [ "$addr" != "$s_addr" ] && { + nxlog "$lp $svc addr strings are different '$s_addr' > '$addr'" + updvars+=",addr"; updvals+="&$addr"; } + + } + + #nxlog "$lp _$st _$type _$svc _$port _$username _$pass _$data _$comp" _$share" #debug + if uservice_mount $type $svc $port "$(echo -e "${username//\%/\\x}")" \ + "$pass" "$data" "$(echo -e "${comp//\%/\\x}")" "$share"; + then + usvcs_set $svc "status,port""$updvars" "on&"$port$updvals + return 0 + else usvcs_set $svc "status,port" "off&0" + fi + } + return 1 +} + +uservice_stop() { +#arg: svc [type] [norestart] +# Used gvars: session_id + local lp="$FUNCNAME ($$/$BASHPID):" + local i ok="" st type=$2 lport_name lport="" data="" hardstop=$3 + # waiting for suitable service status: on + local step=0.25 timeo=28 #7sec + for (( i=0; i<=timeo; i++ )); do + st=$(usvcs_get $svc "status") + [ "$st" = "on" ] && { ok="1"; break; } + sleep $step"s" + done + [ -n "$ok" ] || { + nxlog "$lp service $svc still set in \"$st\" state after $((timeo/4))s waitng"; + return 1; } + [ -z "$type" ] && type=$(usvcs_get $svc "type") + usvcs_set $svc "status" "stopping" + [ -n "$hardstop" ] || { # get suitable session first + lport_name=$(sess_lport_name $type) + local wstr="status='Running' AND session_id!='$session_id' AND $lport_name>0" + #nxlog "$lp $svc wstr='$wstr'" #debug + lport=$(q_vals_str_get "usess" "$wstr" "$lport_name") || { + hardstop=1 + nxlog "$lp '$svc': other suitable listening port is not found" #; wstr='$wstr'" #debug + } + } + [ -n "$hardstop" ] && { # if unable to restart we must known data + data=$(usvcs_get $svc "data"); } + #nxlog "$lp '$svc': hs=$hardstop; data=$data" #debug + uservice_umount $type $svc "$data" "$port" || return 1 + [ -n "$hardstop" ] && { + if [ "$SESSION_LOG_CLEAN" = "1" ]; then + q_dbe "DELETE FROM usvcs WHERE svc='$1';" + else usvcs_set $1 "status,port" "off&0" + fi + return 0; + } + usvcs_set $svc "status,port" "off&0" + uservice_start $svc $lport #|| return 1 + return 0 +} + +node_stop_services() { +# Used gvars: session_id + #local lp="$FUNCNAME ($$/$BASHPID):" + local lports=",$(usess_get $session_id "smbport,cupsport,mmport" ',')" + lports=${lports//,0/}; lports=${lports:1} + [ -n "$lports" ] || return # no services in session + local svc svcs + svcs=$(q_vals_strs_get "usvcs" "status='on' AND port IN ($lports)" "svc") #" + #nxlog "$lp lports=($lports) services list to stop: '$svcs'"; #debug + for svc in $svcs; do uservice_stop $svc; done +} + +node_terminate_session() { +#args: [status] +# Used gvars: nx_dir +# Used config vars: COMMAND_XAUTH, SESSION_LOG_CLEAN SERVER_NAME + local lp="$FUNCNAME ($$/$BASHPID):"; + #nxlog "$lp Start terminating session_id='$1' with status '$2'" #debug + local qs=$(usess_get "$1" "display,agent_pid,tail_pid,status") + [ -z "$qs" ] && { + nxlog "$lp session_id='$1' not found in usess db. Bye."; return; + } + local status=$(cutfn "$qs" 3 '&') + stringinstring "$status" "Terminating|Finished|Failed" && { + nxlog "$lp Session status is already '$status'. Bye."; return; + } + local display=$(cutfn "$qs" 0 '&'); local sess_id="$SERVER_NAME-$display-$1" + [ -d "$nx_dir/C-$sess_id" ] || { + nxlog "$lp Session dir '$nx_dir/C-$sess_id' not found. Bye."; return; + } + usess_set "$1" "status" "Terminating" + + local agent_pid=$(cutfn "$qs" 1 '&') tail_pid=$(cutfn "$qs" 2 '&') + local t_status="$2"; [ -z "$2" ] && t_status="Finished" + node_stop_services + kill -0 $agent_pid 2>/dev/null && { + #nxlog "$lp start killing of nxagent ($agent_pid)" #debug + kill $agent_pid 2>/dev/null + wait $agent_pid 2>/dev/null + kill -0 $agent_pid 2>/dev/null || + nxlog "$lp nxagent ($agent_pid) is dead now" + } + ((tail_pid>0)) && kill -0 $tail_pid 2>/dev/null && { # Kill tail process + #nxlog "$lp kill tail process ($tail_pid)" #debug + kill $tail_pid 2>/dev/null + wait $tail_pid 2>/dev/null + kill -0 $tail_pid 2>/dev/null || { + nxlog "$lp tail ($tail_pid) is dead now"; tail_pid="0" + usess_set "$session_id" "tail_pid" "0" + } + } + + #nxlog "$lp Remove session information" #debug + rm -f /tmp/.X$display-lock; rm -f /tmp/.X11-unix/X$display + # Remove magic cookie information + $COMMAND_XAUTH remove "localhost:$display" >/dev/null 2>&1 + $COMMAND_XAUTH remove ":$display" >/dev/null 2>&1 + if [ "$SESSION_LOG_CLEAN" = "1" ]; then + #nxlog "$lp Clean session information." #debug + rm -rf "$nx_dir/C-$sess_id/" + rm -f "$nx_dir/nxnode-$1.log" + rm -f "$nx_dir/nxnode.log" + elif [ "$2" = "Failed" ]; then mv "$nx_dir/C-$sess_id/" "$nx_dir/F-C-$sess_id" + else mv "$nx_dir/C-$sess_id/" "$nx_dir/T-C-$sess_id" + fi + usess_close "$1" "$t_status" + #nxlog "$lp end" #debug +} + +node_fail_restore_session() { +#arg: + #local lp="$FUNCNAME ($$/$BASHPID):"; nxlog "$lp starting" #debug + echo "NX> 1004 Error: Could not resume session. nxagent process could not be found." + node_terminate_session "$1" "Failed" + #nxlog "$lp end. Next is 'exit 1'" #debug + exit_proc 1 +} + +node_suspend_session() { +#arg: + local lp="$FUNCNAME ($$/$BASHPID):"; + #nxlog "$lp starting" #debug + local agent_pid=$(usess_get "$1" "agent_pid") + nxlog "$lp Killing (HUP) agent_pid ($agent_pid)..." + kill -0 $agent_pid 2>/dev/null || { + nxlog "$lp nxagent is already dead. end (1)"; return 1; + } + kill -HUP $agent_pid 2>/dev/null && { + nxlog "$lp end (HUP)"; return 0; + } + return 1 +} + +node_find_application() { +#args: +# Used config vars: $COMMAND_START_KDE, $COMMAND_START_GNOME, +# $COMMAND_START_CDE, $COMMAND_XTERM, $USER_X_STARTUP_SCRIPT,$DEFAULT_X_SESSION + local lp="$FUNCNAME ($$/$BASHPID):"; + #nxlog "$lp starting with args \"$@\"" #debug + local node_startx="" + case $1 in + shadow|windows|vnc) return + ;; + unix-kde) node_startx=$COMMAND_START_KDE + ;; + unix-gnome) node_startx=$COMMAND_START_GNOME + ;; + unix-cde) node_startx=$COMMAND_START_CDE + ;; + windows-helper) + node_startx="$COMMAND_RDESKTOP /v:$agent_server /u:$agent_user" + [ -n "$agent_domain" ] && node_startx+=" /d:$agent_domain" + node_startx+=" /t:NX-$session-RDP-$agent_server@$agent_user" + node_startx+=" /p:$agent_password /size:$geometry $EXTRA_OPTIONS_RDP" + ;; + vnc-helper) + if [ ! -x "$COMMAND_VNCVIEWER" ]; then + echo "$COMMAND_XMSG 'vncviwer not found'" + else + mkdir -p "$NXSESSION_DIRECTORY/scripts/" + echo "$agent_password" | \ + $COMMAND_VNCPASSWD $NXSESSION_DIRECTORY/scripts/.passwd doit + node_startx="$COMMAND_VNCVIEWER -passwd \ + $NXSESSION_DIRECTORY/scripts/.passwd $EXTRA_OPTIONS_RFB $agent_server" + fi + ;; + unix-application) + [ "$application" = "xterm" ] && application=$COMMAND_XTERM + node_startx=$application + ;; + unix-console) node_startx=$COMMAND_XTERM + ;; + unix-default|*) + if [ -x "$HOME/$USER_X_STARTUP_SCRIPT" ]; then + node_startx="$HOME/$USER_X_STARTUP_SCRIPT" + elif [ -x "$DEFAULT_X_SESSION" ]; then + node_startx="$DEFAULT_X_SESSION" + else node_startx=$COMMAND_XTERM + fi + ;; + esac + + # dimbor: another personalyzed way to ACLS control and replace X-application + [ -n "$NX_ACL_DIR" ] || { echo "$node_startx"; return; } + + local ucond=$(groups); ucond="'#$USER','*${ucond// /\',\'\*}','@all'" + local mode=".mode csv settings\n.separator '&'\n" + local qstr="SELECT key,value,val_depend FROM settings WHERE user IN ($ucond) \ + AND key NOT IN ('@shadow@') ORDER BY user ASC, val_check ASC;" + #nxlog "$lp qstr='$qstr'" #debug + local ts=$(qa_dbe "$mode" "$qstr") + #nxlog "$lp ts='$ts'" #debug + local l tpl inv pm l2="" app_match="" app_rep="$COMMAND_XMSG '$NX_ACL_WARN'" + while read l; do + tpl="${l%%&*}"; tpl="$(sq2s "$tpl")" + inv=0; [ "${tpl:0:1}" = "!" ] && { tpl="${tpl:1}"; inv=1; } + pm=0; [[ "$node_startx" =~ $tpl ]] && pm=1 + #nxlog "$lp $node_startx -> \"$l\" -> $tpl $inv $pm" #debug + ((inv+pm==1)) && { l2=$l; app_match=1; break; } + done <<< "$ts" + if [ -n "$app_match" ]; then + tpl=$(cutfn "$l2" 1 '&'); tpl=$(sq2s "$tpl") + [ -n "$tpl" ] && { # process list checking + app_match="" + inv=0; [ "${tpl:0:1}" = "!" ] && { tpl="${tpl:1}"; inv=1; } + local psall=""; [ "${tpl:0:2}" = "@@" ] && { tpl="${tpl:2}"; psall=1; } + local psl; + if [ -n "$psall" ]; then psl="$(ps ax -o cmd=)" + else psl="$(ps -o cmd= -U $USER)" + fi + pm=0; rematchfn "($tpl)" "$psl" &>/dev/null && pm=1 + ((inv+pm==1)) && app_match=1 + #nxlog "$lp $l - $tpl $inv $pm" #debug + } + local msg=$(cutfn "$l2" 2 '&'); msg=$(sq2s "$msg") + [ -n "$msg" ] && { # exe/msg checking + # need absolute path here? + [ -x "${msg%% *}" ] && app_rep="$msg" || app_rep="$COMMAND_XMSG '$msg'" + } + fi + if [ -n "$app_match" ]; then + echo "$node_startx"; + else + nxlog "$lp App '$node_startx' replaced to '$app_rep'" + echo "$app_rep" + fi +} + +node_start_applications() { +# Used glob vars: $type, $application, $sess_id, $mediahelper, +# $virtualdesktop, $rootless, $display +# Used config vars: + local lp="$FUNCNAME ($$/$BASHPID):"; + #nxlog "$lp starting" #debug + local app node_app napp; + local slave_apps psess sess_ps sapp; + local node_app_pid node_wm_pid; + local ok step timeo + local q=0 i s l + + # Prepare application startup + export DISPLAY=:$display + + #nxlog "$lp display='$display', waiting for it's ready" #debug + ok="" step="0.01" timeo=$((AGENT_STARTUP_TIMEOUT*100)) + for (( i=0; i<=timeo; i++ )); do + [ -f /tmp/.X$display-lock ] && { ok="1"; break; } + sleep $step"s" + done + [ -n "$ok" ] || { + nxlog "$lp /tmp/.X$display-lock not found after $AGENT_STARTUP_TIMEOUT s"; + return 1; } + + #numlockx + if [ "$NUMLOCK_METHOD" != "system" ]; then + #nxlog "$lp Run \"$NUMLOCKX $NUMLOCKX_STATUS\"" #debug + "$NUMLOCKX" "$NUMLOCKX_STATUS" + fi + + # Which application do we start? + app=$(node_find_application "$type") + # For rdesktop/VNC, there is no application to start + [ -n "$app" ] || return + + if [ "$ENABLE_SAMBA_PRELOAD" = "1" ]; then + NXSAMBA_PORT=$(usess_get "$session_id" "smbport") + ((NXSAMBA_PORT>0)) && { + export NXSAMBA_PORT + #nxlog "$lp Preload SAMBA using nxredir. NXSAMBA_PORT is '$NXSAMBA_PORT'" #debug + node_app="$PATH_BIN/nxredir $node_app" + echo "Info: NXNODE - Using nxredir wrapper script to forward \ +SMB ports 139 and 445 to port $NXSAMBA_PORT." >> "$NXSESSION_DIRECTORY/session" + } + fi + #nxlog "$lp app is $app" #debug + + # do fake eval for params + q=0; l=$app; node_app=() + while [ -n "$l" ]; do + s=${l%%[\'\"]*}; l=${l#*[\'\"]} + [ "$s" = "$l" ] && l="" + [ -n "$s" ] || continue + ((q==0)) && { node_app+=($s); q=1; } || { node_app+=("$s"); q=0; } + done + #nxlog "$lp ${#node_app[@]}" #debug + #for ((i=0; i<${#node_app[@]}; i++)); do nxlog "$lp ${node_app[$i]}"; done #debug + + [ "$cups" = "1" -o "$samba" = "1" ] && { + #nxlog "$lp export CUPS_SERVER=$CUPS_DEFAULT_SOCK" #debug + export CUPS_SERVER=$CUPS_DEFAULT_SOCK + } + + # Use Xsession to execute the Desktop session + case $type in + unix-gnome) + export STARTUP="${node_app[@]}" + [ "$BOOTSTRAP_X_SESSION" = "1" ] && node_app=($COMMAND_GDM_X_SESSION) + ;; + unix-kde|unix-cde) + export STARTUP="${node_app[@]}" + [ "$BOOTSTRAP_X_SESSION" = "1" ] && node_app=($DEFAULT_X_SESSION) + ;; + esac + + [ $ENABLE_ROOTLESS_TERMINATE_SESSION = "1" -a "$rootless" = "1" ] && { + psess=$($COMMAND_PS -wo sess= -p $$) + napp=${node_app[0]}; napp=${napp##*/} + slave_apps=$(rematchfn "$napp:(.+)" "${APP_WAIT_MAP//;/$'\n'}") #" + #nxlog "$lp slave(s) will be waiting too. Initial apps: '$slave_apps'" #debug + } + + # Do we need to PRELOAD any libraries? + [ "$virtualdesktop" = "0" -a "$rootless" != "1" ] && export LD_PRELOAD="$APPLICATION_LIBRARY_PRELOAD:$LD_PRELOAD" + + # close input and output file descriptors + exec 0<&-; exec 1>&-; exec 2>&- + + # Should we start a window manager? + if [ "$virtualdesktop" = "1" -a "$type" = "unix-application" -a \ + -x "$DEFAULT_X_WM" ]; then + #nxlog "$lp start a window manager - \"DISPLAY=:$display $DEFAULT_X_WM\"" #debug + DISPLAY=:$display $DEFAULT_X_WM >>"$NXSESSION_DIRECTORY/session" 2>&1 & + node_wm_pid=$! + #nxlog "$lp node_wm_pid='$node_wm_pid'" #debug + fi + + # Startup the application + #nxlog "$lp Starting node_app with /etc/nxserver/Xsession" #debug + DISPLAY=:$display /etc/nxserver/Xsession "${node_app[@]}" >> \ + "$NXSESSION_DIRECTORY/session" 2>&1 & + node_app_pid=$! + nxlog "$lp Start '${node_app[@]}'. Waiting for node_app_pid='$node_app_pid'" + wait $node_app_pid + nxlog "$lp node_app_pid finished" + + # Kill or wait for the started window manager + [ -n "$node_wm_pid" ] && { + nxlog "$lp node_wm_pid is not empty" + # kill the WM after application is finished? + [ "$KILL_DEFAULT_X_WM" = "1" ] && { nxlog "$lp killing $node_wm_pid" + kill $node_wm_pid 2>/dev/null; } + # or just wait until it finishes? + [ "$KILL_DEFAULT_X_WM" = "1" ] || { nxlog "$lp wait for $node_wm_pid is dead" + wait $node_wm_pid; } + } + sleep "$NODE_APP_WAIT_TIMEOUT"s + + [ $ENABLE_ROOTLESS_TERMINATE_SESSION = "1" -a "$rootless" = "1" ] && { + if [ -n "$slave_apps" ] ; then + nxlog "$lp slave(s) will be waiting too. Initial: '$slave_apps'" + sapp=$napp + while [ -n "$sapp" ]; do + sess_ps=$($COMMAND_PS -wo user=,cmd= -s $psess); sapp="" + #nxlog "$lp '$sess_ps'" #debug + while read l; do + [ "$(cutfn "$l" 0)" = "$USER" ] || continue + s=$(cutfn "$l" 1); s=${s##*/} + stringinstring "$s," "$slave_apps," && { + sapp=$s; + #nxlog "$lp >> $sapp '$l'" #debug + break; + } + done <<< "$sess_ps" + sleep "$NODE_APP_WAIT_TIMEOUT"s + done + nxlog "$lp Session app(s) are finished" + fi + node_terminate_session "$session_id" + } + + # Do not terminate agent in case of rootless agent mode. + # The agent times out after a while by itself anyway. + if [ "$virtualdesktop" = "1" -o "$rootless" != "1" ] ; then + #nxlog "$lp Call node_terminate_session for non-rootless or virtualdesktop session type" #debug + node_terminate_session "$session_id" + fi + #nxlog "$lp end" #debug +} + +node_agent_persistent_session() { +# Is the user allowed to run a persistent session? + local username IFS="," p="-nopersistent" + [ "$ENABLE_PERSISTENT_SESSION" = "all" ] && p="-persistent" || { + for username in $ENABLE_PERSISTENT_SESSION; do + [ "${username:0:1}" != "@" ] && [ "$USER" = "$username" ] && \ + p="-persistent" && break; + [ "${username:0:1}" = "@" ] && \ + [ -z $(groups "$USER" | egrep "^${username:1}:") ] && \ + p="-persistent" && break; + done + } + for username in $DISABLE_PERSISTENT_SESSION; do + [ "${username:0:1}" != "@" ] && [ "$USER" = "$username" ] && \ + p="-nopersistent" && break; + [ "${username:0:1}" = "@" ] && \ + [ -z $(groups "$USER" | egrep "^${username:1}:") ] && \ + p="-nopersistent" && break; + done + echo "$p" +} + +node_start_agent() { +# Ok, now we do some wicked fd magic. +# first part: nxagent's fd #2 -> fd #3 +# second part: fd #1 -> #4; fd #3 -> #1; tee | node_start_monitor +# third part: fd #4 -> #1 +# => all output of nxagent goes to tee | node_start_monitor, while +# leaving all other output flow through like normally. + + # preparations + local lp="$FUNCNAME ($$/$BASHPID):"; + local k g b r fp vncfullscreen u p d agent_port viewonly + local agent_exit_status node_failed + #nxlog "$lp starting" #debug + exec 3>&2; exec 4>&1; + + { + + { + + export DISPLAY="nx/nx,options=$NXSESSION_DIRECTORY/options:$display" + export XAUTHORITY="$NXSESSION_DIRECTORY/authority" + export HOME + export NX_CLIENT="$PATH_BIN/nxdialog" + + # Setup optional parameters for nxagent + # keyboard + k="" + # backwards compatibility + [ -n "$keyboard" ] && k="-keyboard $keyboard" + [ -n "$kbtype" ] && k="-kbtype $kbtype" + # backingstore + b="" + if [ -n "$backingstore" ]; then + [ "$backingstore" != 1 ] && b="-bs $backingstore" + [ "$backingstore" = 1 ] && b="+bs" + fi + + # geometry + g="" + [ -n "$geometry" ] && g="-geometry $geometry" + + # type of session + r="-D"; [ "$rootless" = "1" ] && r="-R" + + # Setup fullscreen parameters + [ "$geometry" = "fullscreen" ] && \ + [ "$type" = "vnc-helper" -o "$type" = "windows-helper" ] && \ + g="-geometry $(rematchfn '^([[:digit:]]+x[[:digit:]]+)' $screeninfo)" + + if [ "$r" = "-R" -a "$rootless" != "1" ]; then + #nxlog "$lp Start nxproxy for single application session mode" #debug + [ "$SET_LD_LIBRARY_PATH" = "1" ] && \ + export LD_LIBRARY_PATH="$PROXY_LIBRARY_PATH:$LD_LIBRARY_PATH" + nxlog "$lp Start nxproxy by command: '$PATH_BIN/nxproxy -C :$display $PROXY_EXTRA_OPTIONS'" + $PATH_BIN/nxproxy -C :$display $PROXY_EXTRA_OPTIONS 2>&3 & + else + #nxlog "$lp nxagent session type (X11)" #debug + [ "$SET_LD_LIBRARY_PATH" = "1" ] && \ + export LD_LIBRARY_PATH="$AGENT_LIBRARY_PATH:$LD_LIBRARY_PATH" + # Setup optional parameters + p=$(node_agent_persistent_session) + fp=""; [ -n "$AGENT_FONT_SERVER" ] && fp="-fp $AGENT_FONT_SERVER" + if [ "$type" = "shadow" ]; then + nxlog "$lp Type \"shadow\". Add some args to nxagent" + local shmode=$ENABLE_INTERACTIVE_SESSION_SHADOWING + [ "$shmode" = "1" ] && [ "$shadowviewonly" = "1" ] && shmode="0" + r="-S -shadow $shadowhost:$shadowdisplay -shadowmode $shmode" + p="-nopersistent" + fi + # Start the agent + #nxlog "$lp env start `env`"; nxlog "$lp env end" + nxlog "$lp Start nxagent by command: '$COMMAND_NXAGENT $p $r -name \"NX - $user@$SERVER_NAME:$display - $session (GPL Edition)\" -option \"$NXSESSION_DIRECTORY/options\" $b $fp $AGENT_EXTRA_OPTIONS_X :$display'" + #PATH="$PATH_BIN:$PATH" $COMMAND_NXAGENT $p $r -name "NX - $user@$SERVER_NAME:$display - $session (GPL Edition)" -option "$NXSESSION_DIRECTORY/options" $k $g $b $fp $AGENT_EXTRA_OPTIONS_X :$display 2>&3 & + PATH="$PATH_BIN:$PATH" $COMMAND_NXAGENT $p $r \ + -name "NX - $user@$SERVER_NAME:$display - $session (GPL Edition)" \ + -option "$NXSESSION_DIRECTORY/options" $b $fp \ + $AGENT_EXTRA_OPTIONS_X :$display 2>&3 & + fi + + # Wait for the agent + agent_pid=$! + usess_set "$session_id" "agent_pid" "$agent_pid" + echo "NX> 733 Agent pid: $agent_pid:" + nxlog "$lp Waiting for agent_pid='$agent_pid'" + wait $agent_pid; agent_exit_status=$? + nxlog "$lp agent_exit_status='$agent_exit_status'" + node_failed="" + if [ $agent_exit_status -ne 0 ]; then + echo "NX> 1004 Error: NX Agent exited with exit status $agent_exit_status. To troubleshoot set SESSION_LOG_CLEAN=0 in node.conf and investigate \"$nx_dir/F-C-$sess_id/session\". You might also want to try: ssh -X myserver; $PATH_BIN/nxnode --agent to test the basic functionality. Session log follows:" + echo "$(< $NXSESSION_DIRECTORY/session)" >&2 + node_failed="Failed" + nxlog "$lp node_failed='$node_failed'" + fi + #nxlog "$lp close session" #debug + echo "NX> 1006 Session status: closed" + # Cleanup session information + #nxlog "$lp cleanup session information '$sess_id'" #debug + #nxlog "$lp call 'node_terminate_session \"$session_id\" \"$node_failed\"'" #debug + node_terminate_session "$session_id" "$node_failed" + + # remove possible leftovers of nxagent + #nxlog "$FUNCNAME ($$):remove /tmp/.X$display-lock" #debug + rm -f /tmp/.X$display-lock + #nxlog "$lp remove /tmp/.X11-unix/X$display" #debug + rm -f /tmp/.X11-unix/X$display + + } 3>&1 1>&4 | tee "$NXSESSION_DIRECTORY/session" | \ + node_start_monitor; } 4>&1 +} + + +node_emergency_exit() { + local lp="$FUNCNAME ($$/$BASHPID):"; + #nxlog "$lp starting" #debug + #nxlog "$lp call 'node_terminate_session \"$session_id\" \"Failed\"'" #debug + node_terminate_session "$session_id" "Failed" + echo "NX> 1004 Error: Emergency exit due to kill signal." + #nxlog "$lp end" #debug +} + +node_start_monitor() { +#arg: +# Monitoring the nxagent: Its also kind of a "state-machine" +# as it has to keep track of different +# connection states and react differently. + local lp="$FUNCNAME ($$/$BASHPID):"; + #nxlog "$lp starting with arg: $@" #debug + local tail_pid="" watchdog_pid tosend pars_sent="" + local smbport="0" mmport="0" cupsport="0" + + while read line; do + case "$line" in + *"Info: Waiting for connection from"*) + [ -n "$pars_sent" ] && continue; # send params only once + tosend="NX> 700 Session id: $sess_id +NX> 705 Session display: $display\nNX> 703 Session type: $type +NX> 701 Proxy cookie: $cookie\nNX> 702 Proxy IP: $proxyip +NX> 706 Agent cookie: $cookie\nNX> 704 Session cache: $type +NX> 707 SSL tunneling: $encryption\n" + # File-sharing port options + [ "$samba" = "1" ] && + tosend+="NX> 709 File-sharing port: 445\n" + echo -e "$tosend""NX> 710 Session status: running +NX> 1002 Commit\nNX> 1006 Session status: running" + pars_sent="1"; continue; + ;; + *"Info: Listening"*"SMB connections on port"*) + # Catch NXAGENT SMB Port (sometimes the port differs from what we got from nxserver) + smbport=$(cutfn "$line" 1 "'"); smbport=${smbport##*:} + usess_set "$session_id" "smbport" "$smbport" + continue; + ;; + *"Info: Listening"*"multimedia connections on port"*) + # Catch NXAGENT Multimedia Port + mmport=$(cutfn "$line" 1 "'"); mmport=${mmport##*:} + usess_set "$session_id" "mmport" "$mmport" + continue; + ;; + *"Info: Listening"*"CUPS connections on port"*) + # Catch NXAGENT CUPS Port + cupsport=$(cutfn "$line" 1 "'"); cupsport=${cupsport##*:} + usess_set "$session_id" "cupsport" "$cupsport" + continue; + ;; + *"Info: Watchdog running with pid"*) + # Watchdog termination + watchdog_pid=$(cutfn "$line" 1 "'") + continue; + ;; + *"Info: Waiting the watchdog process to complete"*) + # Kill the watchdog + kill $watchdog_pid 2>/dev/null + continue; + ;; + esac + + if [ "$1" != "restore" ]; then # "start" instance + case "$line" in + *"Session: Starting session at"*) + echo "NX> 1009 Session status: starting" + usess_set "$session_id" "status" "Starting" + ;; + *"Session: Session started at"*) + usess_set "$session_id" "status" "Running" + ;; + *"Session: Suspending session at"*) + echo "NX> 1009 Session status: suspending" + usess_set "$session_id" "status" "Suspending" + ;; + *"Session: Terminating session at"*) + echo "NX> 1009 Session status: terminating" + ;; + *"Session: Session suspended at"*) + # Session suspend + echo "NX> 1005 Session status: suspended" + #nxlog "$lp $line" #debug + ((mmport+smbport+cupsport>0)) && { + #nxlog "$lp call node_stop_services" #debug + node_stop_services + } + usess_set "$session_id" "status,userip,acc_ip" "Suspended&&" + ;; + esac + else # "restore" instance + #nxlog "$lp nxagent output: $line" + case "$line" in + *"Info: tail -f running with pid"*) + # Catch tail pid + tail_pid=$(cutfn "$line" 1 "'") + usess_set "$session_id" "tail_pid" "$tail_pid" + #echo "$node_tail_pid" >"$nx_dir/C-$sess_id/pids/tail" + ;; + *"Session: Resuming session at"*) + echo "NX> 1009 Session status: resuming" + usess_set "$session_id" "status" "Resuming" + ;; + *"Session: Session resumed at"*) + # Reconnection success! + echo "NX> 718 Session restore succeded" + usess_set "$session_id" "status,userip,acc_ip"\ + "Running&$userip&$accept" + kill $tail_pid 2>/dev/null; break + ;; + *"Session: Display failure detected at"*) + # Reconnection failure + echo "NX> 596 Error: Session $1 failed. Reason was: $line" + kill $tail_pid 2>/dev/null; break + ;; + esac + fi + done + + trap "" EXIT + + [ "$1" != "restore" -a "$rootless" != "1" ] && { + nxlog "$lp call node_stop_services at ending" + node_stop_services; + } + # close all open file descriptors + exec 0<&-; exec 1>&-; exec 2>&-; + #nxlog "$lp end" #debug + exit_proc 0 +} + +startsession() { # Start a new session. +# 1.5.0 options: rdpcolors,rdpcache,http +# nxclient > 1.5.0-106 variables: resize,keybd +# FreeNX specific variables: clientproto,status,host +# NX 3.0 shadow mode related variables: shadowusername,shadowcookie, +# shadowdisplay,shadowhost +# dimbor: additional extra-channels extra[1-3], patched nxcomp both +# on server and client are required + + local lp="$FUNCNAME ($$/$BASHPID):"; + local opt_vars opt_str pack cleanup product clipboard menu; + local id fullscreen accept vn; + local i ok step timeo + #nxlog "$lp starting with args \"$@\"" #debug + + [ "$1" = "start" ] && mkdir -p -m700 "$NXSESSION_DIRECTORY" + # Setup environment + [ -n "$SOURCE_SYS_PROFILE" ] && . $SOURCE_SYS_PROFILE + [ -n "$SOURCE_USER_PROFILE" ] && { + if [ "${SOURCE_USER_PROFILE:0:1}" != "/" ]; then + . $HOME/$SOURCE_USER_PROFILE + else . $SOURCE_USER_PROFILE + fi + } + + [ "$PROXY_TCP_NODELAY" = "0" ] && nodelay=0 + [ "$ENABLE_ROOTLESS_MODE" = "0" ] && rootless=0 + [ -z "$samba" ] && samba=0; [ -z "$media" ] && media=0 + [ -z "$shmem" ] && shmem=0; [ -z "$shpix" ] && shpix=0 + [ "$geometry" = "fullscreen" ] && fullscreen="1" || fullscreen="0" + [ -z "$nodelay" ] && nodelay=1 # ??? + cleanup=10; product=LFE/None/LFEN/None; id=$sess_id; + clipboard="$ENABLE_CLIPBOARD"; menu="$ENABLE_PULLDOWN_MENU" + windows_app=$application + [ -z "$keybd" ] && keybd=$aux # backwards compatibility for keybd parameter + + [ "$EXPORT_USERIP" = "1" ] && export NXUSERIP="$userip" + [ "$EXPORT_SESSIONID" = "1" ] && export NXSESSIONID="$sess_id" + export SHADOW_XAUTHORITY="$NXSESSION_DIRECTORY/authority" + if [ "$type" = "vnc-helper" -o "$type" = "windows-helper" ]; then + # We do not want to suspend such a session + # as RDP/RFB are both suspendable as well + ENABLE_PERSISTENT_SESSION="" + fi + + if [ "$encryption" = "1" ]; then + # we need to use the IP of the "calling" server now + accept=$(rematchfn "($ip4_pattern)" "$SSH_CLIENT $SSH2_CLIENT") #" + # If host is the same, use 127.0.0.1, else fallback to default + [ -z "$accept" -a "$host" = "127.0.0.1" ] && accept="127.0.0.1" + else encryption=0; accept=$userip + fi + + # We need our own external IP + proxyip="$EXTERNAL_PROXY_IP"; [ -z "$proxyip" ] && proxyip="127.0.0.1" + + pack="" + if [ -z "$imagecompressionlevel" ]; then imagecompressionlevel="9" + elif [ "$imagecompressionmethod" = "0" ]; then pack="nopack" + elif [ "$imagecompressionmethod" = "1" ]; then pack="16m-jpeg-$imagecompressionlevel" + elif [ "$imagecompressionmethod" = "2" ]; then pack="16m-png-9" + fi + + if [ "$1" = "start" ]; then + cookie=$(echo $[$RANDOM*$RANDOM] | $COMMAND_MD5SUM); cookie=${cookie%% *} + # add row to usses with defaults: session_id, status, display, type, + # client, agent_pid, cookie, tail_pid, userip, acc_ip, mmport, cupsport,\ + # smbport + usess_add "$sqcols_usess" "$session_id&Starting&$display&$type&$client&\ +0&$cookie&0&$userip&$accept&0&0&0&" + elif [ "$1" = "restore" ]; then + cookie=$(usess_get "$session_id" "cookie") + fi + + if [ "$1" = "application" ]; then + # This needs to be set, else nxagent is terminated + rootless="1"; virtualdesktop="0" + #nxlog "$lp call 'node_start_applications'" #debug + node_start_applications & + echo "NX> 596 Application $application started successfully." + return + fi + + #nxlog "$lp generate \"$NXSESSION_DIRECTORY/options\"" #debug + opt_vars="keyboard kbtype kbload keymap geometry\ + client resize cache images pack link nodelay type clipboard composite\ + cleanup product shmem backingstore shpix accept cookie id samba media\ + sync cups keybd aux http extra1 extra2 extra3 rdpcolors rdpcache\ + fullscreen menu" + opt_str="nx/nx"; + for vn in $opt_vars; do [ -n "${!vn}" ] && opt_str+=",$vn=${!vn}"; done + #[ "$type" = "shadow" ] && opt_str+=",shadow=1" + opt_str+=":$display" + # write options file + umask 0077; echo "$opt_str" > "$NXSESSION_DIRECTORY/options"; umask $umask0 + + if [ "$1" = "start" ]; then # write xauth script file + #nxlog "$lp write xauth script file" #debug + txt="add localhost:$display MIT-MAGIC-COOKIE-1 $cookie +add :$display MIT-MAGIC-COOKIE-1 $cookie +exit" + echo "$txt" | $COMMAND_XAUTH >/dev/null 2>&1 + echo "$txt" | $COMMAND_XAUTH -f "$NXSESSION_DIRECTORY/authority" >/dev/null 2>&1 + fi + + if [ -n "$shadowcookie" ]; then + #nxlog "$lp If we have a shadow cookie, we add it to xauth session authority file as well" #debug + $COMMAND_XAUTH -f "$SHADOW_XAUTHORITY" add "$shadowhost:$shadowdisplay" MIT-MAGIC-COOKIE-1 "$shadowcookie" + elif [ -n "$shadowdisplay" ]; then + # we need to merge in the normal .Xauthority file + #nxlog "$lp we need to merge in the normal .Xauthority file" #debug + $COMMAND_XAUTH -f "$SHADOW_XAUTHORITY" merge "$HOME/.Xauthority" + fi + + if [ "$1" = "restore" ]; then + #nxlog "$lp restore session" #debug + #echo > "$NXSESSION_DIRECTORY/session" #this cause to damage file + sh -c 'echo "Info: tail -f running with pid '\'\$$\''."; exec tail -n1 -f '"$NXSESSION_DIRECTORY"'/session' | node_start_monitor "restore" & + MONITOR_PID=$!; export MONITOR_PID + #nxlog "$lp call 'node_suspend_session \"$session_id\"'" #debug + node_suspend_session "$session_id" || { + echo "Info: Reconnection failed: NX Agent process could not be found." >> \ + "$NXSESSION_DIRECTORY/session"; + node_fail_restore_session "$session_id"; + return 1; + } + else # start + #nxlog "$lp call 'node_start_agent'" #debug + node_start_agent & + #nxlog "$lp call 'node_start_applications'" #debug + node_start_applications & + if [ -x "$NODE_AUTOSTART" ]; then + #nxlog "$lp NODE_AUTOSTART: waiting for nxagent" #debug + ok="" step="0.01" timeo=$((AGENT_STARTUP_TIMEOUT*100)) + for (( i=0; i<=timeo; i++ )); do + [ -f /tmp/.X$display-lock ] && { ok="1"; break; } + sleep $step"s" + done + [ -n "$ok" ] || { + nxlog "$lp /tmp/.X$display-lock not found after $AGENT_STARTUP_TIMEOUT s"; + } + + # go into background immediately + NXSESSIONID="$sess_id" DISPLAY=:$display "$NODE_AUTOSTART" "$1" >/dev/null 2>&1 & + disown $! # dont't wait for this child! + fi + fi + + if [ -n "$mediahelper" -a "$1" != "application" ]; then + #nxlog "$lp display='$display', waiting for it's ready" #debug + ok="" step="0.01" timeo=$((AGENT_STARTUP_TIMEOUT*100)) + for (( i=0; i<=timeo; i++ )); do + [ -f /tmp/.X$display-lock ] && { ok="1"; break; } + sleep $step"s" + done + [ -n "$ok" ] || \ + nxlog "$lp /tmp/.X$display-lock not found after $AGENT_STARTUP_TIMEOUT s"; + [ -n "$ok" ] && { + #nxlog "$lp env: $(env)" #debug + uservice_start ${mediahelper%%-*} "" "media-pa" "" "" "" "$mediahelper" + } + fi + + if [ -n "$MONITOR_PID" ]; then + wait "$MONITOR_PID" + usess_set "$session_id" "tail_pid" "0" + fi + wait # for all children + #nxlog "$lp end" #debug +} + +cmd_node_terminate() { + echo "$delim 716 Terminating session $session_id on user request." + node_terminate_session "$session_id" +} + +cmd_node_suspend() { + echo "$delim 716 Suspending session $session_id on user request." + node_suspend_session "$session_id" +} + +# ----------------------------------------------------------------------------- +# Startup of nxnode +# ----------------------------------------------------------------------------- +declare -g delim="NX>" CMDLINE="" nx_dir nxuser_logfile umask0=$(umask); +open_dbe $$ +attach_db "$sq_settings_fn" ro || { + echo "$delim 500 Error: NXNODE: Unable to attach db file $sq_settings_fn"; + exit_proc 1; +} +set_vars_from_db "" $USER + +[ -n "$2" ] && delim="NX-$2>" +echo "$delim 1000 NXNODE - Version $NX_VERSION $NX_LICENSE" + +if [ "$USER" = "nx" ]; then + nx_dir="/var/lib/nxserver/home" # ??? + nxuser_logfile="/var/log/nx/nxnode.log" +else + nx_dir="$HOME/.nx" + [ -d $nx_dir ] || { umask 0077; mkdir -p $nx_dir; umask $umask0; } + nxuser_logfile="$nx_dir/nxnode.log" +fi + +attach_db "$nx_dir/usessions.sq3" && { + init_usessions_db; chmod 0600 "$nx_dir/usessions.sq3" >/dev/null 2>&1; } + +if ! stringinstring "$1" "--check|--setkey|--agent"; then + read CMDLINE; + set_vars_from_ampstr "$CMDLINE" "" "recode" + if [ -z "$session_id" ]; then + echo "NX> 500 Error: Fatal - Missing parameter session id." 1>&2 + exit_proc 1 + fi + declare -g sess_id="$SERVER_NAME-$display-$session_id" + declare -g NXSESSION_DIRECTORY="$nx_dir/C-$sess_id" + nxuser_logfile="$nx_dir/nxnode-$session_id.log" + nxlog "$0 ($$): run nxnode with PARAMS:\"$@\"; CMDLINE='$CMDLINE'" +else + nxlog "$0 ($$): run nxnode with \"$@\"" +fi + +case "$1" in + --startsession) + startsession "start" + ;; + --resumesession) + startsession "restore" + ;; + --applicationsession) + startsession "application" + ;; + --terminate) + cmd_node_terminate + ;; + --suspend) + cmd_node_suspend + ;; + --smbmount) + [ "$(usess_get $session_id "client")" = "winnt" ] && { + username=$(getparam "$CMDLINE" "username") # reread with no hex recode + computername=$(getparam "$CMDLINE" "computername") + username=$(cp_conv "$username"); password=$(cp_conv "$password") + share=$(cp_conv "$share"); dir=$(cp_conv "$dir") + computername=$(cp_conv "$computername") + } + uservice_start "//127.0.0.1/$share" "" "smb-share" "$share" \ + "$username" "$password" "$dir" "$computername" + ;; + --addprinter) + [ "$(usess_get $session_id "client")" = "winnt" ] && { + username=$(getparam "$CMDLINE" "username") # reread with no hex recode + computername=$(getparam "$CMDLINE" "computername") + username=$(cp_conv "$username"); password=$(cp_conv "$password") + share=$(cp_conv "$share"); computername=$(cp_conv "$computername") + } + [ -n "$defaultPrinter" ] && defaultprinter=$defaultPrinter + opts="model=$model;public=$public;defaultprinter=$defaultprinter" + [ "$type" = "ipp" ] && share=$printer; svc=$share + + [ "${svc:0:1}" = "@" ] && svc=${svc:1} # for backward compatibility + svc=${svc%-nocheck}; svc="$USER""_${svc%%__*}" + + uservice_start "$svc" "" "$type-prn" "$share"\ + "$username" "$password" "$opts" "$computername" + ;; + --check) + echo "NX> 716 finished" + ;; + --agent) + echo "NX> 716 Starting NX Agent ..." + shift + [ "$SET_LD_LIBRARY_PATH" = "1" ] && export LD_LIBRARY_PATH="$AGENT_LIBRARY_PATH:$LD_LIBRARY_PATH" + PATH="$PATH:$PATH_BIN" $COMMAND_NXAGENT \ + -name "NX Agent Test - Args: $@" $@ + echo "NX> 716 NX Agent exited with status: $?" + ;; + --setkey) + mkdir -m 700 -p $HOME/.ssh + if ! grep -q "$(cat $NX_ETC_DIR/users.id_dsa.pub)" $HOME/.ssh/$SSH_AUTHORIZED_KEYS 2>/dev/null; then + cat $NX_ETC_DIR/users.id_dsa.pub >> $HOME/.ssh/$SSH_AUTHORIZED_KEYS + chmod 600 $HOME/.ssh/$SSH_AUTHORIZED_KEYS + echo "NX> 716 Public key added to: $HOME/.ssh/$SSH_AUTHORIZED_KEYS" + else + echo "NX> 716 Public key is already present in: $HOME/.ssh/$SSH_AUTHORIZED_KEYS" + fi + ;; + *) + echo "NX> 500 Error: Command not found" + ;; +esac + +echo "$delim 1001 Bye." +exit_proc 0 diff --git a/nxnode-login b/nxnode-login new file mode 100755 index 0000000..601182f --- /dev/null +++ b/nxnode-login @@ -0,0 +1,105 @@ +#!/usr/bin/expect +# +# nxnode-login: spawns and controls ssh +# +# Copyright (c) 2004-2006 by Fabian Franz. +# +# License: GPL, version 2 +# +# SVN: $Id: nxnode-login 512 2008-03-10 23:01:03Z fabianx $ +# + +# Syntax: nxnode-login {ssh|su|test-nx} user ssh-port executable command tosend + +set auth_method [lindex $argv 0] +set user [lindex $argv 1] +set port [lindex $argv 2] +set executable [lindex $argv 3] +set command [lindex $argv 4] +set tosend [lindex $argv 5] +catch {set tosend $env(NXNODE_TOSEND)} +set command_ssh "ssh" +catch {set command_ssh $env(COMMAND_SSH)} +set host "127.0.0.1" +catch {set host $env(NODE_HOSTNAME)} + +# +# Special test-nx instruction for nxsetup +# + +if { "$auth_method"=="test-nx" } { + set stty_init "raw icrnl -echo" + + set publickey "" + catch {set publickey $env(NODE_PUBLICKEY)} + + set pid [spawn -noecho $command_ssh -2 -x -l "$user" "$host" -i "$publickey" -o "RhostsAuthentication no" -o "PasswordAuthentication no" -o "PubkeyAuthentication yes" -o "PreferredAuthentications publickey" -o "ConnectTimeout 3" -p "$port" "$executable $command" ] + + while {1} { + expect { + "Are you sure you want to continue connecting*" { send "yes\r" } + "Permission denied*" { exit 1 } + "HELLO NXSERVER - Version*\n" { + break + } + } + } + expect "NX> 105" { send "quit\r" } + expect "NX> 999 Bye" + exit 0 +} + +# +# Log the user in via the supplied method. +# + +expect_user -re "(.*)\n" +set password $expect_out(1,string) + +set stty_init "raw icrnl -echo" + +if { "$auth_method"=="ssh" } { + set pid [spawn -noecho $command_ssh -2 -x -l "$user" "$host" -o "NumberOfPasswordPrompts 1" -p "$port" "$executable $command" ] +} elseif { "$auth_method"=="su" } { + set env(LANG) "C" + set pid [spawn -noecho su - "$user" -c "$executable $command" ] +} elseif { "$auth_method"=="guest" } { + set pid [spawn -noecho $executable $command ] +} else { + exit 1 +} + +while {1} { + expect { + "Are you sure you want to continue connecting*" { send "yes\r" } + "assword*:" { sleep 0.3; send "$password\r" } + "SSH passphrase:" { sleep 0.3; send "$password\r" } + "Permission denied*" { exit 1 } + "su: Authentication failure" { exit 1 } + "NX> 1000 NXNODE - Version" { + break + } + } +} + +if { "$tosend"!="" } { + send "$tosend\r" +} + +expect { + "NX> 716 finished" { } + "NX> 700" { + set timeout -1 + expect { + "NX> 1001 Bye." { exit 0 } + "NX> *" { exp_continue } + } + exit 0 + } + "NX> 716 Public key is already present in:" { } + "NX> 716 Public key added to:" { } + "NX> 716 Terminating session * on user request." { } + "NX> 716 Suspending session * on user request." { } + "NX> 500 Error: " { exit 1} +} +expect "NX> 1001 Bye." diff --git a/nxredir/Makefile b/nxredir/Makefile new file mode 100644 index 0000000..b943a6f --- /dev/null +++ b/nxredir/Makefile @@ -0,0 +1,29 @@ +PREFIX ?= /usr +PATH_BIN ?= $(PREFIX)/bin +PATH_LIB ?= $(PREFIX)/lib +CUPS_BACKEND ?= $(PREFIX)/lib/cups/backend + +all: libnxredir.so + +CC=gcc +CFLAGS=-g -O2 -Wall -fPIC +LIBNAME=libnxredir.so +VERSION=0 + +libnxredir.so: nxredir.o + $(CC) -fPIC $(CFLAGS) -nostdlib -shared -Wl,-soname,$(LIBNAME).$(VERSION) -o $(LIBNAME).$(VERSION) nxredir.o -ldl -lc + +clean: + rm -f $(LIBNAME) + rm -f $(LIBNAME).$(VERSION) + rm -f *.o + +install: + install -m755 -s $(LIBNAME).$(VERSION) $(DESTDIR)/$(PATH_LIB)/freenx-server/ + install -m755 nxredir $(DESTDIR)/$(PATH_BIN)/ + install -m755 nxsmb $(DESTDIR)/$(CUPS_BACKEND)/ + sed -i -e 's|PATH_LIB=.*|PATH_LIB='$(PATH_LIB)'|' $(DESTDIR)/$(PATH_BIN)/nxredir + sed -i -e 's|PATH_LIB=.*|PATH_LIB='$(PATH_LIB)'|' $(DESTDIR)/$(CUPS_BACKEND)/nxsmb + sed -i -e 's|CUPS_BACKEND=.*|CUPS_BACKEND='$(CUPS_BACKEND)'|' $(DESTDIR)/$(CUPS_BACKEND)/nxsmb + +.PHONY: clean install diff --git a/nxredir/nxredir b/nxredir/nxredir new file mode 100755 index 0000000..b01ea70 --- /dev/null +++ b/nxredir/nxredir @@ -0,0 +1,21 @@ +#!/bin/sh + +PATH_LIB="/usr/lib" +NXREDIR_LIBRARY="$PATH_LIB/freenx-server/libnxredir.so.0" + +if [ -z "$NXCUPS_PORT" -a -z "$NXSAMBA_PORT" ] +then + echo "nxredir: Redirect standard ports to nxproxy" + echo "" + echo "Usage: export NXCUPS_PORT='where_cups_is_running'" + echo " export NXSAMBA_PORT='where_samba_is_running'" + + # invoke the program with the args given + exec "$@" + exit 0 +fi + +export LD_PRELOAD="$NXREDIR_LIBRARY${LD_PRELOAD:+:$LD_PRELOAD}" + +# invoke the program with the args given +exec "$@" diff --git a/nxredir/nxredir.c b/nxredir/nxredir.c new file mode 100644 index 0000000..8ce8753 --- /dev/null +++ b/nxredir/nxredir.c @@ -0,0 +1,116 @@ +/* + * libnxredir - Redirect certain ports to other forwarded ports. + * + * Copyright (c) 2005-2008 by Fabian Franz . + * + * License: GPL, version 2 + * + * Based on TSOCKS - Wrapper library for transparent SOCKS + * + * Copyright (C) 2000 Shaun Clowes + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +char *progname = "libnxredir"; /* Name used in err msgs */ + +#define _GNU_SOURCE + +/* Header Files */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define CONNECT_SIGNATURE int __fd, const struct sockaddr * __addr, socklen_t __len + +static int (*realconnect)(CONNECT_SIGNATURE); + +/* Exported Function Prototypes */ +void _init(void); + +int connect(CONNECT_SIGNATURE); + +void _init(void) +{ + realconnect = dlsym(RTLD_NEXT, "connect"); +} + +int is_local(struct in_addr *testip) { + + if (testip->s_addr == htonl(0x7f000001)) + return(1); + + return(0); +} + +int connect(CONNECT_SIGNATURE) +{ + struct sockaddr_in *connaddr; + struct sockaddr_in peer_address; + int sock_type = -1; + socklen_t sock_type_len = sizeof(sock_type); + socklen_t namelen = sizeof(peer_address); + + if (realconnect == NULL) { + perror("Unresolved symbol: connect\n"); + return(-1); + } + + connaddr = (struct sockaddr_in *) __addr; + + /* Get the type of the socket */ + getsockopt(__fd, SOL_SOCKET, SO_TYPE, + (void *) &sock_type, &sock_type_len); + + /* If this isn't an INET socket for a TCP stream we can't */ + /* handle it, just call the real connect now */ + if ((connaddr->sin_family != AF_INET) || (sock_type != SOCK_STREAM)) + return(realconnect(__fd, __addr, __len)); + + /* If the socket is already connected, just call connect */ + /* and get its standard reply */ + if (!getpeername(__fd, (struct sockaddr *) &peer_address, &namelen)) + return(realconnect(__fd, __addr, __len)); + + /* If the address is not local call realconnect */ + if (!is_local(&(connaddr->sin_addr))) + return(realconnect(__fd, __addr, __len)); + + /* CUPS */ + if ((getenv("NXCUPS_PORT") != NULL) && connaddr->sin_port==htons(631)) + connaddr->sin_port=htons(atoi(getenv("NXCUPS_PORT"))); + + /* SAMBA */ + if ((getenv("NXSAMBA_PORT") != NULL) && (connaddr->sin_port==htons(139) || connaddr->sin_port==htons(445))) + connaddr->sin_port=htons(atoi(getenv("NXSAMBA_PORT"))); + + return realconnect(__fd, __addr, __len); +} diff --git a/nxredir/nxsmb b/nxredir/nxsmb new file mode 100755 index 0000000..a5c9260 --- /dev/null +++ b/nxredir/nxsmb @@ -0,0 +1,45 @@ +#!/bin/sh +# +# nxsmb: Small wrapper for the SMB backend to be able to print to CIFS or SMB ports directly. +# +# Copyright (c) 2008 by Fabian Franz. +# +# + +# turn on DEBUG? +#set -x -v +CUPS_BACKEND="/usr/lib/cups/backend" +PATH_LIB="/usr/lib" + +NXREDIR_LIBRARY="$PATH_LIB/freenx-server/libnxredir.so.0" +COMMAND_SMB="$CUPS_BACKEND/smb" + +PORT=$(echo $DEVICE_URI | cut -d/ -f3 | cut -d@ -f2 | cut -d: -f2) +PROTOCOL=$(echo $DEVICE_URI | cut -d/ -f4) +PRINTER=$(echo $DEVICE_URI | cut -d/ -f5) + +if [ -z "$PRINTER" ]; then # old style setup + echo "Warning: Not using nxredir library. The DEVICE_URI is not in the right format." + exec "$COMMAND_SMB" "$@" +fi + +if [ ! -x "$NXREDIR_LIBRARY" ]; then + # repair DEVICE_URI + DEVICE_URI=$(echo $DEVICE_URI | sed "s|/$PROTOCOL||g") + echo "Error: Not using nxredir library. $NXREDIR_LIBRARY could not be found or is not executable." + exec "$COMMAND_SMB" "$@" +fi + +if [ "$PROTOCOL" = "cifs" -o "$PROTOCOL" = "CIFS" ]; then + REAL_PORT="445" +else + REAL_PORT="139" +fi + +DEVICE_URI=$(echo $DEVICE_URI | sed "s|:$PORT/$PROTOCOL/|:$REAL_PORT/|g") +export DEVICE_URI=$(echo $DEVICE_URI | sed "s|nxsmb://|smb://|g") + +export NXSAMBA_PORT="$PORT" +export LD_PRELOAD="$NXREDIR_LIBRARY${LD_PRELOAD:+:$LD_PRELOAD}" + +exec "$COMMAND_SMB" "$@" diff --git a/nxserver b/nxserver new file mode 100755 index 0000000..07e899d --- /dev/null +++ b/nxserver @@ -0,0 +1,1515 @@ +#!/bin/bash + +# Free implementation of nxserver components +# +# To use nxserver add the user "nx" +# and use nxserver as default shell. +# +# Also make sure that hostkey based authentification works. +# +# Copyright (c) 2004 by Fabian Franz . +# (c) 2008-23 by Dmitry Borisov +# +# License: GNU GPL, version 2 + +shopt -s extglob + +SHARED_CONFS="/usr/share/freenx-server" +. $SHARED_CONFS/nxfuncs + +log() { +#args: + [ "$NX_LOG_LEVEL" != "0" ] || return + [ -n "$1" ] && \ + echo -n "[$(date "+%d.%m %T.%3N"): $$/$BASHPID] " >> "$NX_LOGFILE" + echo -e $@ >> "$NX_LOGFILE" +} + +# Log in a way that is secure for passwords / cookies / ... +echo_secure() { + [ -n "$1" ] && \ + echo -n "[$(date "+%d.%m %T.%3N")] " >> "$NX_LOGFILE" + local res=${@/password=+([^&])&/password=*&} + res=${res//password=\"+([^\"])\"/password=\"*\"} + echo "$res" +} + +log_secure() { +#args: + [ "$NX_LOG_LEVEL" != "0" ] || return + echo_secure $@ >> "$NX_LOGFILE" +} + +log_tee() { + if [ "$NX_LOG_LEVEL" != "0" ]; then exec tee -a "$NX_LOGFILE" + else exec cat - + fi +} + +log_error() { + if [ "$NX_LOG_LEVEL" != "0" ]; then exec tee -a "$NX_LOGFILE" + else exec cat - + fi +} + +echo_x() { log "$@"; echo "$@"; } + +############### PACKAGE session.bm ####################### +# +# Library of session management functions +# + +# Needed global vars: NX_SESS_DIR session_count session_count_user +# COMMAND_MD5SUM SESSION_USER_LIMIT SESSION_LIMIT SESSION_HISTORY +# user + +# =================== sqlite3 stuff ===================== + +sqcols_sess="session_id, session, display, status, userip,\ + rootless, type, user, screeninfo, geometry, host, shadowcookie,\ + startTime, creationTime, endTime, agent_pid" + +init_sess_db() { + local sess_cols="session_id TEXT PRIMARY KEY, session TEXT,\ + display TEXT, status TEXT, userip TEXT, rootless INT, type TEXT,\ + user TEXT, screeninfo TEXT, geometry TEXT, host TEXT,\ + shadowcookie TEXT, startTime INT, creationTime INT, endTime INT,\ + agent_pid TEXT" + local qstr="CREATE TABLE IF NOT EXISTS sessions.sess($sess_cols);" + qstr+="CREATE INDEX IF NOT EXISTS sessions.idx_status_user ON\ + sess(status,user);" + q_dbe "$qstr" +} + +#------------------------------------------------------------------- + +session_list() { +#params: sessId ["format_times"] +#if you need to humane output put something in $2 + local qc fls res r2=""; + [ -n "$2" ] && { fls="session_id, session, display, status,\ + userip, rootless, type, screeninfo, geometry, host, shadowcookie,\ + datetime(startTime,'unixepoch','localtime') AS startTime,\ + datetime(creationTime,'unixepoch','localtime') AS creationTime, user,\ + datetime(endTime,'unixepoch','localtime') AS endTime"; + } || { # original order of fields + fls=$sqcols_sess; + } + res=$(qa_dbe ".mode line sess\n" \ + "SELECT $fls FROM sess WHERE session_id='$1' LIMIT 1;") + [ -n "$2" ] && { echo "$res"; return; } + local line k v; + while read line; do + k=$(trim "$(cutfn "$line" 0 '=')"); v=$(trim "$(cutfn "$line" 1 '=')") #" + r2+="$k=$v"$'\n' + done <<< "$res" + echo -n "$r2" +} + +session_find_cmdstrs() { +#params: [sessid] [user] [display] [status="Running|Suspended"] +#ret: sessions command strings delimited by \n + local st wstr res; + st="Running|Suspended"; [ -n "$4" ] && st="$4" + wstr="WHERE $(str_eq_cond "status" "$st")" + [ -n "$1" ] && wstr+=" AND $(str_eq_cond "session_id" "$1")" + [ -n "$2" -a "$2" != "all" -a "$2" != ".*" ] && \ + wstr+=" AND $(str_eq_cond "user" "$2")" + [ -n "$3" ] && wstr+=" AND $(str_eq_cond "display" "$3")" + res=$(qa_dbe ".mode line sess\n" \ + "SELECT $sqcols_sess FROM sess $wstr ORDER BY startTime DESC;") + qtxt2cmdstrs "$res" +} + +# Find all running session-filenames +session_find_all() { session_find_cmdstrs; } + +# Find all running sessions of a id +session_find_id() { session_find_cmdstrs "$1"; } + +# Finds out if a session belongs to a user +session_find_user() { session_find_cmdstrs "" "$1"; } + +# Find all running sessions of a display +session_find_display() { session_find_cmdstrs "" "" "$1"; } + +# Finds out if a session belongs to a user +session_find_id_user() { +#params: sessid [user] + local wstr c; + wstr="WHERE session_id='$1' AND status IN ('Running', 'Suspended')" + [ -n "$2" -a "$2" != "all" -a "$2" != ".*" ] && \ + wstr+=" AND $(str_eq_cond "user" "$2")" + c=$(qa_dbe ".mode tabs sess\n" \ + "SELECT count(session_id) FROM sess $wstr LIMIT 1;") + [ "$c" -gt "0" 2>/dev/null ] || return 1 + return 0 +} + +# session_get +session_get() { session_find_cmdstrs "$1"; } + +# Get the first session, which can be resumed +session_get_user_suspended() { +#params: user status +#ret: session_id line[s] or empty + local wstr r a; + wstr="WHERE status='$2'AND user='$1'" + r=$(qa_dbe ".mode tabs sess\n" \ + "SELECT count(session_id), session_id FROM sess $wstr ORDER BY startTime DESC LIMIT 1;") + a=($r); ((${#a[@]}==2)) && echo "${a[1]}" +} + +session_count_user() { +#params: user [status] +# Count all sessions of a user +# and save it in session_count and session_count_user + local st wstr r u="" sc="" + session_count=0; session_count_user=0 + st="Running|Suspended"; [ -n "$2" ] && st="$2" + wstr="WHERE $(str_eq_cond "status" "$st")" + if [ "$1" = ".*" -o "$1" = "all" ]; then + session_count=$(qa_dbe ".mode tabs sess\n" \ + "SELECT count(*) FROM sess $wstr;") #" + session_count_user=$session_count + return 0 + fi + r=$(qa_dbe ".mode tabs sess\n" \ + "SELECT user,count(*) FROM sess $wstr GROUP BY user;") #" + while read u sc; do + [ -z "$sc" ] && continue + ((session_count+=sc)) + [ "$u" = "$1" ] && session_count_user=$sc + done <<< "$r" + return 0 +} + +session_user_acl_load() { +#arg: +# load nx shadow acl for given user and store it to +# shadow_users shadow_oviews shadow_uauths variables + [ -n "$ugroups" ] || \ + { ugroups=$(groups $1); ugroups=$(trim "${ugroups#*:}"); } + local s ucond="'#$1','*${ugroups// /\',\'\*}','@all'" + local mode=".mode csv settings\n.separator '&'\n" + local qstr="SELECT value,val_type,val_depend FROM settings WHERE user IN ($ucond) \ + AND key='@shadow@' ORDER BY user ASC, val_check DESC LIMIT 1;" + #log "$FUNCNAME: qstr='$qstr'" #debug + local ts=$(qa_dbe "$mode" "$qstr") + #log "$lp ts='$ts'" #debug + shadow_users=$(cutfn "$ts" 0 '&') + s=$(cutfn "$ts" 1 '&'); shadow_oviews=(${s//,/ }) + s=$(cutfn "$ts" 2 '&'); shadow_uauths=(${s//,/ }) +} + +_session_list_user_suspended() { +# args: [geometry] +# use conf vars: COMMAND_MD5SUM +# use glob: user + local p pstrs pattern geom depth render udepth urender mode; + local options available session_id geo2 displays disp2; + local puser pshadowcookie pscreeninfo prootless pgeometry pstatus; + local ptype pdisplay psession_id psession + local shadow_all="" + [ "$4" = "shadow" ] && stringinstring ",all," ",$shadow_users," && shadow_all="1" + echo "NX> 127 Sessions list of user '$1' for reconnect:" + echo + if [ -z "$4" ]; then + echo "Display Type Session ID Options Depth Screensize Available Session Name" + echo "------- ---------------- -------------------------------- -------- ----- -------------- --------- ----------------------" + else + echo "Display Type Session ID Options Depth Screen Status Session Name" + echo "------- ---------------- -------------------------------- -------- ----- -------------- ----------- ------------------------------" + fi + pstrs=$(session_find_cmdstrs "" "$1" "" "$2") + while read p; do + [ -z "$p" ] && continue + puser=$(getparam "$p" user); pshadowcookie=$(getparam "$p" shadowcookie); + pscreeninfo=$(getparam "$p" screeninfo); prootless=$(getparam "$p" rootless) + pgeometry=$(getparam "$p" geometry); pstatus=$(getparam "$p" status) + ptype=$(getparam "$p" type); pdisplay=$(getparam "$p" display) + psession_id=$(getparam "$p" session_id); psession=$(getparam "$p" session) + if [ "$4" = "shadow" -a "$puser" != "$1" ]; then + [ "$ENABLE_SESSION_SHADOWING" = "1" ] || continue + [ -n "$NX_ACL_DIR" -a -z "$shadow_all" ] && { + #log "in nxacl present CHECK ,$puser, ; ,$shadow_users," #debug + stringinstring ",$puser," ",$shadow_users," || continue + } + fi + + pattern='^([0-9]*x[0-9]*)x([0-9]*)\+?([^+]*)' + [[ $pscreeninfo =~ $pattern ]] + geom=${BASH_REMATCH[1]}; depth=${BASH_REMATCH[2]}; render=${BASH_REMATCH[3]} + [[ $3 =~ $pattern ]] + udepth=${BASH_REMATCH[2]}; urender=${BASH_REMATCH[3]} + mode="D"; [ "$prootless" = "1" ] && mode="-" + options="-"; stringinstring "fullscreen" "$3" && options="F" + [ "$pgeometry" = "fullscreen" ] || options="-" + [ "$urender" = "render" ] && options="${options}R${mode}--PSA" + [ "$urender" = "render" ] || options="${options}-${mode}--PSA" + [ "$udepth" = "$depth" -a "$urender" = "$render" ] && available=$pstatus + # FIXME: HACK !!! to keep compatibility with old snapshot version (Knoppix 3.6 based for example) + if [ -z "$4" -a "$available" != "N/A" ]; then + available="Yes" + fi + if [ "$4" = "shadow" ]; then + available=$pstatus + printf "%-7s %-16s %32s %8s %5s %-14s %-11s %s\n" "$pdisplay" "$ptype" "$psession_id" "$options" "$depth" "$geom" "$available" "$psession ($puser) (Shadowed)" + else + # only unix-* sessions can be resumed, but other session types can still be terminated + stringinstring "unix-" "$4" || available="N/A" + printf "%-7s %-16s %32s %8s %5s %-14s %-11s %s\n" "$pdisplay" "$ptype" "$psession_id" "$options" "$depth" "$geom" "$available" "$psession" + fi + done <<< "$pstrs" + echo "" + echo "" + + session_count_user "$1" + if [ "$session_count" -ge "$SESSION_LIMIT" -o \ + "$session_count_user" -ge "$SESSION_USER_LIMIT" ]; then + echo "NX> 147 Server capacity: reached for user: $1" + else + echo "NX> 148 Server capacity: not reached for user: $1" + fi +} + +session_list_user_suspended() { + local slcd=$(_session_list_user_suspended "$@") + echo "$slcd" | log_tee +} + +session_list_user() { +#params: user [status="Running|Suspended"] + local st wstr + echo -n "NX> 127 Sessions list" + if [ -n "$1" -a "$1" != "all" ]; then echo " of user '$1'" + else echo ":" + fi + echo + echo "Server Display Username Remote IP Session ID" + echo "------ ------- --------------- --------------- --------------------------------" + st="Running|Suspended"; [ -n "$2" ] && st="$2" + wstr="WHERE $(str_eq_cond "status" "$st")" + [ -n "$1" -a "$1" != "all" ] && wstr+=" AND $(str_eq_cond "user" "$1")" + qa_dbe ".mode tabs sess\n SELECT host,display,user,userip,session_id\ + FROM sess $wstr ORDER BY startTime DESC;" # ! check order ! +} + +session_history() { +#params: user session_id + local wstr="" + echo "NX> 127 Session list:" + echo + echo "User Remote IP Status Start Stop " + echo "------- --------------- --------------- -------------- ---------------" + [ -n "$1" -a "$1" != "all" ] && wstr="$(str_eq_cond "user" "$1")" + [ -n "$wstr" -a -n "$2" ] && wstr+=" AND " + [ -n "$2" ] && wstr+=" session_id='$2'" + [ -n "$wstr" ] && wstr="WHERE $wstr" + qa_dbe ".mode tabs sess\n SELECT user,userip,status,strftime('%d.%m-%H:%M:%S',startTime,'unixepoch','localtime'),\ + strftime('%d.%m-%H:%M:%S',endTime,'unixepoch','localtime')\ + FROM sess $wstr ORDER BY endTime;" +} + +# remove all sessions older than $SESSION_HISTORY seconds in failed/closed. +session_cleanup() { + local checkTime st wstr; + [ "$SESSION_HISTORY" -gt "-1" ] || return + let checkTime=$(date +%s)-$SESSION_HISTORY + st="Finished|Failed"; + wstr="WHERE $(str_eq_cond "status" "$st") AND startTime < $checkTime" + q_dbe "DELETE FROM sess $wstr;" +} + +session_list_all() { session_list_user "all"; } + +session_add() { +#params: + q_row_ins "sess" "$1" "$2" +} + +session_change() { +# + q_rows_upd "sess" "session_id='$1'" "$2" "$3" +} + +# session_running (? now dublicated session_find_id_user ?) +# return: true if running, false if not +session_running() { session_find_id_user "$1"; } + +session_close() { +#param: + if [ "$SESSION_HISTORY" = "0" ] ; then + q_dbe "DELETE FROM sess WHERE session_id='$1';" + else + session_change "$1" "status,endTime" "Finished&$(date +%s)" + fi +} + +session_fail() { +#param: + if [ "$SESSION_HISTORY" = "0" ] ; then + q_dbe "DELETE FROM sess WHERE session_id='$1';" + else + session_change "$1" "status,endTime" "Failed&$(date +%s)" + fi +} +# +# end of library +# + +msg2agentdisplay() { +#args: <[host]:display> +# [window_caption] [timeo=$AGENT_STARTUP_TIMEOUT] +# return exit code of nxdialog + local capt="FREENX server"; [ -n "$6" ] && capt=$6 + local timeo=$AGENT_STARTUP_TIMEOUT; [ -n "$7" ] && timeo=$7 + local rc=0 + $COMMAND_XAUTH add "$3" MIT-MAGIC-COOKIE-1 "$4" &>/dev/null + DISPLAY="$3" $PATH_BIN/nxdialog --display "$3" --parent $5 \ + --dialog "$1" --caption "$capt" --message "$2" &>/dev/null & + local dlg_pid=$! + if [ $timeo -gt 0 ]; then # make a simple watchdog for nxdialog + ( sleep $timeo"s" + kill -0 $dlg_pid &>/dev/null && kill $dlg_pid &>/dev/null; ) & + fi + if stringinstring "$1" "ok|error|panic"; then + sleep 0.5s # don't remove xauthority cookie right now + else # wait for anwers only + wait $dlg_pid + rc=$? + fi + $COMMAND_XAUTH remove "$3" &>/dev/null + return $rc +} + + +# +# Main nxserver <-> nxclient communication module +# + +# config variables in use: +# COMMAND_MD5SUM COMMAND_NETCAT +# COMMAND_SESSREG COMMAND_SSH COMMAND_XAUTH +# ENABLE_AUTORECONNECT +# ENABLE_LOAD_BALANCE_PREFERENCE ENABLE_LOG_FAILED_LOGINS +# ENABLE_SESSION_SHADOWING_AUTHORIZATION +# ENABLE_USESSION LOAD_BALANCE_SERVERS +# NX_ETC_DIR NX_HOME_DIR NX_LICENSE NX_LOGFILE NX_LOG_LEVEL +# NX_SESS_DIR NX_VERSION +# SERVER_NAME SESSION_HISTORY SESSION_LIMIT SESSION_USER_LIMIT + +# declare global variables: +declare -g cmd in_params proto login_success login_method ugroups="" +declare -g server_mode preferred_host session_count session_count_user +declare -g user2 ENCRYPTION proxy_display server_host +declare -g oifs rc NODE_HOSTNAME user fl_send="1" +declare -g shadow_users shadow_oviews shadow_uauths shadowviewonly shadowauth + +server_mode="0"; [ "$USER" = "nx" ] && server_mode="1" + +if [ "$server_mode" = "1" ]; then + +# Start! +open_dbe $$ +attach_db "$sq_settings_fn" ro || { + echo "NX> 500 Error: Unable to attach db file $sq_settings_fn"; + exit_proc 1; +} +set_vars_from_db +sess_bd="$NX_SESS_DIR/sessions.sq3" +attach_db $sess_bd && init_sess_db + +log "-- NX SERVER START: $@ - ORIG_COMMAND=$SSH_ORIGINAL_COMMAND" + +# Get the hostname out of SSH_ORIGINAL_COMMAND +preferred_host=$(rematchfn "host=([^&]*)" "$SSH_ORIGINAL_COMMAND") #" + + echo_x "HELLO NXSERVER - Version $NX_VERSION $NX_LICENSE" + # Login stage + while true; do + echo_x -n "NX> 105 " + read cmd + [ "$cmd" = "" ] && cmd="quit" # FIXME? + echo_x "$cmd" + case "$cmd" in + quit|QUIT) + echo_x "Quit"; echo_x "NX> 999 Bye"; exit_proc 0; + ;; + exit|EXIT) + echo_x "Exit"; echo_x "NX> 999 Bye"; exit_proc 0; + ;; + bye|BYE) + echo_x "Bye"; echo_x "NX> 999 Bye"; exit_proc 0; + ;; + hello*|HELLO*) + proto=$(rematchfn 'Version ([[:digit:][:punct:]]+)' "$cmd") #' + echo_x "NX> 134 Accepted protocol: $proto" + ;; + "set auth_mode*"|"SET AUTH_MODE*") + if [ "$cmd" = "set auth_mode password" -o \ + "$cmd" = "SET AUTH_MODE PASSWORD" ]; then + echo_x "Set auth_mode: password" + else + echo_x "NX> 500 ERROR: unknown auth mode ''" + fi + ;; + login|LOGIN) + login_success="0" + echo_x -n "NX> 101 User: "; read user2; echo_x $user2; + echo_x -n "NX> 102 Password: "; + oifs="$IFS"; export IFS=$'\n'; + read -r -s PASS; export IFS=$oifs; echo_x "" + log -n "Info: Auth method: " + # USER already logged in? + user=$user2 + + # SU based auth used ONLY + if [ "$login_success" = "0" ]; then + log -n "su " + LC_MESSAGES=C $COMMAND_SUDO -u $user -Svk -p "" \ + &>/dev/null <<< "$PASS" + if [ $? -eq 0 ]; then login_success="1"; login_method="SU"; fi + fi + + if [ "$login_success" = "1" ]; then + # Reread the config files (so that $USER.node.conf get sourced) + set_vars_from_db "" $user "only" + [ "$ENABLE_SESSION_SHADOWING" = "1" ] && session_user_acl_load $user + break + else + echo_x "NX> 404 ERROR: wrong password or login" + echo_x "NX> 999 Bye" + if [ "$ENABLE_LOG_FAILED_LOGINS" = "1" ]; then + logger -t nxserver -i -p auth.info \ + "($(whoami)) Failed login for user=$user from IP=$(echo $SSH_CLIENT | awk '{print $1}')" + fi + exit_proc 1 + fi + ;; + esac + done +echo_x "NX> 103 Welcome to: $SERVER_NAME user: $user" + +# remove old session infos from history +session_cleanup + +# +# call it with: server_get_params $cmd # no ""! +# +server_get_params() { + shift; + local server_params=" $@"; server_params=${server_params// --/\&}; + server_params=${server_params//\"/}; + if [ "$server_params" = "" ]; then + echo_x -n "NX> 106 Parameters: " + read server_params2; server_params=${server_params2//%2B/+} + echo_x + fi + server_params=${server_params//%20/ }; + server_params=${server_params//\&sessionid/\&session_id}; + server_params=${server_params//\&id/\&session_id}; + echo "$server_params" +} + +server_nxnode_start() { +# use vars: session_id +# NODE_HOSTNAME NXNODE_TOSEND + local cmd="$1" user="$2"; shift; shift; + + # Find NODE_HOSTNAME + #NODE_HOSTNAME="" + #CMDLINE="$@"; session_id=$(getparam session_id) + #CMDLINE=$(session_get "$session_id") + NODE_HOSTNAME=$host; [ -z "$NODE_HOSTNAME" ] && NODE_HOSTNAME="127.0.0.1" + export NODE_HOSTNAME + echo -e "$PASS\n$@" | \ + $COMMAND_SUDO -u $user -HSik -p "" $PATH_BIN/nxnode "$cmd" 2>&1 | \ + log_tee +} + +server_add_usession() { + [ "$ENABLE_USESSION" = "1" ] || return + $COMMAND_SESSREG -l ":$display" -h "$userip" -a $user 2>&1 | \ + log_error +} + +server_remove_usession() { + [ "$ENABLE_USESSION" = "1" ] || return + $COMMAND_SESSREG -l ":$display" -h "$userip" -d $user 2>&1 | \ + log_error +} + +server_nxnode_echo() { + if [ "$server_channel" = "1" ]; then + echo -e "$@" + log "$FUNCNAME >&$server_channel: $@" + elif [ "$server_channel" = "2" ]; then + echo -e "$@" >&2 + log "$FUNCNAME >&$server_channel: $@" + fi +} + +server_nxnode_exit_func() { + log "$FUNCNAME: Info: Emergency-Shutting down due to kill signal ..." + session_fail $session_id + server_remove_usession + # remove lock file + [ -e "/tmp/.nX$display-lock" ] && rm -f /tmp/.nX$display-lock + exit_proc 1 +} + +server_nxserver_exit_func() { + log "$FUNCNAME: Info: Emergency-Shutting down!" + [ -n "$adm_pid" ] && kill -0 $adm_pid &>/dev/null \ + && kill $adm_pid &>/dev/null + exit_proc 1 +} + +server_nxnode_start_wait() { +# use uplevel: $server_wait_pid $user $session_id + local lp=" $FUNCNAME:"; + local server_channel=1 kill_wait_pid=1 shadowcookie agent_pid + local fl_start="" to_send="" + open_dbe $BASHPID + [ "$1" = "--startsession" ] && fl_start="1"; + if [ -n "$fl_start" ]; then + server_add_usession + # We need to stop sending things when a SIGPIPE arrives + trap "server_channel=0" SIGPIPE + trap server_nxnode_exit_func EXIT + fi + server_nxnode_start "$@" | while read cmd; do + case "$cmd" in + "NX> 700"*) + server_channel=0; to_send="$cmd" + ;; + "NX> 706"*) + shadowcookie=$(cutfn "$cmd" 1 ':'); shadowcookie=${shadowcookie// /} + session_change "$session_id" "shadowcookie" "$shadowcookie" + to_send+="\n$cmd" + ;; + "NX> 733"*) + agent_pid=$(cutfn "$cmd" 1 ':'); agent_pid=${agent_pid// /} + session_change "$session_id" "agent_pid" "$agent_pid" + ;; + "NX> 70"*) + to_send+="\n$cmd" + ;; + "NX> 710"*) + to_send+="\n$cmd"; server_channel=1; + server_nxnode_echo "$to_send"; + server_channel=0; + to_send=""; + kill -SIGUSR2 $$ 2>/dev/null + continue + ;; + "NX> 1006"*|"NX> 1005"*|"NX> 1009"*) + case "$cmd" in + *running*) + [ "$kill_wait_pid" = "1" ] && kill -INT $server_wait_pid 2>/dev/null + kill_wait_pid=0 + if [ "$server_channel" = "1" ]; then + server_channel=2 + fi + log "$lp set status $session_id: Running" + session_change $session_id "status" "Running" + ;; + *starting*) + log "$lp set status $session_id: Starting" + session_change $session_id "status" "Starting" + continue; + ;; + *resuming*) + log "$lp set status $session_id: Resuming" + session_change $session_id "status" "Resuming" + continue; + ;; + *closed*) + if [ -n "$fl_start" ]; then + log "$lp session_close $session_id" + session_close $session_id; break; + fi + ;; + *suspended*) + if [ -n "$fl_start" ]; then + [ "$kill_wait_pid" = "1" ] && kill -INT $server_wait_pid 2>/dev/null + kill_wait_pid=0; log "$lp session suspend $session_id" + session_change $session_id "status,userip" "Suspended&-" + fi + ;; + *suspending*) + if [ -n "$fl_start" ]; then + log "$lp set status $session_id: Suspending" + session_change $session_id "status" "Suspending" + # we need to stop sending to client as it will have already + # closed his side of the channel and this will lead to not + # closed sessions. + server_channel=0 + fi + ;; + *terminating*) + if [ -n "$fl_start" ]; then + log "$lp set status $session_id: Terminating" + session_change $session_id "status" "Terminating" + # we need to stop sending to client as it will have already + # closed his side of the channel and this will lead to not + # closed sessions. + server_channel=0 + fi + ;; + esac + ;; + "NX> 1004"*) + [ "$kill_wait_pid" = "1" ] && { + kill -INT $server_wait_pid 2>/dev/null + kill_wait_pid=0 + } + # This fail is correct here as somehow the + # monitor process might have died and we don't + # want the session to be resumed again. + session_fail $session_id + server_nxnode_echo "NX> 596 Session startup failed." + log "NX> 596 Session startup failed." + [ -z "$fl_start" ] && break; # on restore only? + ;; + "NX> 1001"*) + if [ -z "$fl_start" ]; then + server_channel=0 + log "$lp nxnode finished (1001) on display $display" + close_dbe $BASHPID; exit_proc 0 + fi + ;; + esac + case $cmd in "NX> "*) server_nxnode_echo $cmd;; esac + done + + if [ "$1" = "--startsession" ]; then + trap - EXIT + trap - SIGPIPE + # Close it in case the session is still running + session_running $session_id && session_close $session_id + server_remove_usession + # remove lock file + [ -e "/tmp/.nX$display-lock" ] && rm -f /tmp/.nX$display-lock + fi + close_dbe $BASHPID + log "$lp $1 end on display $display" +} + +server_check_session_count() { + session_count_user "$user" + if [ "$session_count" -ge "$SESSION_LIMIT" ]; then + echo_x "NX> 599 Reached the maximum number of concurrent sessions on this server." + echo_x "NX> 500 ERROR: Last operation failed." + return 1 + fi + if [ "$session_count_user" -ge "$SESSION_USER_LIMIT" ]; then + echo_x "NX> 599 Server capacity: reached for user: $user" + echo_x "NX> 500 ERROR: Last operation failed." + return 1 + fi + return 0 +} + +server_loadbalance_random() { + # Pick one based on "random" algorithm + local server_lb_hosts=( $LOAD_BALANCE_SERVERS ) + local server_lb_nr_of_hosts=${#server_lb_hosts[@]} + let server_lb_nr=(RANDOM % server_lb_nr_of_host) + local server_lb_host=${server_lb_hosts[$server_lb_nr]} + echo $server_lb_host +} + +# run in subshell! +server_loadbalance_round_robin() { + local server_lb_hosts=( $LOAD_BALANCE_SERVERS ) + local server_lb_nr_of_hosts=${#server_lb_hosts[@]} + # Atomic incrementation: + # Enter critical section + # - Create .lock file + server_lb_lockfile=$(mktemp "$NX_SESS_DIR/round-robin.lock.XXXXXXXXX") + trap "rm -f $server_lb_lockfile" EXIT + i=0 + while [ $i -lt 200 ]; do + # ln is an atomic operation + ln $server_lb_lockfile "$NX_SESS_DIR/round-robin.lock" && break + LC_MESSAGES=C sleep 0.01 + ((i++)) + done + + if [ $i -ge 200 ]; then + log "Load-Balancing: Round-Robin failed to gain lock file in 200 tries. Falling back to random." + server_loadbalance_random + return + fi + trap "rm -f \"$server_lb_lockfile\" \"$NX_SESS_DIR/round-robin.lock\"" EXIT + + # Lock held + server_lb_nr=$(cat $NX_SESS_DIR/round-robin 2>/dev/null) + let server_lb_nr=(server_lb_nr+1)%server_lb_nr_of_hosts + echo $server_lb_nr >$NX_SESS_DIR/round-robin + + # Exit critical section + rm -f "$server_lb_lockfile" "$NX_SESS_DIR/round-robin.lock" + trap - EXIT + + server_lb_host=${server_lb_hosts[$server_lb_nr]} + echo $server_lb_host +} + +server_loadbalance_load() { + local server_lb_max=0 server_lb_host="" server_lb_load; + export PATH_BIN + for i in $LOAD_BALANCE_SERVERS; do + server_lb_load=$($COMMAND_NXCHECKLOAD $i) + [ -z "$server_lb_load" ] && continue + if [ $server_lb_load -gt $server_lb_max ]; then + server_lb_max=$server_lb_load + server_lb_host=$i + fi + done + echo $server_lb_host +} + +server_loadbalance() { + local server_host="127.0.0.1" + if [ -n "$LOAD_BALANCE_SERVERS" ]; then + server_host="" + if [ -n "$preferred_host" -a "$ENABLE_LOAD_BALANCE_PREFERENCE" = "1" ]; then + stringinstring " $preferred_host " " $LOAD_BALANCE_SERVERS " && \ + server_host="$preferred_host" + fi + # Fallback if still empty + if [ -z "$server_host" ]; then + case "$LOAD_BALANCE_ALGORITHM" in + random) + server_host=$(server_loadbalance_random) + ;; + round-robin) + server_host=$(server_loadbalance_round_robin) + ;; + load) + server_host=$(server_loadbalance_load) + ;; + esac + fi + [ -z "$server_host" ] && server_host="127.0.0.1" + [ -n "$server_host" ] && log "Info: Load-Balancing (if possible) to $server_host ..." + fi + echo "$server_host" +} + +server_startrestore_session() { + local action="$1" params="$2" rc sess_lockfile + local agent_display samba_display cups_display media_display restore + local server_pid server_wait_pid new_params db_params nshu="-1" i s + + + params+="&clientproto=$proto&login_method=$login_method" + echo_x + + if [ "$action" = "shadow" ]; then + shadowauth="0"; shadowviewonly="0" + action="start"; params=$(delparam "$params" "display"); + params=$(delparam "$params" "session_id"); + db_params=$(session_get "$in_session_id" 2>/dev/null) + set_vars_from_ampstr "$db_params" "db_" + + encryption=$in_encryption + shadowdisplay=$in_display; shadowhost=$db_host; + shadowuser=$db_user; shadowcookie=$db_shadowcookie + [ "$shadowcookie" = "none" ] && shadowcookie="" + [ "$in_shadowviewonly" = "1" ] && shadowviewonly="1" + if [ -z "$shadowdisplay" ]; then + echo_x "NX> 596 Could not find shadowed session $session_id. Session failed." + exit_proc 1 + fi + [ "$shadowhost" = "127.0.0.1" ] && shadowhost="" + + if [ "$user" != "$shadowuser" -a \ + "$ENABLE_SESSION_SHADOWING_AUTHORIZATION" = "1" ]; then + shadowauth="1" + [ -n "$shadow_users" ] && { + local shu=(${shadow_users//,/ }) + for ((i=0; i<${#shu[@]}; i++)) { + [ "${shu[$i]}" = "$shadowuser" -o "${shu[$i]}" = "all" ] && { + nshu=$i; break; + } + } + } + ((nshu>=0)) && { + [ "$shadowviewonly" = "0" ] && shadowviewonly=${shadow_oviews[$nshu]} + shadowauth=${shadow_uauths[$nshu]} + } + fi + if [ "$shadowauth" = "1" ]; then + # Ask for permission first: + echo_x "NX> 726 Asking user for authorization to attach to session" + + msg2agentdisplay "yesno" \ + "Do you want to allow $user to shadow your session?" \ + $shadowhost:$shadowdisplay $shadowcookie $db_agent_pid \ + "Authorization Request" + if [ "$?" != "1" ]; then + # User answered NO or time out + echo_x "NX> 596 Error: Authorization refused by user: $shadowuser." + exit_proc 1 + fi + fi + + params+="&shadowdisplay=$shadowdisplay&shadowhost=$shadowhost&\ +shadowcookie=$shadowcookie&shadowuser=$shadowuser&\ +shadowviewonly=$shadowviewonly&shadowauth=$shadowauth" + fi + + [ "$action" = "start" ] && \ + [ "$type" = "windows" -o "$type" = "vnc" ] && \ + params=${params//&type=$type&/&type=$type'-helper'&} + + # If we can't get the userip and SSHD_CHECK_IP is set to 1 + # we bail out. + if [ -z "$SSH_CLIENT" -a -z "$SSH2_CLIENT" ]; then + if [ "$SSHD_CHECK_IP" = "1" ]; then + echo_x "NX> 596 Session startup failed. (Missing SSH_CLIENT environment variable)" + return 1 + else + log "Warning: Failed to determine the client IP." + log "Warning: The SSH_CLIENT or SSH2_CLIENT variable was not provided by SSHD." + log "Warning: Please set SSHD_CHECK_IP=1 if you want to refuse the connection." + fi + fi + export ENCRYPTION=$encryption + if [ "$ENABLE_FORCE_ENCRYPTION" = "1" -a "$ENCRYPTION" != "1" ]; then + echo_x "NX> 596 Unencrypted sessions are not allowed." + exit_proc 1 + fi + + # check if there is a suspended session, which we could resume + if [ "$ENABLE_AUTORECONNECT" = "1" -a "$action" = "start" ]; then + restore=$(session_get_user_suspended "$user" "Suspended") + if [ -n "$restore" ]; then + session_id=$restore; action="resume" + fi + fi + + # as only $SSH_CLIENT or $SSH2_CLIENT will be set, this should work + userip=$(rematchfn "($ip4_pattern)" "$SSH_CLIENT $SSH2_CLIENT") #" + [ -z "$userip" ] && userip="*" + if [ "$action" = "start" -o "$action" = "shadow" ]; then + server_check_session_count || exit_proc 1 + + # Possibly do loadbalancing + server_host=$(server_loadbalance) + + # start nxnode + display=$DISPLAY_BASE + ((sess_display_limit=DISPLAY_BASE+DISPLAY_LIMIT)) + # stupid but working algo ... + + while true; do + while [ -e /tmp/.X$display-lock -o \ + -e "/tmp/.nX$display-lock" -o \ + -e "/tmp/.X11-unix/X$display" ]; do + ((display++)) + done + + # Check if there is already an agent running on that display on that host + ((agent_display=display+6000)) + if port_is_listening $agent_display "$server_host"; then + log "Warning: Stray nxagent without .nX$display-lock found on host:port $server_host:$agent_display." + ((display++)) + continue + fi + + ((proxy_display=display+4000)) + if port_is_listening $proxy_display "$server_host"; then + log "Warning: nxagent proxy without .nX$display-lock found on host:port $server_host:$agent_display." + ((display++)) + continue + fi + + # Now check for the other enabled services + ((samba_display=display+3000)) + if [ "$samba" = 1 ] && \ + port_is_listening $samba_display "$server_host"; then + log "Warning: Skipping $server_host:$agent_display as samba port is not free." + ((display++)) + continue + fi + + ((media_display=display+7000)) + if [ "$media" = 1 ] && \ + port_is_listening $media_display "$server_host"; then + log "Warning: Skipping $server_host:$agent_display as media port is not free." + ((display++)) + continue + fi + + ((cups_display=display+9000)) + if [ "$cups" = 1 ] && \ + port_is_listening $cups_display "$server_host"; then + log "Warning: Skipping $server_host:$agent_display as cups port is not free." + ((display++)) + continue + fi + + sess_lockfile=$(mktemp "/tmp/.nX$display-lock.XXXXXXXXX") + # ln is an atomic operation + ln "$sess_lockfile" "/tmp/.nX$display-lock" 2>/dev/null && break + done + + rm -f "$sess_lockfile" + if [ "$display" -gt "$sess_display_limit" ]; then + echo_x "NX> 596 Error: Display limit exceeded. Please remove some files from /tmp/.X*-lock." + rm -f "/tmp/.nX$display-lock" + exit_proc 1 + fi + + session_id=$(echo $[$RANDOM*$RANDOM] | $COMMAND_MD5SUM) + session_id=${session_id%% *}; session_id=${session_id^^} + params+="&user=$user&userip=$userip&session_id=$session_id&\ +display=$display&host=$server_host" + log_secure "$params" + + # now update the session listing + local time_now=$(date +%s) + session_add "session_id,user,session,display,status,userip,rootless,\ +type,screeninfo,geometry,host,shadowcookie,startTime,creationTime"\ + "$session_id&$user&$session&$display&Running&$userip&$rootless&\ +$type&$screeninfo&$geometry&$server_host&none&$time_now&$time_now" + else + [ -z "$(getparam "$params" "session_id")" ] && params+="&session_id=$session_id" + session_change "$session_id" "userip" "$userip" + db_params=$(session_get "$session_id"); + display=$(getparam "$db_params" display); + host=$(getparam "$db_params" host); server_host=$host + [ -z "$server_host" ] && server_host="127.0.0.1" + status=$(getparam "$db_params" status) + params+="&host=$server_host&user=$user&userip=$userip&display=$display&status=$status" + + if [ "$ENABLE_ADVANCED_SESSION_CONTROL" = "1" ]; then + case "$session" in + "add "*) + server_nxnode_start --applicationsession "$user" "$params" + echo_x "Quit" + echo_x "NX> 999 Quit" + exit_proc 1 + ;; + esac + fi + fi + + # now start the node + sleep $AGENT_STARTUP_TIMEOUT & + server_wait_pid=$! + ( server_nxnode_start_wait --"$action"session $user "$params" ) & + server_pid=$!; disown $server_pid + wait $server_wait_pid 2>/dev/null + if [ $? -eq 0 ]; then + # Something went wrong ... + [ "$action" = "start" ] && session_fail $session_id + echo_x "NX> 1004 Error: Session did not start." + echo_x "NX> 596 Session $action failed." + echo_x "NX> 999 Bye" + # FIXME: Send node signal to terminate + exit_proc 1 + fi +} + +# Session stage +trap "fl_send=1" SIGUSR2 +while true; do + [ "$fl_send" = "0" ] && { sleep 0.01s; continue; } + echo_x -n "NX> 105 " + unset cmd + read cmd 2>/dev/null + [ "$cmd" = "" ] && cmd="quit" # FIXME? + # Logging + case "$cmd" in + startsession*|restoresession*|addmount*|addprinter*) + echo_secure "$cmd"; log_secure "$cmd" + ;; + *) + echo "$cmd"; log "> $cmd" + ;; + esac + + case "$cmd" in + quit|QUIT) + echo_x "Quit" + echo_x "NX> 999 Bye" + exit_proc 0 + ;; + exit|EXIT) + echo_x "Exit" + echo_x "NX> 999 Bye" + exit_proc 0 + ;; + bye|BYE) + echo_x "Bye" 1>&2 + echo_x "NX> 999 Bye" 1>&2 + if [ "$ENCRYPTION" = "1" ]; then + ((proxy_display=display+4000)) + log "Session stage: proxy display starting $server_host:$proxy_display" + $COMMAND_NETCAT $server_host $proxy_display 2>/dev/null; rc=$? + log "Session stage: proxy display finished rc=$rc" + kill $PPID 2>/dev/null # kill our parent sshd process + exit_proc $rc + else + echo_x "NX> 1001 Bye." + fi + ;; + admin) + [ -n "$ugroups" ] || \ + { ugroups=$(groups "$user"); ugroups=$(trim "${ugroups#*:}"); } + if stringinstring " nxadmin " " $ugroups "; then + trap server_nxserver_exit_func EXIT + log "User '$user': admin mode starting" + LC_MESSAGES=C $COMMAND_SUDO -u $user -S -v -p "" <<< "$PASS" + $COMMAND_SUDO -u $user -H /bin/bash -c \ + '/usr/bin/nxnode --admin' + log "User '$user': admin mode stopping with rc=$?" + echo_x "NX> 1001 Bye." + trap EXIT + exit_proc 0 + else + log "User '$user': admin mode start failed" + echo_x "NX> 2004 admin mode start failed"; exit_proc 1; + echo_x "NX> 1001 Bye." + fi + ;; + startsession*) + fl_send="0"; in_params=$(server_get_params $cmd) + set_vars_from_ampstr "$in_params" # set global vars without prefixes + server_startrestore_session "start" "$in_params" + ;; + list*) + # used: user,status, type, screeninfo == geometry ??? + in_params=$(server_get_params $cmd) + set_vars_from_ampstr "$in_params" "in_" + if [ "$in_status" = "Suspended" -a -n "$in_screeninfo" ]; then + session_list_user_suspended "$in_user" "Suspended" \ + "$in_screeninfo" "$in_type" + elif [ "$in_status" = "Suspended,Running" -o "$in_status" = "Suspended" ]; then + # disabled due to problems with 1.4.0-5 client + #session_list_user_suspended "$user" 'Suspended$|^status=Running$' "$(getparam geometry)" "$(getparam type)" | log_tee + session_list_user_suspended "$in_user" \ + 'Suspended' "$in_geometry" "$in_type" + elif [ "$in_status" = "suspended,running" -o "$in_status" = "suspended" ]; then + # since 1.5.0 + [ "$ENABLE_SHOW_RUNNING_SESSIONS" = "0" ] && in_status="Suspended" || { + in_status=${in_status/,/|} + in_status=${in_status/suspended/Suspended} + in_status=${in_status/running/Running} + } + session_list_user_suspended "$in_user" "$in_status" \ + "$in_geometry" "$in_type" + elif [ "$in_type" = "shadow" ]; then + session_list_user_suspended ".*" "Suspended|Running" "" "shadow" + else + session_list_user "$in_user" | log_tee + fi + ;; + suspend*) + # used: user, session_id + in_params=$(server_get_params $cmd) + set_vars_from_ampstr "$in_params" + [ -z "$display" ] && \ + display=$(q_vals_str_get "sess" \ + "session_id='$session_id'" "display") + in_params+="&display=$display" + if session_find_id_user "$session_id" "$user"; then + server_nxnode_start --suspend "$user" "$in_params" + fi + ;; + terminate*) + in_params=$(server_get_params $cmd) + set_vars_from_ampstr "$in_params" + [ -z "$display" ] && \ + display=$(q_vals_str_get "sess" \ + "session_id='$session_id'" "display") + in_params+="&display=$display" + if session_find_id_user "$session_id" "$user"; then + server_nxnode_start --terminate "$user" "$in_params" + fi + ;; + restoresession*) + fl_send="0"; in_params=$(server_get_params $cmd) + set_vars_from_ampstr "$in_params" + [ -z "$display" ] && + display=$(q_vals_str_get "sess" \ + "session_id='$session_id'" "display") + in_params+="&display=$display" + server_startrestore_session "resume" "$in_params" + ;; + attachsession*) + in_params=$(server_get_params $cmd) + set_vars_from_ampstr "$in_params" "in_" + server_startrestore_session "shadow" "$in_params" + ;; + addmount*) + in_params=$(server_get_params $cmd) + set_vars_from_ampstr "$in_params" "in_" + in_params+="&display=$display" + ( server_nxnode_start --smbmount "$user" "$in_params" >/dev/null 2>&1 ) & + ;; + addprinter*) + in_params=$(server_get_params $cmd) + set_vars_from_ampstr "$in_params" "in_" + in_params+="&display=$display" + ( server_nxnode_start --addprinter "$user" "$in_params" >/dev/null 2>&1 ) & + ;; + *) + # disabled for 1.4.0-5 snapshot client + #echo_x "NX> 503 Error: undefined command: '$cmd'" + ;; + esac +done +trap - SIGUSR2 + +fi # server_mode == "1" + +# +# End of Main nxserver <--> nxclient communication module +# + +################### PACKAGE cmd.bm ############################ + +# +# library functions for nxserver-commandline cmds +# + +# Policy: All functions and variables need to start with CMD_ / cmd_ +# Needed global vars: $NX_VERSION, $NX_LICENSE, $NX_ETC_DIR, $PATH_BIN, +# $NX_HOME_DIR, $SSH_AUTHORIZED_KEYS +# Needed package: passdb +cmd_usage() { + echo "NXSERVER - Version $NX_VERSION $NX_LICENSE" 1>&2 + echo "Usage: nxserver