Line data Source code
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 516334 : char *modules_path(TALLOC_CTX *mem_ctx, const char *name)
40 : {
41 516334 : return talloc_asprintf(mem_ctx, "%s/%s", get_dyn_MODULESDIR(), name);
42 : }
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 0 : char *data_path(TALLOC_CTX *mem_ctx, const char *name)
53 : {
54 0 : return talloc_asprintf(mem_ctx, "%s/%s", get_dyn_CODEPAGEDIR(), name);
55 : }
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 156873 : const char *shlib_ext(void)
64 : {
65 156873 : return get_dyn_SHLIBEXT();
66 : }
67 :
68 3 : static char *get_user_home_dir(TALLOC_CTX *mem_ctx)
69 : {
70 3 : struct passwd pwd = {0};
71 3 : struct passwd *pwdbuf = NULL;
72 3 : char *buf = NULL;
73 3 : char *out = NULL;
74 3 : long int initlen;
75 3 : size_t len;
76 3 : int rc;
77 :
78 3 : initlen = sysconf(_SC_GETPW_R_SIZE_MAX);
79 3 : if (initlen == -1) {
80 0 : len = 1024;
81 : } else {
82 3 : len = (size_t)initlen;
83 : }
84 3 : buf = talloc_size(mem_ctx, len);
85 3 : if (buf == NULL) {
86 0 : return NULL;
87 : }
88 :
89 3 : rc = getpwuid_r(getuid(), &pwd, buf, len, &pwdbuf);
90 3 : while (rc == ERANGE) {
91 0 : size_t newlen = 2 * len;
92 0 : if (newlen < len) {
93 : /* Overflow */
94 0 : goto done;
95 : }
96 0 : len = newlen;
97 0 : buf = talloc_realloc_size(mem_ctx, buf, len);
98 0 : if (buf == NULL) {
99 0 : goto done;
100 : }
101 0 : rc = getpwuid_r(getuid(), &pwd, buf, len, &pwdbuf);
102 : }
103 3 : if (rc != 0 || pwdbuf == NULL ) {
104 0 : const char *szPath = getenv("HOME");
105 0 : if (szPath == NULL) {
106 0 : goto done;
107 : }
108 0 : len = strnlen(szPath, PATH_MAX);
109 0 : if (len >= PATH_MAX) {
110 0 : goto done;
111 : }
112 0 : out = talloc_strdup(mem_ctx, szPath);
113 0 : goto done;
114 : }
115 :
116 3 : out = talloc_strdup(mem_ctx, pwd.pw_dir);
117 3 : done:
118 3 : TALLOC_FREE(buf);
119 0 : return out;
120 : }
121 :
122 4 : char *path_expand_tilde(TALLOC_CTX *mem_ctx, const char *d)
123 : {
124 4 : char *h = NULL, *r = NULL;
125 4 : const char *p = NULL;
126 4 : struct stat sb = {0};
127 4 : int rc;
128 :
129 4 : if (d[0] != '~') {
130 1 : return talloc_strdup(mem_ctx, d);
131 : }
132 3 : d++;
133 :
134 : /* handle ~user/path */
135 3 : p = strchr(d, '/');
136 3 : if (p != NULL && p > d) {
137 1 : struct passwd *pw;
138 1 : size_t s = p - d;
139 1 : char u[128];
140 :
141 1 : if (s >= sizeof(u)) {
142 0 : return NULL;
143 : }
144 1 : memcpy(u, d, s);
145 1 : u[s] = '\0';
146 :
147 1 : pw = getpwnam(u);
148 1 : if (pw == NULL) {
149 0 : return NULL;
150 : }
151 1 : h = talloc_strdup(mem_ctx, pw->pw_dir);
152 : } else {
153 2 : p = d;
154 2 : h = get_user_home_dir(mem_ctx);
155 : }
156 3 : if (h == NULL) {
157 0 : return NULL;
158 : }
159 :
160 3 : rc = stat(h, &sb);
161 3 : if (rc != 0) {
162 0 : TALLOC_FREE(h);
163 0 : return NULL;
164 : }
165 :
166 3 : r = talloc_asprintf(mem_ctx, "%s%s", h, p);
167 3 : TALLOC_FREE(h);
168 :
169 3 : return r;
170 : }
|