summaryrefslogtreecommitdiff
path: root/lib/internal/process/methods.js
blob: 9a954f6a9b93cf8ee926f4a650ce22fb0b4c2cea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
'use strict';

const {
  ERR_INVALID_ARG_TYPE,
  ERR_UNKNOWN_CREDENTIAL
} = require('internal/errors').codes;
const {
  validateMode,
  validateUint32
} = require('internal/validators');
const {
  isMainThread
} = require('internal/worker');

function setupProcessMethods(_chdir, _cpuUsage, _hrtime, _memoryUsage,
                             _rawDebug, _umask, _initgroups, _setegid,
                             _seteuid, _setgid, _setuid, _setgroups) {
  // Non-POSIX platforms like Windows don't have certain methods.
  // Workers also lack these methods since they change process-global state.
  if (!isMainThread)
    return;

  if (_setgid !== undefined) {
    setupPosixMethods(_initgroups, _setegid, _seteuid,
                      _setgid, _setuid, _setgroups);
  }

  process.chdir = function chdir(directory) {
    if (typeof directory !== 'string') {
      throw new ERR_INVALID_ARG_TYPE('directory', 'string', directory);
    }
    return _chdir(directory);
  };

  process.umask = function umask(mask) {
    if (mask === undefined) {
      // Get the mask
      return _umask(mask);
    }
    mask = validateMode(mask, 'mask');
    return _umask(mask);
  };
}

function setupPosixMethods(_initgroups, _setegid, _seteuid,
                           _setgid, _setuid, _setgroups) {

  process.initgroups = function initgroups(user, extraGroup) {
    validateId(user, 'user');
    validateId(extraGroup, 'extraGroup');
    // Result is 0 on success, 1 if user is unknown, 2 if group is unknown.
    const result = _initgroups(user, extraGroup);
    if (result === 1) {
      throw new ERR_UNKNOWN_CREDENTIAL('User', user);
    } else if (result === 2) {
      throw new ERR_UNKNOWN_CREDENTIAL('Group', extraGroup);
    }
  };

  process.setegid = function setegid(id) {
    return execId(id, 'Group', _setegid);
  };

  process.seteuid = function seteuid(id) {
    return execId(id, 'User', _seteuid);
  };

  process.setgid = function setgid(id) {
    return execId(id, 'Group', _setgid);
  };

  process.setuid = function setuid(id) {
    return execId(id, 'User', _setuid);
  };

  process.setgroups = function setgroups(groups) {
    if (!Array.isArray(groups)) {
      throw new ERR_INVALID_ARG_TYPE('groups', 'Array', groups);
    }
    for (var i = 0; i < groups.length; i++) {
      validateId(groups[i], `groups[${i}]`);
    }
    // Result is 0 on success. A positive integer indicates that the
    // corresponding group was not found.
    const result = _setgroups(groups);
    if (result > 0) {
      throw new ERR_UNKNOWN_CREDENTIAL('Group', groups[result - 1]);
    }
  };

  function execId(id, type, method) {
    validateId(id, 'id');
    // Result is 0 on success, 1 if credential is unknown.
    const result = method(id);
    if (result === 1) {
      throw new ERR_UNKNOWN_CREDENTIAL(type, id);
    }
  }

  function validateId(id, name) {
    if (typeof id === 'number') {
      validateUint32(id, name);
    } else if (typeof id !== 'string') {
      throw new ERR_INVALID_ARG_TYPE(name, ['number', 'string'], id);
    }
  }
}

exports.setup = setupProcessMethods;