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