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 parseMode, 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 // Result is 0 on success, 1 if credential is unknown. 84 const result = method(id); 85 if (result === 1) { 86 throw new ERR_UNKNOWN_CREDENTIAL(type, id); 87 } 88 }; 89 } 90 91 function validateId(id, name) { 92 if (typeof id === 'number') { 93 validateUint32(id, name); 94 } else if (typeof id !== 'string') { 95 throw new ERR_INVALID_ARG_TYPE(name, ['number', 'string'], id); 96 } 97 } 98 99 return { 100 initgroups, 101 setgroups, 102 setegid: wrapIdSetter('Group', _setegid), 103 seteuid: wrapIdSetter('User', _seteuid), 104 setgid: wrapIdSetter('Group', _setgid), 105 setuid: wrapIdSetter('User', _setuid) 106 }; 107} 108 109// Cache the working directory to prevent lots of lookups. If the working 110// directory is changed by `chdir`, it'll be updated. 111let cachedCwd = ''; 112 113function wrappedChdir(directory) { 114 validateString(directory, 'directory'); 115 rawMethods.chdir(directory); 116 // Mark cache that it requires an update. 117 cachedCwd = ''; 118} 119 120function wrappedUmask(mask) { 121 if (mask !== undefined) { 122 mask = parseMode(mask, 'mask'); 123 } 124 return rawMethods.umask(mask); 125} 126 127function wrappedCwd() { 128 cachedCwd = rawMethods.cwd(); 129 return cachedCwd; 130} 131