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-2002
6 : Copyright (C) Simo Sorce 2001-2011
7 : Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
8 : Copyright (C) James J Myers 2003
9 : Copyright (C) Volker Lendecke 2010
10 : Copyright (C) Swen Schillig 2019
11 :
12 : This program is free software; you can redistribute it and/or modify
13 : it under the terms of the GNU General Public License as published by
14 : the Free Software Foundation; either version 3 of the License, or
15 : (at your option) any later version.
16 :
17 : This program is distributed in the hope that it will be useful,
18 : but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 : GNU General Public License for more details.
21 :
22 : You should have received a copy of the GNU General Public License
23 : along with this program. If not, see <http://www.gnu.org/licenses/>.
24 : */
25 :
26 : #include "replace.h"
27 : #include <talloc.h>
28 : #include <tevent.h>
29 : #include "system/network.h"
30 : #include "system/filesys.h"
31 : #include "system/locale.h"
32 : #include "system/shmem.h"
33 : #include "system/passwd.h"
34 : #include "system/time.h"
35 : #include "system/wait.h"
36 : #include "debug.h"
37 : #include "samba_util.h"
38 : #include "lib/util/select.h"
39 : #include <libgen.h>
40 : #include <gnutls/gnutls.h>
41 :
42 : #ifdef HAVE_SYS_PRCTL_H
43 : #include <sys/prctl.h>
44 : #endif
45 :
46 : #undef malloc
47 : #undef strcasecmp
48 : #undef strncasecmp
49 : #undef strdup
50 : #undef realloc
51 : #undef calloc
52 :
53 : /**
54 : * @file
55 : * @brief Misc utility functions
56 : */
57 :
58 : /**
59 : Find a suitable temporary directory. The result should be copied immediately
60 : as it may be overwritten by a subsequent call.
61 : **/
62 1741 : _PUBLIC_ const char *tmpdir(void)
63 : {
64 : char *p;
65 1741 : if ((p = getenv("TMPDIR")))
66 1741 : return p;
67 0 : return "/tmp";
68 : }
69 :
70 :
71 : /**
72 : Create a tmp file, open it and immediately unlink it.
73 : If dir is NULL uses tmpdir()
74 : Returns the file descriptor or -1 on error.
75 : **/
76 0 : int create_unlink_tmp(const char *dir)
77 0 : {
78 0 : size_t len = strlen(dir ? dir : (dir = tmpdir()));
79 0 : char fname[len+25];
80 : int fd;
81 : mode_t mask;
82 :
83 0 : len = snprintf(fname, sizeof(fname), "%s/listenerlock_XXXXXX", dir);
84 0 : if (len >= sizeof(fname)) {
85 0 : errno = ENOMEM;
86 0 : return -1;
87 : }
88 0 : mask = umask(S_IRWXO | S_IRWXG);
89 0 : fd = mkstemp(fname);
90 0 : umask(mask);
91 0 : if (fd == -1) {
92 0 : return -1;
93 : }
94 0 : if (unlink(fname) == -1) {
95 0 : int sys_errno = errno;
96 0 : close(fd);
97 0 : errno = sys_errno;
98 0 : return -1;
99 : }
100 0 : return fd;
101 : }
102 :
103 :
104 : /**
105 : Check if a file exists - call vfs_file_exist for samba files.
106 : **/
107 42537 : _PUBLIC_ bool file_exist(const char *fname)
108 : {
109 : struct stat st;
110 :
111 42537 : if (stat(fname, &st) != 0) {
112 28785 : return false;
113 : }
114 :
115 13752 : return ((S_ISREG(st.st_mode)) || (S_ISFIFO(st.st_mode)));
116 : }
117 :
118 : /**
119 : Check a files mod time.
120 : **/
121 :
122 103343 : _PUBLIC_ time_t file_modtime(const char *fname)
123 : {
124 : struct stat st;
125 :
126 103343 : if (stat(fname,&st) != 0)
127 8966 : return(0);
128 :
129 94377 : return(st.st_mtime);
130 : }
131 :
132 : /**
133 : Check file permissions.
134 : **/
135 :
136 48 : _PUBLIC_ bool file_check_permissions(const char *fname,
137 : uid_t uid,
138 : mode_t file_perms,
139 : struct stat *pst)
140 : {
141 : int ret;
142 : struct stat st;
143 :
144 48 : if (pst == NULL) {
145 0 : pst = &st;
146 : }
147 :
148 48 : ZERO_STRUCTP(pst);
149 :
150 48 : ret = stat(fname, pst);
151 48 : if (ret != 0) {
152 0 : DEBUG(0, ("stat failed on file '%s': %s\n",
153 : fname, strerror(errno)));
154 0 : return false;
155 : }
156 :
157 48 : if (pst->st_uid != uid && !uid_wrapper_enabled()) {
158 0 : DEBUG(0, ("invalid ownership of file '%s': "
159 : "owned by uid %u, should be %u\n",
160 : fname, (unsigned int)pst->st_uid,
161 : (unsigned int)uid));
162 0 : return false;
163 : }
164 :
165 48 : if ((pst->st_mode & 0777) != file_perms) {
166 0 : DEBUG(0, ("invalid permissions on file "
167 : "'%s': has 0%o should be 0%o\n", fname,
168 : (unsigned int)(pst->st_mode & 0777),
169 : (unsigned int)file_perms));
170 0 : return false;
171 : }
172 :
173 48 : return true;
174 : }
175 :
176 : /**
177 : Check if a directory exists.
178 : **/
179 :
180 248 : _PUBLIC_ bool directory_exist(const char *dname)
181 : {
182 : struct stat st;
183 : bool ret;
184 :
185 248 : if (stat(dname,&st) != 0) {
186 53 : return false;
187 : }
188 :
189 195 : ret = S_ISDIR(st.st_mode);
190 195 : if(!ret)
191 0 : errno = ENOTDIR;
192 195 : return ret;
193 : }
194 :
195 : /**
196 : * Try to create the specified directory if it didn't exist.
197 : * A symlink to a directory is also accepted as a valid existing directory.
198 : *
199 : * @retval true if the directory already existed
200 : * or was successfully created.
201 : */
202 751399 : _PUBLIC_ bool directory_create_or_exist(const char *dname,
203 : mode_t dir_perms)
204 : {
205 : int ret;
206 : mode_t old_umask;
207 :
208 : /* Create directory */
209 751399 : old_umask = umask(0);
210 751399 : ret = mkdir(dname, dir_perms);
211 751399 : if (ret == -1 && errno != EEXIST) {
212 14 : int dbg_level = geteuid() == 0 ? DBGLVL_ERR : DBGLVL_NOTICE;
213 :
214 14 : DBG_PREFIX(dbg_level,
215 : ("mkdir failed on directory %s: %s\n",
216 : dname,
217 : strerror(errno)));
218 14 : umask(old_umask);
219 14 : return false;
220 : }
221 751385 : umask(old_umask);
222 :
223 751385 : if (ret != 0 && errno == EEXIST) {
224 : struct stat sbuf;
225 :
226 750268 : ret = lstat(dname, &sbuf);
227 750268 : if (ret != 0) {
228 0 : return false;
229 : }
230 :
231 750268 : if (S_ISDIR(sbuf.st_mode)) {
232 750268 : return true;
233 : }
234 :
235 0 : if (S_ISLNK(sbuf.st_mode)) {
236 0 : ret = stat(dname, &sbuf);
237 0 : if (ret != 0) {
238 0 : return false;
239 : }
240 :
241 0 : if (S_ISDIR(sbuf.st_mode)) {
242 0 : return true;
243 : }
244 : }
245 :
246 0 : return false;
247 : }
248 :
249 1117 : return true;
250 : }
251 :
252 0 : _PUBLIC_ bool directory_create_or_exists_recursive(
253 : const char *dname,
254 : mode_t dir_perms)
255 : {
256 : bool ok;
257 :
258 0 : ok = directory_create_or_exist(dname, dir_perms);
259 0 : if (!ok) {
260 0 : if (!directory_exist(dname)) {
261 0 : char tmp[PATH_MAX] = {0};
262 0 : char *parent = NULL;
263 : size_t n;
264 :
265 : /* Use the null context */
266 0 : n = strlcpy(tmp, dname, sizeof(tmp));
267 0 : if (n < strlen(dname)) {
268 0 : DBG_ERR("Path too long!\n");
269 0 : return false;
270 : }
271 :
272 0 : parent = dirname(tmp);
273 0 : if (parent == NULL) {
274 0 : DBG_ERR("Failed to create dirname!\n");
275 0 : return false;
276 : }
277 :
278 0 : ok = directory_create_or_exists_recursive(parent,
279 : dir_perms);
280 0 : if (!ok) {
281 0 : return false;
282 : }
283 :
284 0 : ok = directory_create_or_exist(dname, dir_perms);
285 : }
286 : }
287 :
288 0 : return ok;
289 : }
290 :
291 : /**
292 : * @brief Try to create a specified directory if it doesn't exist.
293 : *
294 : * The function creates a directory with the given uid and permissions if it
295 : * doesn't exist. If it exists it makes sure the uid and permissions are
296 : * correct and it will fail if they are different.
297 : *
298 : * @param[in] dname The directory to create.
299 : *
300 : * @param[in] uid The uid the directory needs to belong too.
301 : *
302 : * @param[in] dir_perms The expected permissions of the directory.
303 : *
304 : * @return True on success, false on error.
305 : */
306 437661 : _PUBLIC_ bool directory_create_or_exist_strict(const char *dname,
307 : uid_t uid,
308 : mode_t dir_perms)
309 : {
310 : struct stat st;
311 : bool ok;
312 : int rc;
313 :
314 437661 : ok = directory_create_or_exist(dname, dir_perms);
315 437661 : if (!ok) {
316 14 : return false;
317 : }
318 :
319 437647 : rc = lstat(dname, &st);
320 437647 : if (rc == -1) {
321 0 : DEBUG(0, ("lstat failed on created directory %s: %s\n",
322 : dname, strerror(errno)));
323 0 : return false;
324 : }
325 :
326 : /* Check ownership and permission on existing directory */
327 437647 : if (!S_ISDIR(st.st_mode)) {
328 0 : DEBUG(0, ("directory %s isn't a directory\n",
329 : dname));
330 0 : return false;
331 : }
332 437647 : if (st.st_uid != uid && !uid_wrapper_enabled()) {
333 0 : DBG_NOTICE("invalid ownership on directory "
334 : "%s\n", dname);
335 0 : return false;
336 : }
337 437647 : if ((st.st_mode & 0777) != dir_perms) {
338 0 : DEBUG(0, ("invalid permissions on directory "
339 : "'%s': has 0%o should be 0%o\n", dname,
340 : (unsigned int)(st.st_mode & 0777), (unsigned int)dir_perms));
341 0 : return false;
342 : }
343 :
344 437647 : return true;
345 : }
346 :
347 :
348 : /**
349 : Sleep for a specified number of milliseconds.
350 : **/
351 :
352 721 : _PUBLIC_ void smb_msleep(unsigned int t)
353 : {
354 721 : sys_poll_intr(NULL, 0, t);
355 721 : }
356 :
357 : /**
358 : Get my own name, return in talloc'ed storage.
359 : **/
360 :
361 17738 : _PUBLIC_ char *get_myname(TALLOC_CTX *ctx)
362 : {
363 : char *p;
364 : char hostname[HOST_NAME_MAX];
365 :
366 : /* get my host name */
367 17738 : if (gethostname(hostname, sizeof(hostname)) == -1) {
368 0 : DEBUG(0,("gethostname failed\n"));
369 0 : return NULL;
370 : }
371 :
372 : /* Ensure null termination. */
373 17738 : hostname[sizeof(hostname)-1] = '\0';
374 :
375 : /* split off any parts after an initial . */
376 17738 : p = strchr_m(hostname, '.');
377 17738 : if (p) {
378 10818 : *p = 0;
379 : }
380 :
381 17738 : return talloc_strdup(ctx, hostname);
382 : }
383 :
384 : /**
385 : Check if a process exists. Does this work on all unixes?
386 : **/
387 :
388 2279 : _PUBLIC_ bool process_exists_by_pid(pid_t pid)
389 : {
390 : /* Doing kill with a non-positive pid causes messages to be
391 : * sent to places we don't want. */
392 2279 : if (pid <= 0) {
393 0 : return false;
394 : }
395 2279 : return(kill(pid,0) == 0 || errno != ESRCH);
396 : }
397 :
398 : /**
399 : Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
400 : is dealt with in posix.c
401 : **/
402 :
403 29 : _PUBLIC_ bool fcntl_lock(int fd, int op, off_t offset, off_t count, int type)
404 : {
405 : struct flock lock;
406 : int ret;
407 :
408 29 : DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
409 :
410 29 : lock.l_type = type;
411 29 : lock.l_whence = SEEK_SET;
412 29 : lock.l_start = offset;
413 29 : lock.l_len = count;
414 29 : lock.l_pid = 0;
415 :
416 29 : ret = fcntl(fd,op,&lock);
417 :
418 29 : if (ret == -1 && errno != 0)
419 19 : DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
420 :
421 : /* a lock query */
422 29 : if (op == F_GETLK) {
423 0 : if ((ret != -1) &&
424 0 : (lock.l_type != F_UNLCK) &&
425 0 : (lock.l_pid != 0) &&
426 0 : (lock.l_pid != tevent_cached_getpid())) {
427 0 : DEBUG(3,("fcntl_lock: fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
428 0 : return true;
429 : }
430 :
431 : /* it must be not locked or locked by me */
432 0 : return false;
433 : }
434 :
435 : /* a lock set or unset */
436 29 : if (ret == -1) {
437 19 : DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
438 : (double)offset,(double)count,op,type,strerror(errno)));
439 19 : return false;
440 : }
441 :
442 : /* everything went OK */
443 10 : DEBUG(8,("fcntl_lock: Lock call successful\n"));
444 :
445 10 : return true;
446 : }
447 :
448 : struct debug_channel_level {
449 : int channel;
450 : int level;
451 : };
452 :
453 0 : static void debugadd_channel_cb(const char *buf, void *private_data)
454 : {
455 0 : struct debug_channel_level *dcl =
456 : (struct debug_channel_level *)private_data;
457 :
458 0 : DEBUGADDC(dcl->channel, dcl->level,("%s", buf));
459 0 : }
460 :
461 101666 : static void debugadd_cb(const char *buf, void *private_data)
462 : {
463 101666 : int *plevel = (int *)private_data;
464 101666 : DEBUGADD(*plevel, ("%s", buf));
465 101666 : }
466 :
467 13042250 : void print_asc_cb(const uint8_t *buf, int len,
468 : void (*cb)(const char *buf, void *private_data),
469 : void *private_data)
470 : {
471 : int i;
472 : char s[2];
473 13042250 : s[1] = 0;
474 :
475 26084500 : for (i=0; i<len; i++) {
476 13042250 : s[0] = isprint(buf[i]) ? buf[i] : '.';
477 13042250 : cb(s, private_data);
478 : }
479 13042250 : }
480 :
481 0 : void print_asc(int level, const uint8_t *buf,int len)
482 : {
483 0 : print_asc_cb(buf, len, debugadd_cb, &level);
484 0 : }
485 :
486 905546 : static void dump_data_block16(const char *prefix, size_t idx,
487 : const uint8_t *buf, size_t len,
488 : void (*cb)(const char *buf, void *private_data),
489 : void *private_data)
490 : {
491 : char tmp[16];
492 : size_t i;
493 :
494 905546 : SMB_ASSERT(len >= 0 && len <= 16);
495 :
496 905546 : snprintf(tmp, sizeof(tmp), "%s[%04zX]", prefix, idx);
497 905546 : cb(tmp, private_data);
498 :
499 15394282 : for (i=0; i<16; i++) {
500 14488736 : if (i == 8) {
501 905546 : cb(" ", private_data);
502 : }
503 14488736 : if (i < len) {
504 13042250 : snprintf(tmp, sizeof(tmp), " %02X", (int)buf[i]);
505 : } else {
506 1446486 : snprintf(tmp, sizeof(tmp), " ");
507 : }
508 14488736 : cb(tmp, private_data);
509 : }
510 :
511 905546 : cb(" ", private_data);
512 :
513 905546 : if (len == 0) {
514 0 : cb("EMPTY BLOCK\n", private_data);
515 0 : return;
516 : }
517 :
518 13947796 : for (i=0; i<len; i++) {
519 13042250 : if (i == 8) {
520 787126 : cb(" ", private_data);
521 : }
522 13042250 : print_asc_cb(&buf[i], 1, cb, private_data);
523 : }
524 :
525 905546 : cb("\n", private_data);
526 : }
527 :
528 : /**
529 : * Write dump of binary data to a callback
530 : */
531 202962 : void dump_data_cb(const uint8_t *buf, int len,
532 : bool omit_zero_bytes,
533 : void (*cb)(const char *buf, void *private_data),
534 : void *private_data)
535 : {
536 202962 : int i=0;
537 202962 : bool skipped = false;
538 :
539 202962 : if (len<=0) return;
540 :
541 1128791 : for (i=0;i<len;i+=16) {
542 925829 : size_t remaining_len = len - i;
543 925829 : size_t this_len = MIN(remaining_len, 16);
544 925829 : const uint8_t *this_buf = &buf[i];
545 :
546 925829 : if ((omit_zero_bytes == true) &&
547 722867 : (i > 0) && (remaining_len > 16) &&
548 622999 : (this_len == 16) && all_zero(this_buf, 16))
549 : {
550 20283 : if (!skipped) {
551 16026 : cb("skipping zero buffer bytes\n",
552 : private_data);
553 16026 : skipped = true;
554 : }
555 20283 : continue;
556 : }
557 :
558 905546 : skipped = false;
559 905546 : dump_data_block16("", i, this_buf, this_len,
560 : cb, private_data);
561 : }
562 : }
563 :
564 : /**
565 : * Write dump of binary data to the log file.
566 : *
567 : * The data is only written if the log level is at least level.
568 : */
569 5594307 : _PUBLIC_ void dump_data(int level, const uint8_t *buf, int len)
570 : {
571 5594307 : if (!DEBUGLVL(level)) {
572 5591191 : return;
573 : }
574 3116 : dump_data_cb(buf, len, false, debugadd_cb, &level);
575 : }
576 :
577 : /**
578 : * Write dump of binary data to the log file.
579 : *
580 : * The data is only written if the log level is at least level for
581 : * debug class dbgc_class.
582 : */
583 30900 : _PUBLIC_ void dump_data_dbgc(int dbgc_class, int level, const uint8_t *buf, int len)
584 : {
585 30900 : struct debug_channel_level dcl = { dbgc_class, level };
586 :
587 30900 : if (!DEBUGLVLC(dbgc_class, level)) {
588 30900 : return;
589 : }
590 0 : dump_data_cb(buf, len, false, debugadd_channel_cb, &dcl);
591 : }
592 :
593 : /**
594 : * Write dump of binary data to the log file.
595 : *
596 : * The data is only written if the log level is at least level.
597 : * 16 zero bytes in a row are omitted
598 : */
599 0 : _PUBLIC_ void dump_data_skip_zeros(int level, const uint8_t *buf, int len)
600 : {
601 0 : if (!DEBUGLVL(level)) {
602 0 : return;
603 : }
604 0 : dump_data_cb(buf, len, true, debugadd_cb, &level);
605 : }
606 :
607 0 : static void fprintf_cb(const char *buf, void *private_data)
608 : {
609 0 : FILE *f = (FILE *)private_data;
610 0 : fprintf(f, "%s", buf);
611 0 : }
612 :
613 0 : void dump_data_file(const uint8_t *buf, int len, bool omit_zero_bytes,
614 : FILE *f)
615 : {
616 0 : dump_data_cb(buf, len, omit_zero_bytes, fprintf_cb, f);
617 0 : }
618 :
619 : /**
620 : * Write dump of compared binary data to a callback
621 : */
622 0 : void dump_data_diff_cb(const uint8_t *buf1, size_t len1,
623 : const uint8_t *buf2, size_t len2,
624 : bool omit_zero_bytes,
625 : void (*cb)(const char *buf, void *private_data),
626 : void *private_data)
627 : {
628 0 : size_t len = MAX(len1, len2);
629 : size_t i;
630 0 : bool skipped = false;
631 :
632 0 : for (i=0; i<len; i+=16) {
633 0 : size_t remaining_len = len - i;
634 0 : size_t remaining_len1 = 0;
635 0 : size_t this_len1 = 0;
636 0 : const uint8_t *this_buf1 = NULL;
637 0 : size_t remaining_len2 = 0;
638 0 : size_t this_len2 = 0;
639 0 : const uint8_t *this_buf2 = NULL;
640 :
641 0 : if (i < len1) {
642 0 : remaining_len1 = len1 - i;
643 0 : this_len1 = MIN(remaining_len1, 16);
644 0 : this_buf1 = &buf1[i];
645 : }
646 0 : if (i < len2) {
647 0 : remaining_len2 = len2 - i;
648 0 : this_len2 = MIN(remaining_len2, 16);
649 0 : this_buf2 = &buf2[i];
650 : }
651 :
652 0 : if ((omit_zero_bytes == true) &&
653 0 : (i > 0) && (remaining_len > 16) &&
654 0 : (this_len1 == 16) && all_zero(this_buf1, 16) &&
655 0 : (this_len2 == 16) && all_zero(this_buf2, 16))
656 : {
657 0 : if (!skipped) {
658 0 : cb("skipping zero buffer bytes\n",
659 : private_data);
660 0 : skipped = true;
661 : }
662 0 : continue;
663 : }
664 :
665 0 : skipped = false;
666 :
667 0 : if ((this_len1 == this_len2) &&
668 0 : (memcmp(this_buf1, this_buf2, this_len1) == 0))
669 : {
670 0 : dump_data_block16(" ", i, this_buf1, this_len1,
671 : cb, private_data);
672 0 : continue;
673 : }
674 :
675 0 : dump_data_block16("-", i, this_buf1, this_len1,
676 : cb, private_data);
677 0 : dump_data_block16("+", i, this_buf2, this_len2,
678 : cb, private_data);
679 : }
680 0 : }
681 :
682 0 : _PUBLIC_ void dump_data_diff(int dbgc_class, int level,
683 : bool omit_zero_bytes,
684 : const uint8_t *buf1, size_t len1,
685 : const uint8_t *buf2, size_t len2)
686 : {
687 0 : struct debug_channel_level dcl = { dbgc_class, level };
688 :
689 0 : if (!DEBUGLVLC(dbgc_class, level)) {
690 0 : return;
691 : }
692 0 : dump_data_diff_cb(buf1, len1, buf2, len2, true, debugadd_channel_cb, &dcl);
693 : }
694 :
695 0 : _PUBLIC_ void dump_data_file_diff(FILE *f,
696 : bool omit_zero_bytes,
697 : const uint8_t *buf1, size_t len1,
698 : const uint8_t *buf2, size_t len2)
699 : {
700 0 : dump_data_diff_cb(buf1, len1, buf2, len2, omit_zero_bytes, fprintf_cb, f);
701 0 : }
702 :
703 : /**
704 : malloc that aborts with smb_panic on fail or zero size.
705 : **/
706 :
707 24389 : _PUBLIC_ void *smb_xmalloc(size_t size)
708 : {
709 : void *p;
710 24389 : if (size == 0)
711 0 : smb_panic("smb_xmalloc: called with zero size.\n");
712 24389 : if ((p = malloc(size)) == NULL)
713 0 : smb_panic("smb_xmalloc: malloc fail.\n");
714 24389 : return p;
715 : }
716 :
717 : /**
718 : Memdup with smb_panic on fail.
719 : **/
720 :
721 24389 : _PUBLIC_ void *smb_xmemdup(const void *p, size_t size)
722 : {
723 : void *p2;
724 24389 : p2 = smb_xmalloc(size);
725 24389 : memcpy(p2, p, size);
726 24389 : return p2;
727 : }
728 :
729 : /**
730 : strdup that aborts on malloc fail.
731 : **/
732 :
733 560843 : char *smb_xstrdup(const char *s)
734 : {
735 : #if defined(PARANOID_MALLOC_CHECKER)
736 : #ifdef strdup
737 : #undef strdup
738 : #endif
739 : #endif
740 :
741 : #ifndef HAVE_STRDUP
742 : #define strdup rep_strdup
743 : #endif
744 :
745 560843 : char *s1 = strdup(s);
746 : #if defined(PARANOID_MALLOC_CHECKER)
747 : #ifdef strdup
748 : #undef strdup
749 : #endif
750 : #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
751 : #endif
752 560843 : if (!s1) {
753 0 : smb_panic("smb_xstrdup: malloc failed");
754 : }
755 560843 : return s1;
756 :
757 : }
758 :
759 : /**
760 : strndup that aborts on malloc fail.
761 : **/
762 :
763 2282 : char *smb_xstrndup(const char *s, size_t n)
764 : {
765 : #if defined(PARANOID_MALLOC_CHECKER)
766 : #ifdef strndup
767 : #undef strndup
768 : #endif
769 : #endif
770 :
771 : #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
772 : #undef HAVE_STRNDUP
773 : #define strndup rep_strndup
774 : #endif
775 :
776 2282 : char *s1 = strndup(s, n);
777 : #if defined(PARANOID_MALLOC_CHECKER)
778 : #ifdef strndup
779 : #undef strndup
780 : #endif
781 : #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
782 : #endif
783 2282 : if (!s1) {
784 0 : smb_panic("smb_xstrndup: malloc failed");
785 : }
786 2282 : return s1;
787 : }
788 :
789 :
790 :
791 : /**
792 : Like strdup but for memory.
793 : **/
794 :
795 22639 : _PUBLIC_ void *smb_memdup(const void *p, size_t size)
796 : {
797 : void *p2;
798 22639 : if (size == 0)
799 0 : return NULL;
800 22639 : p2 = malloc(size);
801 22639 : if (!p2)
802 0 : return NULL;
803 22639 : memcpy(p2, p, size);
804 22639 : return p2;
805 : }
806 :
807 : /**
808 : * Write a password to the log file.
809 : *
810 : * @note Only actually does something if DEBUG_PASSWORD was defined during
811 : * compile-time.
812 : */
813 3044089 : _PUBLIC_ void dump_data_pw(const char *msg, const uint8_t * data, size_t len)
814 : {
815 : #ifdef DEBUG_PASSWORD
816 3044089 : DEBUG(11, ("%s", msg));
817 3044089 : if (data != NULL && len > 0)
818 : {
819 3043734 : dump_data(11, data, len);
820 : }
821 : #endif
822 3044089 : }
823 :
824 :
825 : /**
826 : * see if a range of memory is all zero. A NULL pointer is considered
827 : * to be all zero
828 : */
829 10525566 : _PUBLIC_ bool all_zero(const uint8_t *ptr, size_t size)
830 : {
831 : size_t i;
832 10525566 : if (!ptr) return true;
833 211969830 : for (i=0;i<size;i++) {
834 202337791 : if (ptr[i]) return false;
835 : }
836 9632039 : return true;
837 : }
838 :
839 : /**
840 : realloc an array, checking for integer overflow in the array size
841 : */
842 24039 : _PUBLIC_ void *realloc_array(void *ptr, size_t el_size, unsigned count, bool free_on_fail)
843 : {
844 : #define MAX_MALLOC_SIZE 0x7fffffff
845 42733 : if (count == 0 ||
846 24039 : count >= MAX_MALLOC_SIZE/el_size) {
847 0 : if (free_on_fail)
848 0 : SAFE_FREE(ptr);
849 0 : return NULL;
850 : }
851 24039 : if (!ptr) {
852 22602 : return malloc(el_size * count);
853 : }
854 1437 : return realloc(ptr, el_size * count);
855 : }
856 :
857 : /****************************************************************************
858 : Type-safe malloc.
859 : ****************************************************************************/
860 :
861 21277 : void *malloc_array(size_t el_size, unsigned int count)
862 : {
863 21277 : return realloc_array(NULL, el_size, count, false);
864 : }
865 :
866 : /****************************************************************************
867 : Type-safe memalign
868 : ****************************************************************************/
869 :
870 0 : void *memalign_array(size_t el_size, size_t align, unsigned int count)
871 : {
872 0 : if (el_size == 0 || count >= MAX_MALLOC_SIZE/el_size) {
873 0 : return NULL;
874 : }
875 :
876 0 : return memalign(align, el_size*count);
877 : }
878 :
879 : /****************************************************************************
880 : Type-safe calloc.
881 : ****************************************************************************/
882 :
883 0 : void *calloc_array(size_t size, size_t nmemb)
884 : {
885 0 : if (nmemb >= MAX_MALLOC_SIZE/size) {
886 0 : return NULL;
887 : }
888 0 : if (size == 0 || nmemb == 0) {
889 0 : return NULL;
890 : }
891 0 : return calloc(nmemb, size);
892 : }
893 :
894 : /**
895 : Trim the specified elements off the front and back of a string.
896 : **/
897 243510 : _PUBLIC_ bool trim_string(char *s, const char *front, const char *back)
898 : {
899 243510 : bool ret = false;
900 : size_t front_len;
901 : size_t back_len;
902 : size_t len;
903 :
904 : /* Ignore null or empty strings. */
905 243510 : if (!s || (s[0] == '\0')) {
906 0 : return false;
907 : }
908 243510 : len = strlen(s);
909 :
910 243510 : front_len = front? strlen(front) : 0;
911 243510 : back_len = back? strlen(back) : 0;
912 :
913 243510 : if (front_len) {
914 2 : size_t front_trim = 0;
915 :
916 5 : while (strncmp(s+front_trim, front, front_len)==0) {
917 2 : front_trim += front_len;
918 : }
919 2 : if (front_trim > 0) {
920 : /* Must use memmove here as src & dest can
921 : * easily overlap. Found by valgrind. JRA. */
922 2 : memmove(s, s+front_trim, (len-front_trim)+1);
923 2 : len -= front_trim;
924 2 : ret=true;
925 : }
926 : }
927 :
928 243510 : if (back_len) {
929 458393 : while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
930 4693 : s[len-back_len]='\0';
931 4693 : len -= back_len;
932 4693 : ret=true;
933 : }
934 : }
935 243510 : return ret;
936 : }
937 :
938 : /**
939 : Find the number of 'c' chars in a string
940 : **/
941 3374 : _PUBLIC_ _PURE_ size_t count_chars(const char *s, char c)
942 : {
943 3374 : size_t count = 0;
944 :
945 126270 : while (*s) {
946 120539 : if (*s == c) count++;
947 120539 : s ++;
948 : }
949 :
950 3374 : return count;
951 : }
952 :
953 : /**
954 : * Routine to get hex characters and turn them into a byte array.
955 : * the array can be variable length.
956 : * - "0xnn" or "0Xnn" is specially catered for.
957 : * - The first non-hex-digit character (apart from possibly leading "0x"
958 : * finishes the conversion and skips the rest of the input.
959 : * - A single hex-digit character at the end of the string is skipped.
960 : *
961 : * valid examples: "0A5D15"; "0x123456"
962 : */
963 3823018 : _PUBLIC_ size_t strhex_to_str(char *p, size_t p_len, const char *strhex, size_t strhex_len)
964 : {
965 3823018 : size_t i = 0;
966 3823018 : size_t num_chars = 0;
967 :
968 : /* skip leading 0x prefix */
969 3823018 : if (strncasecmp(strhex, "0x", 2) == 0) {
970 0 : i += 2; /* skip two chars */
971 : }
972 :
973 135067315 : while ((i < strhex_len) && (num_chars < p_len)) {
974 127674095 : bool ok = hex_byte(&strhex[i], (uint8_t *)&p[num_chars]);
975 127674095 : if (!ok) {
976 0 : break;
977 : }
978 127674095 : i += 2;
979 127674095 : num_chars += 1;
980 : }
981 :
982 3823018 : return num_chars;
983 : }
984 :
985 : /**
986 : * Parse a hex string and return a data blob.
987 : */
988 191689 : _PUBLIC_ DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
989 : {
990 191689 : DATA_BLOB ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
991 :
992 191689 : ret_blob.length = strhex_to_str((char *)ret_blob.data, ret_blob.length,
993 : strhex,
994 : strlen(strhex));
995 :
996 191689 : return ret_blob;
997 : }
998 :
999 : /**
1000 : * Parse a hex dump and return a data blob. Hex dump is structured as
1001 : * is generated from dump_data_cb() elsewhere in this file
1002 : *
1003 : */
1004 0 : _PUBLIC_ DATA_BLOB hexdump_to_data_blob(TALLOC_CTX *mem_ctx, const char *hexdump, size_t hexdump_len)
1005 : {
1006 0 : DATA_BLOB ret_blob = { 0 };
1007 0 : size_t i = 0;
1008 0 : size_t char_count = 0;
1009 : /* hexdump line length is 77 chars long. We then use the ASCII representation of the bytes
1010 : * at the end of the final line to calculate how many are in that line, minus the extra space
1011 : * and newline. */
1012 0 : size_t hexdump_byte_count = (16 * (hexdump_len / 77));
1013 0 : if (hexdump_len % 77) {
1014 0 : hexdump_byte_count += ((hexdump_len % 77) - 59 - 2);
1015 : }
1016 :
1017 0 : ret_blob = data_blob_talloc(mem_ctx, NULL, hexdump_byte_count+1);
1018 0 : for (; i+1 < hexdump_len && hexdump[i] != 0 && hexdump[i+1] != 0; i++) {
1019 0 : if ((i%77) == 0)
1020 0 : i += 7; /* Skip the offset at the start of the line */
1021 0 : if ((i%77) < 56) { /* position 56 is after both hex chunks */
1022 0 : if (hexdump[i] != ' ') {
1023 0 : char_count += strhex_to_str((char *)&ret_blob.data[char_count],
1024 : hexdump_byte_count - char_count,
1025 : &hexdump[i], 2);
1026 0 : i += 2;
1027 : } else {
1028 0 : i++;
1029 : }
1030 : } else {
1031 0 : i++;
1032 : }
1033 : }
1034 0 : ret_blob.length = char_count;
1035 :
1036 0 : return ret_blob;
1037 : }
1038 :
1039 : /**
1040 : * Print a buf in hex. Assumes dst is at least (srclen*2)+1 large.
1041 : */
1042 6024 : _PUBLIC_ void hex_encode_buf(char *dst, const uint8_t *src, size_t srclen)
1043 : {
1044 : size_t i;
1045 156891 : for (i=0; i<srclen; i++) {
1046 150867 : snprintf(dst + i*2, 3, "%02X", src[i]);
1047 : }
1048 : /*
1049 : * Ensure 0-termination for 0-length buffers
1050 : */
1051 6024 : dst[srclen*2] = '\0';
1052 6024 : }
1053 :
1054 : /**
1055 : * talloc version of hex_encode_buf()
1056 : */
1057 6020 : _PUBLIC_ char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
1058 : {
1059 : char *hex_buffer;
1060 :
1061 6020 : hex_buffer = talloc_array(mem_ctx, char, (len*2)+1);
1062 6020 : if (!hex_buffer) {
1063 0 : return NULL;
1064 : }
1065 6020 : hex_encode_buf(hex_buffer, buff_in, len);
1066 6020 : talloc_set_name_const(hex_buffer, hex_buffer);
1067 6020 : return hex_buffer;
1068 : }
1069 :
1070 : /**
1071 : varient of strcmp() that handles NULL ptrs
1072 : **/
1073 159024 : _PUBLIC_ int strcmp_safe(const char *s1, const char *s2)
1074 : {
1075 159024 : if (s1 == s2) {
1076 613 : return 0;
1077 : }
1078 158411 : if (s1 == NULL || s2 == NULL) {
1079 0 : return s1?-1:1;
1080 : }
1081 158411 : return strcmp(s1, s2);
1082 : }
1083 :
1084 :
1085 : /**
1086 : return the number of bytes occupied by a buffer in ASCII format
1087 : the result includes the null termination
1088 : limited by 'n' bytes
1089 : **/
1090 1155889 : _PUBLIC_ size_t ascii_len_n(const char *src, size_t n)
1091 : {
1092 : size_t len;
1093 :
1094 1155889 : len = strnlen(src, n);
1095 1155889 : if (len+1 <= n) {
1096 1155889 : len += 1;
1097 : }
1098 :
1099 1155889 : return len;
1100 : }
1101 :
1102 2164243 : _PUBLIC_ bool mem_equal_const_time(const void *s1, const void *s2, size_t n)
1103 : {
1104 : /* Ensure we won't overflow the unsigned index used by gnutls. */
1105 2164243 : SMB_ASSERT(n <= UINT_MAX);
1106 :
1107 2164243 : return gnutls_memcmp(s1, s2, n) == 0;
1108 : }
1109 :
1110 : struct anonymous_shared_header {
1111 : union {
1112 : size_t length;
1113 : uint8_t pad[16];
1114 : } u;
1115 : };
1116 :
1117 : /* Map a shared memory buffer of at least nelem counters. */
1118 1059 : void *anonymous_shared_allocate(size_t orig_bufsz)
1119 : {
1120 : void *ptr;
1121 : void *buf;
1122 1059 : size_t pagesz = getpagesize();
1123 : size_t pagecnt;
1124 1059 : size_t bufsz = orig_bufsz;
1125 : struct anonymous_shared_header *hdr;
1126 :
1127 1059 : bufsz += sizeof(*hdr);
1128 :
1129 : /* round up to full pages */
1130 1059 : pagecnt = bufsz / pagesz;
1131 1059 : if (bufsz % pagesz) {
1132 1059 : pagecnt += 1;
1133 : }
1134 1059 : bufsz = pagesz * pagecnt;
1135 :
1136 1059 : if (orig_bufsz >= bufsz) {
1137 : /* integer wrap */
1138 0 : errno = ENOMEM;
1139 0 : return NULL;
1140 : }
1141 :
1142 : #ifdef MAP_ANON
1143 : /* BSD */
1144 1059 : buf = mmap(NULL, bufsz, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED,
1145 : -1 /* fd */, 0 /* offset */);
1146 : #else
1147 : {
1148 : int saved_errno;
1149 : int fd;
1150 :
1151 : fd = open("/dev/zero", O_RDWR);
1152 : if (fd == -1) {
1153 : return NULL;
1154 : }
1155 :
1156 : buf = mmap(NULL, bufsz, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
1157 : fd, 0 /* offset */);
1158 : saved_errno = errno;
1159 : close(fd);
1160 : errno = saved_errno;
1161 : }
1162 : #endif
1163 :
1164 1059 : if (buf == MAP_FAILED) {
1165 0 : return NULL;
1166 : }
1167 :
1168 1059 : hdr = (struct anonymous_shared_header *)buf;
1169 1059 : hdr->u.length = bufsz;
1170 :
1171 1059 : ptr = (void *)(&hdr[1]);
1172 :
1173 1059 : return ptr;
1174 : }
1175 :
1176 0 : void *anonymous_shared_resize(void *ptr, size_t new_size, bool maymove)
1177 : {
1178 : #ifdef HAVE_MREMAP
1179 : void *buf;
1180 0 : size_t pagesz = getpagesize();
1181 : size_t pagecnt;
1182 : size_t bufsz;
1183 : struct anonymous_shared_header *hdr;
1184 0 : int flags = 0;
1185 :
1186 0 : if (ptr == NULL) {
1187 0 : errno = EINVAL;
1188 0 : return NULL;
1189 : }
1190 :
1191 0 : hdr = (struct anonymous_shared_header *)ptr;
1192 0 : hdr--;
1193 0 : if (hdr->u.length > (new_size + sizeof(*hdr))) {
1194 0 : errno = EINVAL;
1195 0 : return NULL;
1196 : }
1197 :
1198 0 : bufsz = new_size + sizeof(*hdr);
1199 :
1200 : /* round up to full pages */
1201 0 : pagecnt = bufsz / pagesz;
1202 0 : if (bufsz % pagesz) {
1203 0 : pagecnt += 1;
1204 : }
1205 0 : bufsz = pagesz * pagecnt;
1206 :
1207 0 : if (new_size >= bufsz) {
1208 : /* integer wrap */
1209 0 : errno = ENOSPC;
1210 0 : return NULL;
1211 : }
1212 :
1213 0 : if (bufsz <= hdr->u.length) {
1214 0 : return ptr;
1215 : }
1216 :
1217 0 : if (maymove) {
1218 0 : flags = MREMAP_MAYMOVE;
1219 : }
1220 :
1221 0 : buf = mremap(hdr, hdr->u.length, bufsz, flags);
1222 :
1223 0 : if (buf == MAP_FAILED) {
1224 0 : errno = ENOSPC;
1225 0 : return NULL;
1226 : }
1227 :
1228 0 : hdr = (struct anonymous_shared_header *)buf;
1229 0 : hdr->u.length = bufsz;
1230 :
1231 0 : ptr = (void *)(&hdr[1]);
1232 :
1233 0 : return ptr;
1234 : #else
1235 : errno = ENOSPC;
1236 : return NULL;
1237 : #endif
1238 : }
1239 :
1240 1053 : void anonymous_shared_free(void *ptr)
1241 : {
1242 : struct anonymous_shared_header *hdr;
1243 :
1244 1053 : if (ptr == NULL) {
1245 0 : return;
1246 : }
1247 :
1248 1053 : hdr = (struct anonymous_shared_header *)ptr;
1249 :
1250 1053 : hdr--;
1251 :
1252 1053 : munmap(hdr, hdr->u.length);
1253 : }
1254 :
1255 : #ifdef DEVELOPER
1256 : /* used when you want a debugger started at a particular point in the
1257 : code. Mostly useful in code that runs as a child process, where
1258 : normal gdb attach is harder to organise.
1259 : */
1260 0 : void samba_start_debugger(void)
1261 : {
1262 : int ready_pipe[2];
1263 : char c;
1264 : int ret;
1265 : pid_t pid;
1266 :
1267 0 : ret = pipe(ready_pipe);
1268 0 : SMB_ASSERT(ret == 0);
1269 :
1270 0 : pid = fork();
1271 0 : SMB_ASSERT(pid >= 0);
1272 :
1273 0 : if (pid) {
1274 0 : c = 0;
1275 :
1276 0 : ret = close(ready_pipe[0]);
1277 0 : SMB_ASSERT(ret == 0);
1278 : #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
1279 : /*
1280 : * Make sure the child process can attach a debugger.
1281 : *
1282 : * We don't check the error code as the debugger
1283 : * will tell us if it can't attach.
1284 : */
1285 0 : (void)prctl(PR_SET_PTRACER, pid, 0, 0, 0);
1286 : #endif
1287 0 : ret = write(ready_pipe[1], &c, 1);
1288 0 : SMB_ASSERT(ret == 1);
1289 :
1290 0 : ret = close(ready_pipe[1]);
1291 0 : SMB_ASSERT(ret == 0);
1292 :
1293 : /* Wait for gdb to attach. */
1294 0 : sleep(2);
1295 : } else {
1296 0 : char *cmd = NULL;
1297 :
1298 0 : ret = close(ready_pipe[1]);
1299 0 : SMB_ASSERT(ret == 0);
1300 :
1301 0 : ret = read(ready_pipe[0], &c, 1);
1302 0 : SMB_ASSERT(ret == 1);
1303 :
1304 0 : ret = close(ready_pipe[0]);
1305 0 : SMB_ASSERT(ret == 0);
1306 :
1307 0 : ret = asprintf(&cmd, "gdb --pid %u", getppid());
1308 0 : SMB_ASSERT(ret != -1);
1309 :
1310 0 : execlp("xterm", "xterm", "-e", cmd, (char *) NULL);
1311 0 : smb_panic("execlp() failed");
1312 : }
1313 0 : }
1314 : #endif
|