creds.ha (4796B)
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 = { 19 let uid = 0u, euid = 0u, suid = 0u; 20 rt::getresuid(&uid, &euid, &suid) as void; 21 return uid; 22 }; 23 24 // Returns the current process effective user ID. 25 export fn geteuid() uid = { 26 let uid = 0u, euid = 0u, suid = 0u; 27 rt::getresuid(&uid, &euid, &suid) as void; 28 return euid; 29 }; 30 31 // Returns the current process group ID. 32 export fn getgid() gid = { 33 let gid = 0u, egid = 0u, sgid = 0u; 34 rt::getresgid(&gid, &egid, &sgid) as void; 35 return gid; 36 }; 37 38 // Returns the current process effective group ID. 39 export fn getegid() gid = { 40 let gid = 0u, egid = 0u, sgid = 0u; 41 rt::getresgid(&gid, &egid, &sgid) as void; 42 return egid; 43 }; 44 45 // Sets the caller's user ID to the specified value. This generally requires 46 // elevated permissions from the calling process. 47 // 48 // If the system returns an error, this function will abort the program. Failing 49 // to handle errors from setuid is a grave security issue in your program, and 50 // therefore we require this function to succeed. If you need to handle the 51 // error case gracefully, call the appropriate syscall wrapper in [[rt::]] 52 // yourself, and take extreme care to handle errors correctly. 53 export fn setuid(uid: uid) void = rt::setresuid(uid, -1i: uint, -1i: uint)!; 54 55 // Sets the caller's effective user ID to the specified value. This generally 56 // requires elevated permissions from the calling process. 57 // 58 // If the system returns an error, this function will abort the program. Failing 59 // to handle errors from seteuid is a grave security issue in your program, and 60 // therefore we require this function to succeed. If you need to handle the 61 // error case gracefully, call the appropriate syscall wrapper in [[rt::]] 62 // yourself, and take extreme care to handle errors correctly. 63 export fn seteuid(uid: uid) void = rt::setresuid(-1i: uint, uid, -1i: uint)!; 64 65 // Sets the caller's group ID to the specified value. This generally requires 66 // elevated permissions from the calling process. 67 // 68 // If the system returns an error, this function will abort the program. Failing 69 // to handle errors from setuid is a grave security issue in your program, and 70 // therefore we require this function to succeed. If you need to handle the 71 // error case gracefully, call the appropriate syscall wrapper in [[rt::]] 72 // yourself, and take extreme care to handle errors correctly. 73 export fn setgid(gid: gid) void = rt::setresgid(gid, -1i: uint, -1i: uint)!; 74 75 // Sets the caller's effective group ID to the specified value. This generally 76 // requires elevated permissions from the calling process. 77 // 78 // If the system returns an error, this function will abort the program. Failing 79 // to handle errors from setegid is a grave security issue in your program, and 80 // therefore we require this function to succeed. If you need to handle the 81 // error case gracefully, call the appropriate syscall wrapper in [[rt::]] 82 // yourself, and take extreme care to handle errors correctly. 83 export fn setegid(gid: gid) void = rt::setresgid(-1i: uint, gid, -1i: uint)!; 84 85 // Returns a list of supplementary group IDs for the current process. The 86 // returned slice is statically allocated. 87 export fn getgroups() []gid = { 88 static let gids: [rt::NGROUPS_MAX]rt::gid_t = [0...]; 89 const n = rt::getgroups(gids)!; 90 return gids[..n]: []gid; 91 }; 92 93 // Sets the list of supplementary group IDs which apply to the current process. 94 // This generally requires elevated permissions. 95 // 96 // If the system returns an error, this function will abort the program. Failing 97 // to handle errors from setgroups is a grave security issue in your program, 98 // and therefore we require this function to succeed. If you need to handle the 99 // error case gracefully, call the appropriate syscall wrapper in [[rt::]] 100 // yourself, and take extreme care to handle errors correctly. 101 export fn setgroups(gids: []gid) void = rt::setgroups(gids: []rt::gid_t)!; 102 103 // Returns the current process ID. 104 export fn getpid() pid = rt::getpid(); 105 106 // Returns the parent process ID. 107 export fn getppid() pid = rt::getppid(); 108 109 // Returns the current process group ID. 110 export fn getpgrp() pid = rt::getpgrp(); 111 112 // Returns the current process's session ID. 113 export fn getsid() pid = rt::getsid(0)!; 114 115 // Returns the session ID associated with the given process. 116 export fn getpsid(pid: pid) (pid | errors::noentry | errors::noaccess) = { 117 match (rt::getsid(pid)) { 118 case let pid: rt::pid_t => 119 return pid; 120 case let err: rt::errno => 121 assert(err == rt::ESRCH); 122 return errors::noentry; 123 }; 124 };