1'use strict'; 2 3const credentials = internalBinding('credentials'); 4const rawMethods = internalBinding('process_methods'); 5 6process.abort = rawMethods.abort; 7process.umask = wrappedUmask; 8process.chdir = wrappedChdir; 9process.cwd = wrappedCwd; 10 11if (credentials.implementsPosixCredentials) { 12 const wrapped = wrapPosixCredentialSetters(credentials); 13 14 process.initgroups = wrapped.initgroups; 15 process.setgroups = wrapped.setgroups; 16 process.setegid = wrapped.setegid; 17 process.seteuid = wrapped.seteuid; 18 process.setgid = wrapped.setgid; 19 process.setuid = wrapped.setuid; 20} 21 22// ---- keep the attachment of the wrappers above so that it's easier to ---- 23// ---- compare the setups side-by-side ----- 24 25const { 26 parseFileMode, 27 validateArray, 28 validateString, 29} = require('internal/validators'); 30 31function wrapPosixCredentialSetters(credentials) { 32 const { 33 codes: { 34 ERR_INVALID_ARG_TYPE, 35 ERR_UNKNOWN_CREDENTIAL, 36 }, 37 } = require('internal/errors'); 38 const { 39 validateUint32, 40 } = require('internal/validators'); 41 42 const { 43 initgroups: _initgroups, 44 setgroups: _setgroups, 45 setegid: _setegid, 46 seteuid: _seteuid, 47 setgid: _setgid, 48 setuid: _setuid, 49 } = credentials; 50 51 function initgroups(user, extraGroup) { 52 validateId(user, 'user'); 53 validateId(extraGroup, 'extraGroup'); 54 // Result is 0 on success, 1 if user is unknown, 2 if group is unknown. 55 const result = _initgroups(user, extraGroup); 56 if (result === 1) { 57 throw new ERR_UNKNOWN_CREDENTIAL('User', user); 58 } else if (result === 2) { 59 throw new ERR_UNKNOWN_CREDENTIAL('Group', extraGroup); 60 } 61 } 62 63 function setgroups(groups) { 64 validateArray(groups, 'groups'); 65 for (let i = 0; i < groups.length; i++) { 66 validateId(groups[i], `groups[${i}]`); 67 } 68 // Result is 0 on success. A positive integer indicates that the 69 // corresponding group was not found. 70 const result = _setgroups(groups); 71 if (result > 0) { 72 throw new ERR_UNKNOWN_CREDENTIAL('Group', groups[result - 1]); 73 } 74 } 75 76 function wrapIdSetter(type, method) { 77 return function(id) { 78 validateId(id, 'id'); 79 if (typeof id === 'number') id >>>= 0; 80 // Result is 0 on success, 1 if credential is unknown. 81 const result = method(id); 82 if (result === 1) { 83 throw new ERR_UNKNOWN_CREDENTIAL(type, id); 84 } 85 }; 86 } 87 88 function validateId(id, name) { 89 if (typeof id === 'number') { 90 validateUint32(id, name); 91 } else if (typeof id !== 'string') { 92 throw new ERR_INVALID_ARG_TYPE(name, ['number', 'string'], id); 93 } 94 } 95 96 return { 97 initgroups, 98 setgroups, 99 setegid: wrapIdSetter('Group', _setegid), 100 seteuid: wrapIdSetter('User', _seteuid), 101 setgid: wrapIdSetter('Group', _setgid), 102 setuid: wrapIdSetter('User', _setuid), 103 }; 104} 105 106// Cache the working directory to prevent lots of lookups. If the working 107// directory is changed by `chdir`, it'll be updated. 108let cachedCwd = ''; 109 110function wrappedChdir(directory) { 111 validateString(directory, 'directory'); 112 rawMethods.chdir(directory); 113 // Mark cache that it requires an update. 114 cachedCwd = ''; 115} 116 117function wrappedUmask(mask) { 118 if (mask !== undefined) { 119 mask = parseFileMode(mask, 'mask'); 120 } 121 return rawMethods.umask(mask); 122} 123 124function wrappedCwd() { 125 if (cachedCwd === '') 126 cachedCwd = rawMethods.cwd(); 127 return cachedCwd; 128} 129