How can I offer options to save data to a user from an rpm? - linux

I deliver an application via an RPM.
What I need to do is if the user uninstalls the application (rpm -e) to get a chance to do a back up of some the files that are part of the application installed.
Additionally on (post) installation I want the user to get a chance to replace some of the installation's files with the ones that he saved during a previous uninstall.
To do this I thought to make an interactive RPM.
But it did not work. Googling I found that some of the commands e.g. read are ignored in an RPM spec somehow and additionally the idea to get interactive input
from a user is frowned upon and not recommended.
My question is, am I really following a wrong approach here? Should I be doing it differently? How? I can't think of another solution on this specific problem.
Any help?

Interaction with the user while un/installing RPM is not a good practice. The philosophy behind it is that RPMs should able to be un/installed automatically, for example, when installed via YUM. If you must, you have several options:
Best: Create a script that get all information from the user, and write it to a file. In the RPM prerequisites, verify that the file exists.
Optional: Embed the RPM within a bash script that interacts with the user, extracts the RPM and run it. I believe Java RPM does it to let you accept the EULA.
Not a good idea: I have read somewhere that RPM reads from /dev/tty so you can try to add exec 0</dev/tty in the beginning of the %pre or %post

Related

Configuring Bash Script to work on other people's computers

I've created a bash script that I'd like to share for other people to use
The script downloads video files, stores them in appropriate folders (which are essential to the app) and allows the user to cycle between them, using getopts so the user can send specific commands via flags
I've never done this before so I'm unsure of what "configuration" requirements I'd need to have so it works on other peoples computers. I want them to be easily able to download using homebrew or another package manager, automatically set up the required components and have them be able to use it
I know I have to create folders and a man page for them at the appropriate location. Does this require a makefile?
What other things should I be considering? My google search skills are sucking, so any links would be much appreciated
Package a precompiled busybox (https://busybox.net/downloads/binaries/latest/) next to your script, and use busybox functions only.

setting up cygwin via the GUI

I have a standalone server running Cygwin -- I did not setup this server, it was inherited. Anyway, I'd like to know what options the installing admin selected in the setup program.
I've read that I could look in /etc/setup, /etc/postinstall, or /etc/preremove but there are a lot of packages in those directories... same goes for the output of cygcheck -c.
I don't want to know every single library on the system... just how to duplicate the install. Is there a way to determine which packages were select in the GUI setup program?
Thanks!
Cygwin is pretty standalone. You should be able to archive up the entire Cygwin directory (and subdirectories) and move it to the same location on another system.
If you archive it up I recommend 7-zip. You can get it free here. The built in Windows archiver can create permission problems when an archive is extracted on a destination system. I recommend 7-zip for both archiving and unarchiving. If you use the built in Windows archiver and then move it to the new system and extract it - it will extract without errors. However you may find things don't actually work right while using some Cygwin applications
If you don't copy everything you won't move any of the original admin's custom changes.

CentOS/auditd: file creation at directory to trigger a script

I need to audit the directory and call a script with the file-path parameter as the file is created there. Reading the man of auditctl i can't find a way to do it.
There're references in the web to inotify or iwatch services, that should do what i need, but i'd rather use the standard auditd functionality not installing an extra software.
If that's really not possible to use auditd to track the file creation and call the script for that file, a short sample of iwatch/inotify command to do the trick will be appreciated and accepted.
For the CentOs environment pyinotify module was used which handles directories watch pretty well and triggers the desired scripts.
Unfortunately i wasn't able to find solution using pure auditd.
The list of examples of how do someone use pyinotify is here.

Double-click installer in Ubuntu?

I'm trying to update our installer so a user can simply double-click on a file and have all the dependencies and our software installed easily. This is a suite of applications that will are deployed on a clean UbuntuĀ 8.04 (Hardy Heron) installation. I have investigated making a .deb file, but listing the dependencies doesn't work, because there isn't any Internet access available. And, any script that would set up a local APT repository would still need to be run from the command line. Is there a way to put a .deb file inside of a .deb file?
I know many companies ship shell scripts that you have to chmod +x, and then execute. This is not acceptable. It is ridiculous that this isn't possible; especially considering the distribution and architecture is fixed.
If you are totally confident that it will be installed on the same system every time, you can find the list of package dependencies yourself, fetch them from the Ubuntu repositories, and package them up with your software. You just have to be clear that your software is for a specific version, probably deal with things like keeping up with maintenance releases.
You can also easily install with a script. As for your complaint about making scripts executable, well, I don't know how you're shipping your product, but since you say it's going somewhere without Internet access, I assume it's going to be copied from some kind of media. If you make the script executable when you put it on that media, you're done.
If you'd like to do this using packages, you can create a CD-ROM which contains a package repository. You can find all kinds of information on this with Google Search. For starters, try this - it's a GUI for doing it. http://aptoncd.sourceforge.net/
A makeself self-extracting executable that starts the install script using sudo will work.
The user can either run it from a terminal (after chmod-ing it) or can double-click it and tell it to "Run" from the prompt.
It's possible to put deb-files into deb-files. The only thing you need to do is to configure the appropriate scripts.
A .deb-file consists of:
1x control.tar.gz: contains a file "control" (describes the package) and optional files like "postinst" (script executed right after extraction). There are other files you might include, and Google Search should deliver information about the available scripts.
1x data.tar.gz: contains some structure of root-filesystem which contains files/folders that need to be (re-)placed. Additionally, you may configure the behaviour in the mentioned scripts.
1x debian-binary: as far as I remember, this is simply a version number in a file. I don't know exactly what it means; just remember that in most of the cases this is 2.0.
So you now may put your .deb files in the data-package. Those are extracted by your script... and installed using:
# dpkg -i yourpackage1.deb yourpackage2.deb

Escalating privileges on linux programmatically

I am creating a graphical installer that should run on Linux. Installing should consist of copying files to some places in /usr. Currently the installer is written in Python.
How can I escalate the privileges of my installer when I need to copy files? I looked at PolicyKit but
a) there doesn't seem to be a generic "install files" action-id for PolicyKit
b) of the action ids I can use, I don't think they are standard across distros
I also looked at PAM and I have code that uses libpam but I can't seem to do anything with it. After authenticating my user (by providing username and password) I don't have write access to /usr. I tried changing my user with os.setuid(0) after authentication but I get an error from the OS.
Also, strangely, it doesn't seem to matter what service I provide to pam_start. As long as the username and password are correct I can pass anything I want. I see I have /etc/pam.d/sudo. The below code is simplified, the password is correctly stored in a pam_conversation object and I do pass a handle object.
pam_start("my_user", "my_pass", "sudo_garbage_12345");
works just as well as
pam_start("my_user", "my_pass", "sudo");
That is, they both succeed.
As a last resort I can probably execute gksudo or kdesudo but I don't want to be tied to those programs. Requiring users to invoke my installer with sudo is a (very) last resort.
You might be better off wrapping RPM with a front end that takes the user options and invokes RPM to do the hard work. This also gives you infrastructure for managing dependencies and plays nicely with the existing package management system. If you need to run on a .deb based system (Debian or Ubuntu) you may also need to consturct a .deb and put some mechanism in the front end that works out which package management system is active.
Granting random users access to root privilege is generally viewed as bad form on Linux or Unix systems (or any multi-user system for that matter) as it is a significant security risk. However you do have the option of letting the user install it under their home directory (~/bin) if they don't have root access or sudo permissions that allow them to write to system areas. In this case you can require them to install it as root if they want to install in /usr/bin but permit them to install it under their home directory for their own use if they don't have root privileges.
For a graphical installer, stick with a graphical environment. Use gksudo or kdesudo if they are available, otherwise fail with an error dialog saying they need root. People (newbies in particular) will download your installer and double-click to launch it from their desktop, and you need a graphical way to ask them for their password. You don't want to pop open a terminal on them.
Given that, don't do sudo for them even if they are running from the terminal. Just output an error saying you need root and exit. If the user is already at the command prompt (like I most likely would be), I already know how to sudo or su myself into root if I want to do so. I promise you you will most likely ruffle some feathers if you attempt to make an experienced user root when they can do it themselves.
If you INSIST on doing a sudo yourself from within your installer, for God's sake please force a 'sudo -K' before you do to remove the previous timestamp. If you don't do this, and I have sudo'd recently, you will run your installer with me as root without my knowledge (since I don't expect that to happen). A 'sudo -K' will force a prompt that I can then decide whether I want to proceed as root or not.
The best way in this case is to use su within your program. Redirect inputs/outputs and you're good to go!

Resources