Coverage Report

Created: 2025-10-10 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/sudo/plugins/sudoers/exptilde.c
Line
Count
Source
1
/*
2
 * SPDX-License-Identifier: ISC
3
 *
4
 * Copyright (c) 2020 Todd C. Miller <Todd.Miller@sudo.ws>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <config.h>
20
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <grp.h>
25
#include <pwd.h>
26
27
#include <sudoers.h>
28
#include <pwutil.h>
29
30
/*
31
 * Expand leading tilde in *path, which must be dynamically allocated.
32
 * Replaces path with the expanded version as needed, freeing the old one.
33
 * Returns true on success, false on failure.
34
 */
35
bool
36
expand_tilde(char **path, const char *user)
37
0
{
38
0
    char *npath, *opath = *path;
39
0
    char *slash = NULL;
40
0
    struct passwd *pw;
41
0
    int len;
42
0
    debug_decl(expand_tilde, SUDOERS_DEBUG_UTIL);
43
44
0
    switch (*opath++) {
45
0
    case '/':
46
  /* A fully-qualified path, nothing to do. */
47
0
  debug_return_bool(true);
48
0
    case '~':
49
  /* See below. */
50
0
  break;
51
0
    default:
52
  /* Not a fully-qualified path or one that starts with a tilde. */
53
0
  debug_return_bool(false);
54
0
    }
55
56
0
    switch (*opath) {
57
0
    case '\0':
58
  /* format: ~ */
59
0
  break;
60
0
    case '/':
61
  /* format: ~/foo */
62
0
  opath++;
63
0
  break;
64
0
    default:
65
  /* format: ~user/foo */
66
0
  user = opath;
67
0
  slash = strchr(opath, '/');
68
0
  if (slash != NULL) {
69
0
      *slash = '\0';
70
0
      opath = slash + 1;
71
0
  } else {
72
0
      opath = (char *)"";
73
0
  }
74
0
    }
75
0
    pw = sudo_getpwnam(user);
76
0
    if (slash != NULL)
77
0
  *slash = '/';
78
0
    if (pw == NULL) {
79
  /* Unknown user. */
80
0
  sudo_warnx(U_("unknown user %s"), user);
81
0
  debug_return_bool(false);
82
0
    }
83
84
0
    len = asprintf(&npath, "%s%s%s", pw->pw_dir, *opath ? "/" : "", opath);
85
0
    sudo_pw_delref(pw);
86
0
    if (len == -1) {
87
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
88
0
  debug_return_bool(false);
89
0
    }
90
91
0
    free(*path);
92
0
    *path = npath;
93
    debug_return_bool(true);
94
0
}