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