terminal commands and permissions, specifically mount lazarus / 32-Linux ---------------------------------------------------------------------- andyH · 2020-03-03 17:15 Got an app that uses a lot of terminal commands, some like parted and mount require root privileges to run. They are executed through a procedure I've written, termcmd, that executes bash with the command line passed to it (why bash - use a fair number of pipes, |, and it's easier this way). For those commands that require root privileges they are executed as pkexec command (with a polkit for every command needing one). All is fine. Now want to run myapp as root, i.e. pkexec myapp or sudo myapp. Shouldn't need to embed pkexec in the code, right? Wrong! Works with parted, not with mount (the only two I've tried out of many). I've now coded the exec command directly into my mount procedure and no difference, code snippet below, for example to execute mount -r /dev/sda1 /media/myfolder/sda1 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   mntProcess:= TProcess.Create(nil);  with mntProcess do       begin       Executable:= '/bin/mount';         Parameters.Add('-r');         Parameters.Add('/dev/' + partition);         Parameters.Add(MountFolder + partition);         Options:= [poUsePipes,poStderrToOutPut]; //no difference with stderr and no poStderrToOutPut         writeln(Executable,' ','r',' ','/dev/' + partition,' ',MountFolder +partition);         Execute; //run       end;  writeln('after termcmd...');  BytesRead:= mntProcess.output.Read(buffer[1],length(buffer));  <---- hangs here  writeln('after bytesread...');                               <---- never reachedmount is executed, sda1 gets mounted but the code never returns from BytesRead:=. I've tried all combinations, reading stderr and/or stdout, increasing the size of the buffer, putting bytesread in a repeat loop until bytesread = 0 to make sure it is all read. Nothing makes any difference. The only thing that does work is back to what I had before: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Executable:= '/bin/bash';Parameters.Add('pkexec mount restofthecommandline'); Am I doing something stupid or is this a bug? ---------------------------------------------------------------------- sash · 2020-03-03 17:40 Just a suggestion. PipeStream behavior could differ from other streams. Try to inspect NumBytesAvailable before read it. ---------------------------------------------------------------------- MarkMLl · 2020-03-03 17:44 The stupid thing that you're not doing is telling us whether this is a console program or a GUI one written using the LCL, and how you're trying to run and debug it. Over the last few weeks I've been doing quite a lot with POSIX capabilities (so that I could create a unix domain socket in /var?run or listen to a UDP port below 1024) and as soon as I tried running with a debugger the capabilities were ignored: I either had to use resources that didn't require the additional capabilities during debugging (socket in ~ or port >>1024) or use "old school" debugging output. MarkMLl ---------------------------------------------------------------------- winni · 2020-03-03 18:27 Hi! Without the rest of the code some things are not quiete clear. BUT: the error seems to be here: Parameters.Add(MountFolder + partition); The partition is needed for the source. This is done right. But the destination only needs the mountFolder - including the path. Winni ---------------------------------------------------------------------- andyH · 2020-03-03 19:08 QuoteThe stupid thing that you're not doing is telling us whether this is a console program or a GUI oneGUI and my bad, shouldn't run a GUI program with sudo, poor example! Can't test inside lazarus (unless you want to run it as root) so I've been compiling and then from a terminal executing through a script that has 'pkexec myapp' with a polkit defined for myapp. Debugging has been writeln's to find out where in the code it is hanging. EDIT - I haven't turned off any of the debugging code that lazarus builds into the executable as 'standard'. ---------------------------------------------------------------------- winni · 2020-03-03 19:12 I  told you. The code hangs at execute. ---------------------------------------------------------------------- andyH · 2020-03-03 19:13 Quote from: winni on March 03, 2020, 07:27:33 pmWithout the rest of the code some things are not quiete clear. BUT: the error seems to be here: Parameters.Add(MountFolder + partition); The partition is needed for the source. This is done right. But the destination only needs the mountFolder - including the path. Winni The rest of the code is some +3000 lines. I think you misunderstood, as an example what it is supposed to be doing is mount -r /dev/sda1 /media/myfolder/sda1 the code previously creates the folder /media/myfolder/sda1 successfully. I'm deliberately using the partition reference in the mount point to keep track of things. ---------------------------------------------------------------------- andyH · 2020-03-03 19:20 Quote from: winni on March 03, 2020, 08:12:03 pmI  told you. The code hangs at execute. It may well be hanging here, if so why, but the following statement gets executed - writeln('after termcmd...'); It also executes 'successfully' in that the partition does get mounted (I have to go and manually unmount it after the program has hung) ---------------------------------------------------------------------- andyH · 2020-03-03 19:30 Quote from: sash on March 03, 2020, 06:40:11 pmJust a suggestion. PipeStream behavior could differ from other streams. Try to inspect NumBytesAvailable before read it. Thanks, I'll have a look at that. EDIT - having had a quick google, thanks, wasn't aware that existed. May not help with the current issue, but I can change my termcmd procedure into a function returning NumBytesAvailable to save reading output if none available and reading NumBytesAvailable instead of looping until there is nothing left to read. ---------------------------------------------------------------------- winni · 2020-03-03 20:17 Hi! Did you u(n)mount /media/MyFolder/sdaX ??? Winni ---------------------------------------------------------------------- MarkMLl · 2020-03-03 20:36 Quote from: andyH on March 03, 2020, 08:08:31 pmGUI and my bad, shouldn't run a GUI program with sudo, poor example! Almost every system has at least one GUI program running with root privilege: the display manager. Running setuid root is far more problematic, if for no reason other than that gtk2 explicitly doesn't allow it. QuoteCan't test inside lazarus (unless you want to run it as root) so I've been compiling and then from a terminal executing through a script that has 'pkexec myapp' with a polkit defined for myapp. Debugging has been writeln's to find out where in the code it is hanging. I don't think that anybody- or at least anybody in their right mind- is happy with the idea of running the full Lazarus IDE as root. But if one really does need to debug as root and isn't intimately familiar with gdb... MarkMLl ---------------------------------------------------------------------- sash · 2020-03-04 08:33 Quote from: winni on March 03, 2020, 08:12:03 pmThe code hangs at execute. But according to code comments, line 12 has worked out. ---------------------------------------------------------------------- andyH · 2020-03-04 09:57 Quote from: winni on March 03, 2020, 09:17:18 pmHi! Did you u(n)mount /media/MyFolder/sdaX ??? Winni The overall process that myapp (it's a linux image backup/restore/clone program) follows on startup is: run parted to find all drives/partitions in the system and basic info - size, part table type, part type.check if partitions are already mounted, if not create mount folder and mountrun df on every known partition type to get total blocks and used blocksrun blkid to get part labels if they existif myapp mounted the partition, unmount and remove mountfoldermain menuThe reason I'm looking at running myapp as root is if a linux newbie takes a new drive, puts a partition on it and tries to use it as a backup destination it will fail - the partition is owned by root. Problem found by one of my volunteer testers. Latest version of myapp checks for this and raises a warning, but still potentially confusing for a linux newbie. Hence looking at running myapp as root which will overcome this. If running as root, then I shouldn't need to embed pkexec in the code for all the terminal commands that need root privilege - which is where the problem arose. It will work, running myapp as root and leaving all the embedded pkexec commands in the code, but this feels like double counting. Since I have a solution/workaround, my question is more academic. My pascal experience is over 30 years on and off (started with turbo pascal V1 under CP/M), my experience with lazarus is one year, so I raised this topic just in case my limited lazarus knowledge had caused me to miss something. ---------------------------------------------------------------------- MarkMLl · 2020-03-04 10:56 Quote from: andyH on March 04, 2020, 10:57:44 amThe reason I'm looking at running myapp as root is if a linux newbie takes a new drive, puts a partition on it At some point you have to say "do I really want to give an inexperienced user this degree of control? (Written with the benefit of >40 years experience, including commercial data processing.) MarkMLl ---------------------------------------------------------------------- eljo · 2020-03-04 11:29 Quote from: MarkMLl on March 04, 2020, 11:56:14 amQuote from: andyH on March 04, 2020, 10:57:44 amThe reason I'm looking at running myapp as root is if a linux newbie takes a new drive, puts a partition on it At some point you have to say "do I really want to give an inexperienced user this degree of control? (Written with the benefit of >40 years experience, including commercial data processing.) MarkMLl to his disk? You are kidding right? ---------------------------------------------------------------------- MarkMLl · 2020-03-04 11:33 I never joke. MarkMLl ---------------------------------------------------------------------- lucamar · 2020-03-04 11:41 Quote from: MarkMLl on March 04, 2020, 11:56:14 amQuote from: andyH on March 04, 2020, 10:57:44 amThe reason I'm looking at running myapp as root is if a linux newbie takes a new drive, puts a partition on it At some point you have to say "do I really want to give an inexperienced user this degree of control? They have it already. Take, for example, the case of Ubuntu (and lots other distros); the root account is "locked" by default and normal users access root capabilities by elevating privileges (more or less) through gksu or other means. The thing is that they can execute whatever by simply entering their own password, so there is little to prevent them from running, say, gparted to initialize a newly bought disk. And there is nothing you can do to prevent it from your own application: it's a system-wide issue. Regarding the OP's original problem, try adding poWaitOnExit to the process options; otherwise you might be trying to read the output before the process even starts executing: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  mntProcess:= TProcess.Create(nil);  with mntProcess do    begin      { ... }      Options:= [poWaitOnExit, poUsePipes,poStderrToOutPut];    { ... }    end; ---------------------------------------------------------------------- MarkMLl · 2020-03-04 11:55 Quote from: lucamar on March 04, 2020, 12:41:19 pmThey have it already. Take, for example, the case of Ubuntu (and lots other distros); the root account is "locked" by default and normal users access root capabilities by elevating privileges (more or less) through gksu or other means. Yes, but somebody's decided that specific users are to be on the sudoers list, are not to be locked out by a password-protected login screen and so on. That's very much distinct from saying "because an arbitrary user can click on this program, he automatically is able to screw the system: whether or not he understands the consequences". Don't get me wrong: I'm as enthusiastic about the "it's my computer and I'll pry if I want to" philosophy as anybody. But after being (peripherally) involved with an office where the receptionist had opened- and saved- c:\command.com with a word processor, and with somebody who was taken to court for selling an ISA bus modem card without telling the purchaser that it was advisable to power the computer off before plugging it in, I also believe that asking "is this user qualified to perform this operation" is in order. MarkMLl ---------------------------------------------------------------------- taazz · 2020-03-04 12:21 Quote from: MarkMLl on March 04, 2020, 12:55:04 pmQuote from: lucamar on March 04, 2020, 12:41:19 pmThey have it already. Take, for example, the case of Ubuntu (and lots other distros); the root account is "locked" by default and normal users access root capabilities by elevating privileges (more or less) through gksu or other means. Yes, but somebody's decided that specific users are to be on the sudoers list, are not to be locked out by a password-protected login screen and so on. That's very much distinct from saying "because an arbitrary user can click on this program, he automatically is able to screw the system: whether or not he understands the consequences". it is far safer to allow the application manage what ever needs to be managed than forcing the user to "learn" linux incantations to do his job. that way the application will only do the absolutely minimum required. Now having said that... Quote from: MarkMLl on March 04, 2020, 12:55:04 pmDon't get me wrong: I'm as enthusiastic about the "it's my computer and I'll pry if I want to" philosophy as anybody. But after being (peripherally) involved with an office where the receptionist had opened- and saved- c:\command.com with a word processor, and with somebody who was taken to court for selling an ISA bus modem card without telling the purchaser that it was advisable to power the computer off before plugging it in, I also believe that asking "is this user qualified to perform this operation" is in order. MarkMLl Just because some one is stupid enough to sue some one else for his own ignorance doesn't make you right to treat everyone else as an idiot. ---------------------------------------------------------------------- lucamar · 2020-03-04 12:54 Quote from: MarkMLl on March 04, 2020, 12:55:04 pmYes, but somebody's decided that specific users are to be on the sudoers list, are not to be locked out by a password-protected login screen and so on. That's very much distinct from saying "because an arbitrary user can click on this program, he automatically is able to screw the system: whether or not he understands the consequences". Yes, but "somebody" in this case are the distro maintainers, who cater only to the most frequent use. Note that we're not talking about enterprise-level installations, which sould be done by a person (whether administrator, IT drone or whatever) with the proper know-how, but common "home" installations, where the user and the admin are one and the same (which is what leads to, at least, the first user added to have root rights). I'm saying nothing about whether this is an ideal situation or not, just what the current one is. And it is that in most default intallations the (frequently unique) user can obtain root privileges by simply typing his own password. And that's, in fact, how most people like it, rather than having to log-in as root or the system asking about your right to do anything; witness the debacle of the UAC prompts in Windows Vista Anecdotical, but note that protecting that c:\command.com would have been as easy as making it system, hidden and read-only, which should have been done by the person installing that secretarial computer. But then, DOS offers little protection against mishaps which is why there was such a flowering of "recovery" tools in that era. I remember a much worse case, and the blunder made by myself. I'd started working as (system) programmer for a software house using Prologue (a french MT/MU OS) and I was drafted to make a demo in a hope-to-be customer; the computer for the demo was a DOS one used, basically, for Lotus 1-2-3. I went there and, happily, deleted the DOS partition (after asking if they had backup, of course; I was not so green) and installed Prologue to demo our program. You can guess what happened: at the end I reinstaled DOS and tried to reinstall everything else, which went well ... except, of course, for Lotus 1-2-3, which had just one installation left (and would leave them without "backup" install). We ended having to buy them a new Lotus, and I was severely scolded. ---------------------------------------------------------------------- andyH · 2020-03-04 17:45 While drifting off thread, think I read somewhere that windows assumes you are stupid, linux requires you to prove it. You can't stop users messing with their system, but at least you can force them to do it consciously with sudo (it's part of the learning process). Hence my backup app. Not be be confused with the likes of timeshift, backintime, lucky backup, et al. at the file level. When I first started I found clonezilla intimidating - you could call the UI user hostile. I used redo - simple, but not touched since 2012. Decided about a year ago to do a replacement - image backup with a simple point and click GUI. I'll have a look at poWaitOnExit and see what happens, but can't use that throughout. Guts of the program is using partclone for partition backup/restore and I'm reading that continuously to update the user on % complete and time remaining as it runs.