So I run this command on Linux from user account named 'x':
sudo dotnet App.dll
And App.dll does:
File.WriteAllText("App.txt", "Text");
This file is not write accessible to 'x' or normal users. It's owned by root. How can I write it so it's not a root user file but while running from sudo? I know I can grant access/ownership to a username to the file, but what do I do if I don't know the username's name is 'x'?
I have very little knowledge of Linux. I'm just writing a simple tool that configures some files. It needs to write some root-owned files but also some user-owned files.
I'm not even sure my question makes sense. I want to write a file without the (locked) icon overlay from sudo app execution.
After more furious googling I found that I can get the User's that invoked sudo UID and GID by running:
env | grep SUDO
or via C#:
var groupId = int.Parse(Environment.GetEnvironmentVariable("SUDO_GID"));
var userId = int.Parse(Environment.GetEnvironmentVariable("SUDO_UID"));
var user = Environment.GetEnvironmentVariable("SUDO_USER");
So I can execute:
chgrp GID File.txt
chown UID File.txt
or Process.Start using /bin/bash -c "command":
var command1 = $"chgrp {groupId} Test.txt";
var command2 = $"chown {userId} Test.txt";
to give the file to the User that launched sudo dotnet App.dll.
Related
I have an application built in C# .dotnet 6 on macos.
I want the application to be able to seamlessly update itself.
It's downloads the latest pkg and my problem is how I run it.
I want to start this process using "sudo installer -pkg /tmp/mypackage.pkg -target /" but sudo ask for password on the standard input.
How can I start a process with escalated privileges where the user permissions are asked first through something like:
You can use AppleScript to create a graphical authentication prompt:
#!/bin/sh
osascript -e "do shell script \"$*\" with administrator privileges"
Other methods: Is there any graphical "sudo" for Mac OS X?
You could try the option -S of sudo for accepting the password from standard input. After use echo password and | to pass the password to the command:
echo myPassword | sudo -S installer -pkg /tmp/mypackage.pkg -target
I'm trying to update an app remotely. All devices are rooted.
Due to the nature of the apps and devices, there are no users, the devices monitor a range of sensors and send the info back to a server from key locations.
I know that
"pm install -r app.apk\n"
will install a downloaded apk.
But how would I get it to run without a user.
Once this command executes the app stops and all it's services stop aswell.
So is there a command to install + run ?
am start -n com.package.name/com.package.name.ActivityName
does not get executed and wont start the services because this code is not reached after the install command
edit:
this is the code once the apk is downloaded
dataOutputStream.WriteBytes("mount -o rw,remount -t /system\n");
dataOutputStream.Flush();
dataOutputStream.WriteBytes("chmod -R 777 "+localPath+"\n");
dataOutputStream.Flush();
dataOutputStream.WriteBytes("mount -o ro,remount -t /system\n");
dataOutputStream.Flush();
dataOutputStream.WriteBytes("pm install -r "+localPath+"\n");
dataOutputStream.Flush();
//The code below is not reached because the install kills the app
dataOutputStream.WriteBytes("am start -n com.company.remote/com.company.remote.RebootServices\n");
dataOutputStream.Flush();
Whenever you install an app through Android Studio, it installs your app and launches it immediately afterwards. By looking into the commands it executes, I have found the following line, it might help you:
adb shell am start -n "com.package.name/com.package.name.ActivityName" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Notice the intent filter flags: -a for "action" and -c for "category" as defined in manifest. If you have an intent filter, you can use those too.
EDIT: After reading the comment of SushiHangover, this is indeed a duplicate of this question: https://stackoverflow.com/a/4567928/3673616
According to the answer from there, instead of am start[...] you need to use adb shell am start[...]
For some reason, I can't seem to launch and run a .cmd file with c#. An example of a line of the cmd file is:
"C:\Windows\system32\ffmpeg64.exe" -v verbose -y -i "S:\TEMP\A.ts" -c:v copy -c:a copy -ss 00:00:00.000 -t 2 "S:\TEMP\A_SHORT.ts"
I've tried several different ways to launch this file from within C#, such as (where curDirectory is for example "S:\TEMP")
Process p = Process.Start(curDirectory + "\\ffmpeg.cmd");
I've also tried
string path = curDirectory + "\\ffmpeg.cmd";
Process p = Process.Start("cmd.exe", #"/c " + path); //I've also tried /k
But what happens is the cmd prompt will show up and say "C:\Windows\System32\ffmpeg64.exe" is not recognized ..." even though the file is there. What am I doing wrong?
If your system is running the Windows 6.1 kernel or later, System32 is actually comprised of other directories based on the application you're running (depending on whether it is a 32-bit or 64-bit application).
I assume that ffmpeg64.exe is a 64-bit application, and when you execute the .cmd file manually, it should default to a 64-bit command prompt - Also ensure that your application is targeting "x64" or "Any CPU". Alternatively, you could place a 32-bit version of ffmpeg in the WoW64 directory.
Also, I know you've stated in comments that you don't want to read the .cmd file and modify it, but you could compose your ProcessStartInfo with Environment.SystemDirectory instead of the hard-coded path.
As a last option, you could place the ffmpeg exe somewhere static (as you stated in the comments, in c:\ works), or just in your application's working directory.
I have a batch file I wrote (proof of concept) to install a sample service I also created. It contains the following command line:
sc create serviceTest binPath= C:\Sandbox\ServiceTest\ServiceTest.exe DisplayName= "Service Test"
When I right click and select 'Run as Administrator' everything runs as expected. Running the batch file without doing this gives 'Access Denied'. This is proof that the command works.
I have also tried running the sc command via Process.Start():
const string sc = #"sc";
const string arguments = #"create serviceTest binpath= {0} DisplayName= ""Service Test""";
FileInfo fi = new FileInfo(this.txtServiceLocation.Text);
if (fi.Exists)
{
ProcessStartInfo psi = new ProcessStartInfo()
{
FileName = sc,
Arguments = string.Format(arguments, fi.FullName),
UserName = "admin",
Password = "secret".ToSecureString(),
Domain = "MYDOMAIN",
WorkingDirectory = fi.DirectoryName,
CreateNoWindow = true,
UseShellExecute = false
};
Process.Start(psi);
}
else
MessageBox.Show("The service exe could not be found.");
I need to be able to do this programatically. What do I need to do to get this to work?
CLARIFICATION: I need to be able to do this without a user being prompted. This code will be running under a custom tfs build process.
In Windows 7 by default, runs most applications with least privilege access (non-admin) control. As your application is trying to modify the system, it needs to be elevated to Admin privilege in order to run successfully. If you want to make this app to run in admin privilege permanently, please follow the instructions as in the link
http://www.groovypost.com/howto/microsoft/automatically-run-any-application-as-admin-in-windows-7/
You need to add a UAC manifest file to your assembly in order to force UAC to run the process as an administrator. For a reference to other solutions, you can see UAC need for console application.
While I never got this to work I can still use impersonation via code and also ensure that the tfs build account has appropriate access. This is what I had to do.
I've need to add a function to my C# WPF application to fix up certain registry entries.
This would be done by calling regsvr32.exe /s mylib.dll. Now, this should be easy to do from what I see using the runas verb with a new Process object. (My dll does require admin rights due to some registry keys it writes to.)
But the problem is there are multiple DLLs, thus multiple invocations of regsvr32.exe, and it is not possible to put all the registrations into a single .dll. But were I to just runas multiple times, the user would get as many UAC dialogs as I start it... and I don't want that.
I want just a single dialog, and I really really want to avoid having a mystery extra fixer.exe file to have to do the launching instead. Now, I only know Windows Security stuff on a really basic level, but shouldn't it be possible to get an 'admin' token somehow (which gets me the UAC dialog) and use that to launch the different processes?
You can just use command line arguments, and shell to your own .exe running that process as an admin. When your application loads, check for those command line arguments...If they are there, register all of your dlls, then exit.
Or, you could write a batch file that registers all of the dlls, and shell to that with admin rights.
The issue here is security. You have three options:
Create a service account and run the application with service account privileges.
Prep the target machines that the application will run on with some sort of install package.
Use powershell to invoke regsvr32.exe with admin rights ->
function Run-Elevated ($scriptblock)
{
# TODO: make -NoExit a parameter
# TODO: just open PS (no -Command parameter) if $sb -eq ''
$sh = new-object -com 'Shell.Application'
$sh.ShellExecute('powershell', "-NoExit -Command $sb", '', 'runas')
}
I would opt for option 2, as registering dll's are more than an installation step. The registering of the dll crosses the boundary of the account privileges needed to run the main application. If your app is running on a domain environment an MSI could be rolled out to prep each machine?
If you want only one single UAC prompt, there is already an answer at Stackoverflow, look here.
This script elevates itself once, and you can execute a sequence of commands which all need elevated rights, so you don't get multiple UAC prompts anymore.
In your case, this means you can just append the invokations of
regsvr32.exe /s mylib1.dll
regsvr32.exe /s mylib2.dll
regsvr32.exe /s mylib3.dll
at the end of the script mentioned above, i.e.
:::::::::::::::::::::::::::::::::::::::::
:: Automatically check & get admin rights
:::::::::::::::::::::::::::::::::::::::::
#echo off
CLS
ECHO.
ECHO =============================
ECHO Running Admin shell
ECHO =============================
:checkPrivileges
NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )
:getPrivileges
if '%1'=='ELEV' (shift & goto gotPrivileges)
ECHO.
ECHO **************************************
ECHO Invoking UAC for Privilege Escalation
ECHO **************************************
setlocal DisableDelayedExpansion
set "batchPath=%~0"
setlocal EnableDelayedExpansion
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%temp%\OEgetPrivileges.vbs"
ECHO UAC.ShellExecute "!batchPath!", "ELEV", "", "runas", 1 >> "%temp%\OEgetPrivileges.vbs"
"%temp%\OEgetPrivileges.vbs"
exit /B
:gotPrivileges
::::::::::::::::::::::::::::
:START
::::::::::::::::::::::::::::
setlocal & pushd .
REM The following code will cause Windows UAC to prompt only once
regsvr32.exe /s mylib1.dll
regsvr32.exe /s mylib2.dll
regsvr32.exe /s mylib3.dll
and the UAC dialog will only appear once.