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