Coverage Report

Created: 2025-11-16 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/lib/util/util_paths.c
Line
Count
Source
1
/* 
2
   Unix SMB/CIFS implementation.
3
   Samba utility functions
4
   Copyright (C) Andrew Tridgell 1992-1998
5
   Copyright (C) Jeremy Allison 2001-2007
6
   Copyright (C) Simo Sorce 2001
7
   Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8
   Copyright (C) James Peach 2006
9
   Copyright (c) 2020      Andreas Schneider <asn@samba.org>
10
11
   This program is free software; you can redistribute it and/or modify
12
   it under the terms of the GNU General Public License as published by
13
   the Free Software Foundation; either version 3 of the License, or
14
   (at your option) any later version.
15
16
   This program is distributed in the hope that it will be useful,
17
   but WITHOUT ANY WARRANTY; without even the implied warranty of
18
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
   GNU General Public License for more details.
20
21
   You should have received a copy of the GNU General Public License
22
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
*/
24
25
#include "replace.h"
26
#include "dynconfig/dynconfig.h"
27
#include "lib/util/util_paths.h"
28
#include "system/passwd.h"
29
#include "system/filesys.h"
30
31
/**
32
 * @brief Returns an absolute path to a file in the Samba modules directory.
33
 *
34
 * @param name File to find, relative to MODULESDIR.
35
 *
36
 * @retval Pointer to a string containing the full path.
37
 **/
38
39
char *modules_path(TALLOC_CTX *mem_ctx, const char *name)
40
0
{
41
0
  return talloc_asprintf(mem_ctx, "%s/%s", get_dyn_MODULESDIR(), name);
42
0
}
43
44
/**
45
 * @brief Returns an absolute path to a file in the Samba data directory.
46
 *
47
 * @param name File to find, relative to CODEPAGEDIR.
48
 *
49
 * @retval Pointer to a talloc'ed string containing the full path.
50
 **/
51
52
char *data_path(TALLOC_CTX *mem_ctx, const char *name)
53
0
{
54
0
  return talloc_asprintf(mem_ctx, "%s/%s", get_dyn_CODEPAGEDIR(), name);
55
0
}
56
57
/**
58
 * @brief Returns the platform specific shared library extension.
59
 *
60
 * @retval Pointer to a const char * containing the extension.
61
 **/
62
63
const char *shlib_ext(void)
64
0
{
65
0
  return get_dyn_SHLIBEXT();
66
0
}
67
68
static char *get_user_home_dir(TALLOC_CTX *mem_ctx)
69
0
{
70
0
  struct passwd pwd = {0};
71
0
  struct passwd *pwdbuf = NULL;
72
0
  char *buf = NULL;
73
0
  char *out = NULL;
74
0
  long int initlen;
75
0
  size_t len;
76
0
  int rc;
77
78
0
  initlen = sysconf(_SC_GETPW_R_SIZE_MAX);
79
0
  if (initlen == -1) {
80
0
    len = 1024;
81
0
  } else {
82
0
    len = (size_t)initlen;
83
0
  }
84
0
  buf = talloc_size(mem_ctx, len);
85
0
  if (buf == NULL) {
86
0
    return NULL;
87
0
  }
88
89
0
  rc = getpwuid_r(getuid(), &pwd, buf, len, &pwdbuf);
90
0
  while (rc == ERANGE) {
91
0
    size_t newlen = 2 * len;
92
0
    char *tmp = NULL;
93
0
    if (newlen < len) {
94
      /* Overflow */
95
0
      goto done;
96
0
    }
97
0
    len = newlen;
98
0
    tmp = talloc_realloc(mem_ctx, buf, char, len);
99
0
    if (tmp == NULL) {
100
0
      goto done;
101
0
    }
102
0
    buf = tmp;
103
0
    rc = getpwuid_r(getuid(), &pwd, buf, len, &pwdbuf);
104
0
  }
105
0
  if (rc != 0 || pwdbuf == NULL ) {
106
0
    const char *szPath = getenv("HOME");
107
0
    if (szPath == NULL) {
108
0
      goto done;
109
0
    }
110
0
    len = strnlen(szPath, PATH_MAX);
111
0
    if (len >= PATH_MAX) {
112
0
      goto done;
113
0
    }
114
0
    out = talloc_strdup(mem_ctx, szPath);
115
0
    goto done;
116
0
  }
117
118
0
  out = talloc_strdup(mem_ctx, pwd.pw_dir);
119
0
done:
120
0
  TALLOC_FREE(buf);
121
0
  return out;
122
0
}
123
124
char *path_expand_tilde(TALLOC_CTX *mem_ctx, const char *d)
125
0
{
126
0
  char *h = NULL, *r = NULL;
127
0
  const char *p = NULL;
128
0
  struct stat sb = {0};
129
0
  int rc;
130
131
0
  if (d[0] != '~') {
132
0
    return talloc_strdup(mem_ctx, d);
133
0
  }
134
0
  d++;
135
136
  /* handle ~user/path */
137
0
  p = strchr(d, '/');
138
0
  if (p != NULL && p > d) {
139
0
    struct passwd *pw;
140
0
    size_t s = p - d;
141
0
    char u[128];
142
143
0
    if (s >= sizeof(u)) {
144
0
      return NULL;
145
0
    }
146
0
    memcpy(u, d, s);
147
0
    u[s] = '\0';
148
149
0
    pw = getpwnam(u);
150
0
    if (pw == NULL) {
151
0
      return NULL;
152
0
    }
153
0
    h = talloc_strdup(mem_ctx, pw->pw_dir);
154
0
  } else {
155
0
    p = d;
156
0
    h = get_user_home_dir(mem_ctx);
157
0
  }
158
0
  if (h == NULL) {
159
0
    return NULL;
160
0
  }
161
162
0
  rc = stat(h, &sb);
163
0
  if (rc != 0) {
164
0
    TALLOC_FREE(h);
165
0
    return NULL;
166
0
  }
167
168
0
  r = talloc_asprintf(mem_ctx, "%s%s", h, p);
169
0
  TALLOC_FREE(h);
170
171
0
  return r;
172
0
}