2 Unix SMB/CIFS implementation.
3 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-2001
6 Copyright (C) Simo Sorce 2001-2002
7 Copyright (C) Martin Pool 2003
8 Copyright (C) James Peach 2006
9 Copyright (C) Jeremy Allison 1992-2007
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.
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.
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/>.
27 const char toupper_ascii_fast_table[128] = {
28 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
29 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
30 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
31 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
32 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
33 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
34 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
35 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
39 * Case insensitive string compararison.
41 * iconv does not directly give us a way to compare strings in
42 * arbitrary unix character sets -- all we can is convert and then
43 * compare. This is expensive.
45 * As an optimization, we do a first pass that considers only the
46 * prefix of the strings that is entirely 7-bit. Within this, we
47 * check whether they have the same value.
49 * Hopefully this will often give the answer without needing to copy.
50 * In particular it should speed comparisons to literal ascii strings
51 * or comparisons of strings that are "obviously" different.
53 * If we find a non-ascii character we fall back to converting via
56 * This should never be slower than convering the whole thing, and
59 * A different optimization would be to compare for bitwise equality
60 * in the binary encoding. (It would be possible thought hairy to do
61 * both simultaneously.) But in that case if they turn out to be
62 * different, we'd need to restart the whole thing.
64 * Even better is to implement strcasecmp for each encoding and use a
67 int StrCaseCmp(const char *s, const char *t)
72 smb_ucs2_t *buffer_s, *buffer_t;
75 for (ps = s, pt = t; ; ps++, pt++) {
79 return 0; /* both ended */
81 return -1; /* s is a prefix */
83 return +1; /* t is a prefix */
84 else if ((*ps & 0x80) || (*pt & 0x80))
85 /* not ascii anymore, do it the hard way
89 us = toupper_ascii_fast(*ps);
90 ut = toupper_ascii_fast(*pt);
99 if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
100 return strcmp(ps, pt);
101 /* Not quite the right answer, but finding the right one
102 under this failure case is expensive, and it's pretty
106 if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
107 TALLOC_FREE(buffer_s);
108 return strcmp(ps, pt);
109 /* Not quite the right answer, but finding the right one
110 under this failure case is expensive, and it's pretty
114 ret = strcasecmp_w(buffer_s, buffer_t);
115 TALLOC_FREE(buffer_s);
116 TALLOC_FREE(buffer_t);
122 Case insensitive string compararison, length limited.
124 int StrnCaseCmp(const char *s, const char *t, size_t len)
129 smb_ucs2_t *buffer_s, *buffer_t;
132 for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
136 return 0; /* both ended */
138 return -1; /* s is a prefix */
140 return +1; /* t is a prefix */
141 else if ((*ps & 0x80) || (*pt & 0x80))
142 /* not ascii anymore, do it the
143 * hard way from here on in */
146 us = toupper_ascii_fast(*ps);
147 ut = toupper_ascii_fast(*pt);
160 if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
161 return strncmp(ps, pt, len-n);
162 /* Not quite the right answer, but finding the right one
163 under this failure case is expensive,
164 and it's pretty close */
167 if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
168 TALLOC_FREE(buffer_s);
169 return strncmp(ps, pt, len-n);
170 /* Not quite the right answer, but finding the right one
171 under this failure case is expensive,
172 and it's pretty close */
175 ret = strncasecmp_w(buffer_s, buffer_t, len-n);
176 TALLOC_FREE(buffer_s);
177 TALLOC_FREE(buffer_t);
182 * Compare 2 strings up to and including the nth char.
184 * @note The comparison is case-insensitive.
186 bool strnequal(const char *s1,const char *s2,size_t n)
190 if (!s1 || !s2 || !n)
193 return(StrnCaseCmp(s1,s2,n)==0);
197 Convert a string to "normal" form.
200 void strnorm(char *s, int case_default)
202 if (case_default == CASE_UPPER)
209 * Skip past some strings in a buffer - old version - no checks.
212 char *push_skip_string(char *buf)
214 buf += strlen(buf) + 1;
219 Skip past a string in a buffer. Buffer may not be
220 null terminated. end_ptr points to the first byte after
221 then end of the buffer.
224 char *skip_string(const char *base, size_t len, char *buf)
226 const char *end_ptr = base + len;
228 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
232 /* Skip the string */
235 if (buf >= end_ptr) {
245 Count the number of characters in a string. Normally this will
246 be the same as the number of bytes in a string for single byte strings,
247 but will be different for multibyte.
250 size_t str_charnum(const char *s)
252 size_t ret, converted_size;
253 smb_ucs2_t *tmpbuf2 = NULL;
254 if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
257 ret = strlen_w(tmpbuf2);
258 TALLOC_FREE(tmpbuf2);
262 bool trim_char(char *s,char cfront,char cback)
268 /* Ignore null or empty strings. */
269 if (!s || (s[0] == '\0'))
273 while (*fp && *fp == cfront)
276 /* We ate the string. */
284 ep = fp + strlen(fp) - 1;
286 /* Attempt ascii only. Bail for mb strings. */
287 while ((ep >= fp) && (*ep == cback)) {
289 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
290 /* Could be mb... bail back to tim_string. */
298 return trim_string(s, cfront ? fs : NULL, bs);
304 /* We ate the string. */
311 memmove(s, fp, ep-fp+2);
316 Like strncpy but always null terminates. Make sure there is room!
317 The variable n should always be one less than the available size.
319 char *StrnCpy(char *dest,const char *src,size_t n)
324 smb_panic("ERROR: NULL dest in StrnCpy");
332 while (n-- && (*d = *src)) {
342 Check if a string is part of a list.
345 bool in_list(const char *s, const char *list, bool casesensitive)
355 frame = talloc_stackframe();
356 while (next_token_talloc(frame, &list, &tok,LIST_SEP)) {
358 if (strcmp(tok,s) == 0) {
363 if (StrCaseCmp(tok,s) == 0) {
373 /* this is used to prevent lots of mallocs of size 1 */
374 static const char null_string[] = "";
377 Set a string value, allocing the space for the string
380 static bool string_init(char **dest,const char *src)
390 *dest = CONST_DISCARD(char*, null_string);
392 (*dest) = SMB_STRDUP(src);
393 if ((*dest) == NULL) {
394 DEBUG(0,("Out of memory in string_init\n"));
405 void string_free(char **s)
409 if (*s == null_string)
415 Set a string value, deallocating any existing space, and allocing the space
419 bool string_set(char **dest,const char *src)
422 return(string_init(dest,src));
425 void fstring_sub(char *s,const char *pattern,const char *insert)
427 string_sub(s, pattern, insert, sizeof(fstring));
431 Similar to string_sub2, but it will accept only allocated strings
432 and may realloc them so pay attention at what you pass on no
433 pointers inside strings, no const may be passed
437 char *realloc_string_sub2(char *string,
440 bool remove_unsafe_characters,
441 bool allow_trailing_dollar)
445 ssize_t ls,lp,li,ld, i;
447 if (!insert || !pattern || !*pattern || !string || !*string)
452 in = SMB_STRDUP(insert);
454 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
457 ls = (ssize_t)strlen(s);
458 lp = (ssize_t)strlen(pattern);
459 li = (ssize_t)strlen(insert);
464 /* allow a trailing $
465 * (as in machine accounts) */
466 if (allow_trailing_dollar && (i == li - 1 )) {
476 if ( remove_unsafe_characters ) {
486 while ((p = strstr_m(s,pattern))) {
488 int offset = PTR_DIFF(s,string);
489 string = (char *)SMB_REALLOC(string, ls + ld + 1);
491 DEBUG(0, ("realloc_string_sub: "
492 "out of memory!\n"));
496 p = string + offset + (p - s);
499 memmove(p+li,p+lp,strlen(p+lp)+1);
509 char *realloc_string_sub(char *string,
513 return realloc_string_sub2(string, pattern, insert, true, false);
517 * Internal guts of talloc_string_sub and talloc_all_string_sub.
518 * talloc version of string_sub2.
521 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
524 bool remove_unsafe_characters,
526 bool allow_trailing_dollar)
531 ssize_t ls,lp,li,ld, i;
533 if (!insert || !pattern || !*pattern || !src) {
537 string = talloc_strdup(mem_ctx, src);
538 if (string == NULL) {
539 DEBUG(0, ("talloc_string_sub2: "
540 "talloc_strdup failed\n"));
546 in = SMB_STRDUP(insert);
548 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
551 ls = (ssize_t)strlen(s);
552 lp = (ssize_t)strlen(pattern);
553 li = (ssize_t)strlen(insert);
559 /* allow a trailing $
560 * (as in machine accounts) */
561 if (allow_trailing_dollar && (i == li - 1 )) {
571 if (remove_unsafe_characters) {
581 while ((p = strstr_m(s,pattern))) {
583 int offset = PTR_DIFF(s,string);
584 string = (char *)TALLOC_REALLOC(mem_ctx, string,
587 DEBUG(0, ("talloc_string_sub: out of "
592 p = string + offset + (p - s);
595 memmove(p+li,p+lp,strlen(p+lp)+1);
609 /* Same as string_sub, but returns a talloc'ed string */
611 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
616 return talloc_string_sub2(mem_ctx, src, pattern, insert,
620 char *talloc_all_string_sub(TALLOC_CTX *ctx,
625 return talloc_string_sub2(ctx, src, pattern, insert,
626 false, false, false);
630 Write an octal as a string.
633 char *octal_string(int i)
637 result = talloc_strdup(talloc_tos(), "-1");
640 result = talloc_asprintf(talloc_tos(), "0%o", i);
642 SMB_ASSERT(result != NULL);
648 Truncate a string at a specified length.
651 char *string_truncate(char *s, unsigned int length)
653 if (s && strlen(s) > length)
659 /***********************************************************************
660 Return the equivalent of doing strrchr 'n' times - always going
662 ***********************************************************************/
664 char *strnrchr_m(const char *s, char c, unsigned int n)
666 smb_ucs2_t *ws = NULL;
670 size_t converted_size;
672 if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
673 /* Too hard to try and get right. */
676 p = strnrchr_w(ws, UCS2_CHAR(c), n);
682 if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
684 /* Too hard to try and get right. */
687 ret = (char *)(s+strlen(s2));
693 static bool unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
696 smb_ucs2_t *buffer = NULL;
699 if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
700 (void **)(void *)&buffer, &size))
702 smb_panic("failed to create UCS2 buffer");
704 if (!strlower_w(buffer) && (dest == src)) {
708 ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
713 #if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
716 Convert a string to lower case.
718 _PUBLIC_ void strlower_m(char *s)
721 struct smb_iconv_handle *iconv_handle;
723 iconv_handle = get_iconv_handle();
728 size_t c_size, c_size2;
729 codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
730 c_size2 = push_codepoint_handle(iconv_handle, d, tolower_m(c));
731 if (c_size2 > c_size) {
732 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
733 c, tolower_m(c), (int)c_size, (int)c_size2));
734 smb_panic("codepoint expansion in strlower_m\n");
745 Convert a string to lower case.
748 void strlower_m(char *s)
753 /* this is quite a common operation, so we want it to be
754 fast. We optimise for the ascii case, knowing that all our
755 supported multi-byte character sets are ascii-compatible
756 (ie. they match for the first 128 chars) */
758 while (*s && !(((unsigned char)s[0]) & 0x80)) {
759 *s = tolower_ascii((unsigned char)*s);
766 /* I assume that lowercased string takes the same number of bytes
767 * as source string even in UTF-8 encoding. (VIV) */
771 unix_strlower(s,len,s,len);
772 /* Catch mb conversion errors that may not terminate. */
778 static bool unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
784 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
788 if (!strupper_w(buffer) && (dest == src)) {
793 ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
798 #if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
801 Convert a string to UPPER case.
803 _PUBLIC_ void strupper_m(char *s)
806 struct smb_iconv_handle *iconv_handle;
808 iconv_handle = get_iconv_handle();
813 size_t c_size, c_size2;
814 codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
815 c_size2 = push_codepoint_handle(iconv_handle, d, toupper_m(c));
816 if (c_size2 > c_size) {
817 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
818 c, toupper_m(c), (int)c_size, (int)c_size2));
819 smb_panic("codepoint expansion in strupper_m\n");
830 Convert a string to upper case.
833 void strupper_m(char *s)
838 /* this is quite a common operation, so we want it to be
839 fast. We optimise for the ascii case, knowing that all our
840 supported multi-byte character sets are ascii-compatible
841 (ie. they match for the first 128 chars) */
843 while (*s && !(((unsigned char)s[0]) & 0x80)) {
844 *s = toupper_ascii_fast((unsigned char)*s);
851 /* I assume that lowercased string takes the same number of bytes
852 * as source string even in multibyte encoding. (VIV) */
856 unix_strupper(s,len,s,len);
857 /* Catch mb conversion errors that may not terminate. */
864 Just a typesafety wrapper for snprintf into a fstring.
867 int fstr_sprintf(fstring s, const char *fmt, ...)
873 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
879 List of Strings manipulation functions
882 #define S_LIST_ABS 16 /* List Allocation Block Size */
884 /******************************************************************************
885 version of standard_sub_basic() for string lists; uses talloc_sub_basic()
887 *****************************************************************************/
889 bool str_list_sub_basic( char **list, const char *smb_name,
890 const char *domain_name )
892 TALLOC_CTX *ctx = list;
897 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
899 DEBUG(0,("str_list_sub_basic: "
900 "alloc_sub_basic() return NULL!\n"));
913 /******************************************************************************
914 substitute a specific pattern in a string list
915 *****************************************************************************/
917 bool str_list_substitute(char **list, const char *pattern, const char *insert)
919 TALLOC_CTX *ctx = list;
921 ssize_t ls, lp, li, ld, i, d;
930 lp = (ssize_t)strlen(pattern);
931 li = (ssize_t)strlen(insert);
936 ls = (ssize_t)strlen(s);
938 while ((p = strstr_m(s, pattern))) {
942 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
944 DEBUG(0,("str_list_substitute: "
945 "Unable to allocate memory"));
949 memcpy(t +d +li, p +lp, ls -d -lp +1);
956 for (i = 0; i < li; i++) {
981 #define IPSTR_LIST_SEP ","
982 #define IPSTR_LIST_CHAR ','
985 * Add ip string representation to ipstr list. Used also
986 * as part of @function ipstr_list_make
988 * @param ipstr_list pointer to string containing ip list;
989 * MUST BE already allocated and IS reallocated if necessary
990 * @param ipstr_size pointer to current size of ipstr_list (might be changed
991 * as a result of reallocation)
992 * @param ip IP address which is to be added to list
993 * @return pointer to string appended with new ip and possibly
994 * reallocated to new length
997 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
999 char *new_ipstr = NULL;
1000 char addr_buf[INET6_ADDRSTRLEN];
1003 /* arguments checking */
1004 if (!ipstr_list || !service) {
1008 print_sockaddr(addr_buf,
1012 /* attempt to convert ip to a string and append colon separator to it */
1014 if (service->ss.ss_family == AF_INET) {
1016 ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
1017 IPSTR_LIST_SEP, addr_buf,
1021 ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
1022 IPSTR_LIST_SEP, addr_buf,
1025 SAFE_FREE(*ipstr_list);
1027 if (service->ss.ss_family == AF_INET) {
1029 ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
1033 ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
1040 *ipstr_list = new_ipstr;
1045 * Allocate and initialise an ipstr list using ip adresses
1046 * passed as arguments.
1048 * @param ipstr_list pointer to string meant to be allocated and set
1049 * @param ip_list array of ip addresses to place in the list
1050 * @param ip_count number of addresses stored in ip_list
1051 * @return pointer to allocated ip string
1054 char *ipstr_list_make(char **ipstr_list,
1055 const struct ip_service *ip_list,
1060 /* arguments checking */
1061 if (!ip_list || !ipstr_list) {
1067 /* process ip addresses given as arguments */
1068 for (i = 0; i < ip_count; i++) {
1069 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1072 return (*ipstr_list);
1077 * Parse given ip string list into array of ip addresses
1078 * (as ip_service structures)
1079 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
1081 * @param ipstr ip string list to be parsed
1082 * @param ip_list pointer to array of ip addresses which is
1083 * allocated by this function and must be freed by caller
1084 * @return number of successfully parsed addresses
1087 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
1090 char *token_str = NULL;
1094 if (!ipstr_list || !ip_list)
1097 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1098 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1099 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
1100 (unsigned long)count));
1104 frame = talloc_stackframe();
1105 for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
1106 IPSTR_LIST_SEP) && i<count; i++ ) {
1107 char *s = token_str;
1108 char *p = strrchr(token_str, ':');
1112 (*ip_list)[i].port = atoi(p+1);
1115 /* convert single token to ip address */
1116 if (token_str[0] == '[') {
1119 p = strchr(token_str, ']');
1125 if (!interpret_string_addr(&(*ip_list)[i].ss,
1136 * Safely free ip string list
1138 * @param ipstr_list ip string list to be freed
1141 void ipstr_list_free(char* ipstr_list)
1143 SAFE_FREE(ipstr_list);
1146 /* read a SMB_BIG_UINT from a string */
1147 uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1150 uint64_t val = (uint64_t)-1;
1151 const char *p = nptr;
1160 while (*p && isspace(*p))
1163 sscanf(p,"%"PRIu64,&val);
1165 while (*p && isdigit(*p))
1173 /* Convert a size specification to a count of bytes. We accept the following
1175 * bytes if there is no suffix
1180 * pP whatever the ISO name for petabytes is
1182 * Returns 0 if the string can't be converted.
1184 uint64_t conv_str_size(const char * str)
1190 if (str == NULL || *str == '\0') {
1194 lval = strtoull(str, &end, 10 /* base */);
1196 if (end == NULL || end == str) {
1206 if (strwicmp(end, "K") == 0) {
1208 } else if (strwicmp(end, "M") == 0) {
1209 lval *= (1024ULL * 1024ULL);
1210 } else if (strwicmp(end, "G") == 0) {
1211 lval *= (1024ULL * 1024ULL *
1213 } else if (strwicmp(end, "T") == 0) {
1214 lval *= (1024ULL * 1024ULL *
1216 } else if (strwicmp(end, "P") == 0) {
1217 lval *= (1024ULL * 1024ULL *
1227 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
1228 * error checking in between. The indiation that something weird happened is
1231 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
1232 size_t *bufsize, const char *fmt, ...)
1239 /* len<0 is an internal marker that something failed */
1243 if (*string == NULL) {
1247 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
1248 if (*string == NULL)
1253 ret = vasprintf(&newstr, fmt, ap);
1261 while ((*len)+ret >= *bufsize) {
1264 if (*bufsize >= (1024*1024*256))
1269 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
1271 if (*string == NULL) {
1276 StrnCpy((*string)+(*len), newstr, ret);
1287 * asprintf into a string and strupper_m it after that.
1290 int asprintf_strupper_m(char **strp, const char *fmt, ...)
1297 ret = vasprintf(&result, fmt, ap);
1308 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
1314 ret = talloc_vasprintf(t, fmt, ap);
1324 char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
1330 ret = talloc_vasprintf(t, fmt, ap);
1342 Returns the substring from src between the first occurrence of
1343 the char "front" and the first occurence of the char "back".
1344 Mallocs the return string which must be freed. Not for use
1345 with wide character strings.
1347 char *sstring_sub(const char *src, char front, char back)
1349 char *temp1, *temp2, *temp3;
1352 temp1 = strchr(src, front);
1353 if (temp1 == NULL) return NULL;
1354 temp2 = strchr(src, back);
1355 if (temp2 == NULL) return NULL;
1356 len = temp2 - temp1;
1357 if (len <= 0) return NULL;
1358 temp3 = (char*)SMB_MALLOC(len);
1359 if (temp3 == NULL) {
1360 DEBUG(1,("Malloc failure in sstring_sub\n"));
1363 memcpy(temp3, temp1+1, len-1);
1364 temp3[len-1] = '\0';
1368 /********************************************************************
1369 Check a string for any occurrences of a specified list of invalid
1371 ********************************************************************/
1373 bool validate_net_name( const char *name,
1374 const char *invalid_chars,
1383 for ( i=0; i<max_len && name[i]; i++ ) {
1384 /* fail if strchr_m() finds one of the invalid characters */
1385 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
1394 /*******************************************************************
1395 Add a shell escape character '\' to any character not in a known list
1396 of characters. UNIX charset format.
1397 *******************************************************************/
1399 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
1400 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
1402 char *escape_shell_string(const char *src)
1404 size_t srclen = strlen(src);
1405 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
1407 bool in_s_quote = false;
1408 bool in_d_quote = false;
1409 bool next_escaped = false;
1417 codepoint_t c = next_codepoint(src, &c_size);
1419 if (c == INVALID_CODEPOINT) {
1425 memcpy(dest, src, c_size);
1428 next_escaped = false;
1433 * Deal with backslash escaped state.
1434 * This only lasts for one character.
1439 next_escaped = false;
1444 * Deal with single quote state. The
1445 * only thing we care about is exiting
1458 * Deal with double quote state. The most
1459 * complex state. We must cope with \, meaning
1460 * possibly escape next char (depending what it
1461 * is), ", meaning exit this state, and possibly
1462 * add an \ escape to any unprotected character
1463 * (listed in INSIDE_DQUOTE_LIST).
1469 * Next character might be escaped.
1470 * We have to peek. Inside double
1471 * quotes only INSIDE_DQUOTE_LIST
1472 * characters are escaped by a \.
1477 c = next_codepoint(&src[1], &c_size);
1478 if (c == INVALID_CODEPOINT) {
1484 * Don't escape the next char.
1493 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
1495 next_escaped = true;
1502 /* Exit double quote state. */
1509 * We know the character isn't \ or ",
1510 * so escape it if it's any of the other
1511 * possible unprotected characters.
1514 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
1522 * From here to the end of the loop we're
1523 * not in the single or double quote state.
1527 /* Next character must be escaped. */
1528 next_escaped = true;
1534 /* Go into single quote state. */
1541 /* Go into double quote state. */
1547 /* Check if we need to escape the character. */
1549 if (!strchr(INCLUDE_LIST, (int)*src)) {
1558 /***************************************************
1559 str_list_make, v3 version. The v4 version does not
1560 look at quoted strings with embedded blanks, so
1561 do NOT merge this function please!
1562 ***************************************************/
1564 #define S_LIST_ABS 16 /* List Allocation Block Size */
1566 char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
1574 if (!string || !*string)
1577 list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
1583 s = talloc_strdup(list, string);
1585 DEBUG(0,("str_list_make: Unable to allocate memory"));
1589 if (!sep) sep = LIST_SEP;
1594 while (next_token_talloc(list, &str, &tok, sep)) {
1599 lsize += S_LIST_ABS;
1601 tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
1604 DEBUG(0,("str_list_make: "
1605 "Unable to allocate memory"));
1612 memset (&list[num], 0,
1613 ((sizeof(char**)) * (S_LIST_ABS +1)));
1626 char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
1630 alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
1631 return talloc_strdup(mem_ctx, tmp);