How to change a users password in Linux using C#

Viewed 342

Following scenario:

  • I do have sudo permissions
  • I know the old and new password of a user

Now I want to write a C# .NET 6 application which can change the password of the user. In Linux I would just call

sudo passwd username

My first idea was to create a new process, redirect the stdin and write the password there.
Another option would be to create a bash script and call it from C# (also using a new process).

However, both seem a little bit hacky to me. Is there any option to change the password in-process in C#?

2 Answers

Something along these lines should work properly if you already have the linux shell script.

   if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)){    
        var ShellScriptPath =  $"-c '{ShellScriptPath } &>> {OutputTextFilePath}'";
        var fileInfo = new FileInfo(ShellScriptPath);
        var startInfo = new ProcessStartInfo
        {
           CreateNoWindow = true,
           RedirectStandardOutput = true,
           RedirectStandardError = true,
           UseShellExecute = false,
           FileName = "/bin/bash",
           WindowStyle = ProcessWindowStyle.Hidden,
           Arguments = fileInfo.FullName,
           WorkingDirectory = WorkingDirectoryPath,
        };
        
        using Process process = Process.Start(startInfo);
        process.WaitForExit();
        process.Dispose();
    }

Program.cs

class PasswordChanger
{
  static void Main(string[] args)
  {
    string password = args[1];
    string user = args[0];
    Console.WriteLine(ShellHelper.Bash($"echo -e \"{password}\n{password}\n\" | sudo passwd {user}"));
  }
}

LinuxHelper.cs

using System;
using System.Diagnostics;

namespace LinuxHelper
{
  public static class ShellHelper
  {
    public static string Bash(string cmd)
    {
      string escapedArgs = cmd.Replace("\"", "\\\"");

      Process process = new Process()
      {
        StartInfo = new ProcessStartInfo
        {
          FileName = "/bin/bash",
          Arguments = $"-c \"{escapedArgs}\"",
          RedirectStandardOutput = true,
          UseShellExecute = false,
          CreateNoWindow = true,
        }
      };

      process.Start();
      string result = process.StandardOutput.ReadToEnd();
      process.WaitForExit();

      return result;
    }
  }
}

The above code works, takes two args first is the username , second is the password. I have separated the solution into two files because the LinuxHelper/Shellhelper can be used for any shell command you need to call. The main function/method can also be easily modified to be a standard method in any project. If you do change the Main method to be a method inside a class, I suggest you change (string[] args) to (string user, string password) then you can remove the string declarations inside the method.

Related