keyctl.ha (2828B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use errors; 5 use rt; 6 use types::c; 7 8 fn errno(errno: rt::errno) error = { 9 switch (errno) { 10 case rt::ENOKEY => 11 return nokey; 12 case => 13 return errors::errno(errno); 14 }; 15 }; 16 17 // Adds a key to the kernel's key management facility. 18 export fn add_key( 19 keytype: str, 20 name: str, 21 payload: []u8, 22 keyring: serial, 23 ) (serial | error) = { 24 const keytype = c::fromstr(keytype); 25 defer free(keytype); 26 const name = c::fromstr(name); 27 defer free(name); 28 match (rt::add_key(keytype: *const u8, name: *const u8, 29 payload: *[*]u8: *opaque, len(payload), keyring)) { 30 case let err: rt::errno => 31 return errno(err); 32 case let n: int => 33 return n: serial; 34 }; 35 }; 36 37 fn keyctl( 38 cmd: command, 39 arg2: u64, 40 arg3: u64, 41 arg4: u64, 42 arg5: u64, 43 ) (int | error) = { 44 match (rt::keyctl(cmd, arg2, arg3, arg4, arg5)) { 45 case let err: rt::errno => 46 return errno(err); 47 case let n: int => 48 return n; 49 }; 50 }; 51 52 // Maps a special key or keyring ID to the serial number of the key actually 53 // representing that feature. If it does not exist and 'create' is true, then 54 // the key or keyring will be created if it is appropriate to do so. 55 export fn get_keyring_id(key: serial, create: bool) (serial | error) = { 56 return keyctl(command::GET_KEYRING_ID, 57 key: u64, if (create) 1 else 0, 0, 0)?: serial; 58 }; 59 60 // Replace the session keyring this process subscribes to with a new session 61 // keyring using the given name, or, given an empty string, "_ses". 62 export fn join_session_keyring(name: str) (serial | error) = { 63 let name = if (name == "") { 64 yield null; 65 } else { 66 yield c::fromstr(name); 67 }; 68 defer free(name); 69 return keyctl(command::JOIN_SESSION_KEYRING, 70 name: uintptr: u64, 0, 0, 0)?: serial; 71 }; 72 73 // Update a key's payload. 74 export fn update(id: serial, payload: []u8) (void | error) = { 75 keyctl(command::UPDATE, id: u64, 76 payload: *[*]u8: uintptr: u64, 77 len(payload): u64, 0)?; 78 }; 79 80 // Revoke the key with the provided ID. 81 export fn revoke(id: serial) (void | error) = { 82 keyctl(command::REVOKE, id: u64, 0, 0, 0)?; 83 }; 84 85 // Reads the payload from a key, returning the size of the key data. The 86 // provided buffer may be empty to probe the key size without reading. 87 export fn read(id: serial, buf: []u8) (size | error) = { 88 const bufln = len(buf); 89 const buf = if (len(buf) == 0) { 90 yield null; 91 } else { 92 yield buf: *[*]u8: *opaque; 93 }; 94 return keyctl(command::READ, id: u64, 95 buf: uintptr: u64, bufln: u64, 0)?: size; 96 }; 97 98 // Changes the user and group ownership of the key. 99 export fn chown(id: serial, uid: uint, gid: uint) (void | error) = { 100 keyctl(command::CHOWN, id: u64, uid: u64, gid: u64, 0)?; 101 }; 102 103 // Changes the permissions mask of the key. 104 export fn setperm(id: serial, perm: perm) (void | error) = { 105 keyctl(command::SETPERM, id: u64, perm, 0, 0)?; 106 };