hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

creds.ha (5753B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 // Unix credentials types & functions; ref credentials(7)
      4 
      5 use errors;
      6 use rt;
      7 
      8 // Process ID.
      9 export type pid = rt::pid_t;
     10 
     11 // User ID.
     12 export type uid = rt::uid_t;
     13 
     14 // Group ID.
     15 export type gid = rt::gid_t;
     16 
     17 // Returns the current process user ID.
     18 export fn getuid() uid = rt::getuid();
     19 
     20 // Returns the current process effective user ID.
     21 export fn geteuid() uid = rt::geteuid();
     22 
     23 // Returns the current process group ID.
     24 export fn getgid() uid = rt::getgid();
     25 
     26 // Returns the current process effective group ID.
     27 export fn getegid() uid = rt::getegid();
     28 
     29 // Sets the caller's user ID to the specified value. This generally requires
     30 // elevated permissions from the calling process.
     31 //
     32 // If the system returns an error, this function will abort the program. Failing
     33 // to handle errors from setuid is a grave security issue in your program, and
     34 // therefore we require this function to succeed. If you need to handle the
     35 // error case gracefully, call the appropriate syscall wrapper in [[rt::]] yourself,
     36 // and take extreme care to handle errors correctly.
     37 export fn setuid(uid: uid) void = rt::setuid(uid)!;
     38 
     39 // Sets the caller's effective user ID to the specified value. This generally
     40 // requires elevated permissions from the calling process.
     41 //
     42 // If the system returns an error, this function will abort the program. Failing
     43 // to handle errors from seteuid is a grave security issue in your program, and
     44 // therefore we require this function to succeed. If you need to handle the
     45 // error case gracefully, call the appropriate syscall wrapper in [[rt::]] yourself,
     46 // and take extreme care to handle errors correctly.
     47 export fn seteuid(uid: uid) void = rt::seteuid(uid)!;
     48 
     49 // Sets the caller's group ID to the specified value. This generally requires
     50 // elevated permissions from the calling process.
     51 //
     52 // If the system returns an error, this function will abort the program. Failing
     53 // to handle errors from setuid is a grave security issue in your program, and
     54 // therefore we require this function to succeed. If you need to handle the
     55 // error case gracefully, call the appropriate syscall wrapper in [[rt::]] yourself,
     56 // and take extreme care to handle errors correctly.
     57 export fn setgid(gid: gid) void = rt::setgid(gid)!;
     58 
     59 // Sets the caller's effective group ID to the specified value. This generally
     60 // requires elevated permissions from the calling process.
     61 //
     62 // If the system returns an error, this function will abort the program. Failing
     63 // to handle errors from setegid is a grave security issue in your program, and
     64 // therefore we require this function to succeed. If you need to handle the
     65 // error case gracefully, call the appropriate syscall wrapper in [[rt::]] yourself,
     66 // and take extreme care to handle errors correctly.
     67 export fn setegid(gid: gid) void = rt::setegid(gid)!;
     68 
     69 // Returns a list of supplementary group IDs for the current process. The
     70 // returned slice is statically allocated.
     71 export fn getgroups() []gid = {
     72 	static let gids: [rt::NGROUPS_MAX]rt::gid_t = [0...];
     73 	const n = rt::getgroups(gids)!;
     74 	return gids[..n]: []gid;
     75 };
     76 
     77 // Sets the list of supplementary group IDs which apply to the current process.
     78 // This generally requires elevated permissions.
     79 //
     80 // If the system returns an error, this function will abort the program. Failing
     81 // to handle errors from setgroups is a grave security issue in your program,
     82 // and therefore we require this function to succeed. If you need to handle the
     83 // error case gracefully, call the appropriate syscall wrapper in [[rt::]]
     84 // yourself, and take extreme care to handle errors correctly.
     85 export fn setgroups(gids: []gid) void = rt::setgroups(gids: []rt::gid_t)!;
     86 
     87 // Returns the current process ID.
     88 export fn getpid() pid = rt::getpid();
     89 
     90 // Returns the parent process ID.
     91 export fn getppid() pid = rt::getppid();
     92 
     93 // Returns the current process group ID.
     94 export fn getpgrp() pid = rt::getpgrp();
     95 
     96 // Returns the process group associated with the given pid.
     97 export fn getpgid(pid: pid) (pid | errors::noentry) = {
     98 	match (rt::getpgid(pid)) {
     99 	case let pid: rt::pid_t =>
    100 		return pid;
    101 	case let err: rt::errno =>
    102 		assert(err == rt::ESRCH, "Unexpected getpgid return value");
    103 		return errors::noentry;
    104 	};
    105 };
    106 
    107 // Sets the process group ID of the specified process. This function is
    108 // error-prone; see the notes in the POSIX specification for its many caveats.
    109 export fn setpgid(targ: pid, pgid: pid) (void | errors::error) = {
    110 	match (rt::setpgid(targ, pgid)) {
    111 	case let err: rt::errno =>
    112 		return errors::errno(err);
    113 	case void =>
    114 		return;
    115 	};
    116 };
    117 
    118 // Returns the current process's session ID.
    119 export fn getsid() pid = rt::getsid(0)!;
    120 
    121 // Returns the session ID associated with the given process.
    122 export fn getpsid(pid: pid) (pid | errors::noentry | errors::noaccess) = {
    123 	match (rt::getsid(pid)) {
    124 	case let pid: rt::pid_t =>
    125 		return pid;
    126 	case let err: rt::errno =>
    127 		assert(err == rt::ESRCH, "Unexpected getsid return value");
    128 		return errors::noentry;
    129 	};
    130 };
    131 
    132 // Creates a new session and sets the current process to the session leader.
    133 // A new process group is also created with its process group ID equal to the
    134 // pid of the current process, and the current process is made the process group
    135 // leader.
    136 //
    137 // Upon return, the new session will have no controlling terminal. To establish
    138 // one, the caller must open a terminal file with [[fs::flag::CTTY]]; this
    139 // opt-in approach differs from the Unix norm where O_NOCTTY is required to
    140 // opt-out of establishing a controlling terminal.
    141 //
    142 // The current process cannot be a process group leader; this is a programmer
    143 // error and will cause a runtime assertion failure.
    144 export fn setsid() void = rt::setsid()!;