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, length limited.
41 int StrnCaseCmp(const char *s, const char *t, size_t len)
46 smb_ucs2_t *buffer_s, *buffer_t;
49 for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
53 return 0; /* both ended */
55 return -1; /* s is a prefix */
57 return +1; /* t is a prefix */
58 else if ((*ps & 0x80) || (*pt & 0x80))
59 /* not ascii anymore, do it the
60 * hard way from here on in */
63 us = toupper_ascii_fast(*ps);
64 ut = toupper_ascii_fast(*pt);
77 if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
78 return strncmp(ps, pt, len-n);
79 /* Not quite the right answer, but finding the right one
80 under this failure case is expensive,
81 and it's pretty close */
84 if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
85 TALLOC_FREE(buffer_s);
86 return strncmp(ps, pt, len-n);
87 /* Not quite the right answer, but finding the right one
88 under this failure case is expensive,
89 and it's pretty close */
92 ret = strncasecmp_w(buffer_s, buffer_t, len-n);
93 TALLOC_FREE(buffer_s);
94 TALLOC_FREE(buffer_t);
99 * Compare 2 strings up to and including the nth char.
101 * @note The comparison is case-insensitive.
103 bool strnequal(const char *s1,const char *s2,size_t n)
107 if (!s1 || !s2 || !n)
110 return(StrnCaseCmp(s1,s2,n)==0);
114 Convert a string to "normal" form.
117 void strnorm(char *s, int case_default)
119 if (case_default == CASE_UPPER)
126 * Skip past some strings in a buffer - old version - no checks.
129 char *push_skip_string(char *buf)
131 buf += strlen(buf) + 1;
136 Skip past a string in a buffer. Buffer may not be
137 null terminated. end_ptr points to the first byte after
138 then end of the buffer.
141 char *skip_string(const char *base, size_t len, char *buf)
143 const char *end_ptr = base + len;
145 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
149 /* Skip the string */
152 if (buf >= end_ptr) {
162 Count the number of characters in a string. Normally this will
163 be the same as the number of bytes in a string for single byte strings,
164 but will be different for multibyte.
167 size_t str_charnum(const char *s)
169 size_t ret, converted_size;
170 smb_ucs2_t *tmpbuf2 = NULL;
171 if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
174 ret = strlen_w(tmpbuf2);
175 TALLOC_FREE(tmpbuf2);
179 bool trim_char(char *s,char cfront,char cback)
185 /* Ignore null or empty strings. */
186 if (!s || (s[0] == '\0'))
190 while (*fp && *fp == cfront)
193 /* We ate the string. */
201 ep = fp + strlen(fp) - 1;
203 /* Attempt ascii only. Bail for mb strings. */
204 while ((ep >= fp) && (*ep == cback)) {
206 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
207 /* Could be mb... bail back to tim_string. */
215 return trim_string(s, cfront ? fs : NULL, bs);
221 /* We ate the string. */
228 memmove(s, fp, ep-fp+2);
233 Like strncpy but always null terminates. Make sure there is room!
234 The variable n should always be one less than the available size.
236 char *StrnCpy(char *dest,const char *src,size_t n)
241 smb_panic("ERROR: NULL dest in StrnCpy");
249 while (n-- && (*d = *src)) {
259 Check if a string is part of a list.
262 bool in_list(const char *s, const char *list, bool casesensitive)
272 frame = talloc_stackframe();
273 while (next_token_talloc(frame, &list, &tok,LIST_SEP)) {
275 if (strcmp(tok,s) == 0) {
280 if (strcasecmp_m(tok,s) == 0) {
290 /* this is used to prevent lots of mallocs of size 1 */
291 static const char null_string[] = "";
294 Set a string value, allocing the space for the string
297 static bool string_init(char **dest,const char *src)
307 *dest = discard_const_p(char, null_string);
309 (*dest) = SMB_STRDUP(src);
310 if ((*dest) == NULL) {
311 DEBUG(0,("Out of memory in string_init\n"));
322 void string_free(char **s)
326 if (*s == null_string)
332 Set a string value, deallocating any existing space, and allocing the space
336 bool string_set(char **dest,const char *src)
339 return(string_init(dest,src));
342 void fstring_sub(char *s,const char *pattern,const char *insert)
344 string_sub(s, pattern, insert, sizeof(fstring));
348 Similar to string_sub2, but it will accept only allocated strings
349 and may realloc them so pay attention at what you pass on no
350 pointers inside strings, no const may be passed
354 char *realloc_string_sub2(char *string,
357 bool remove_unsafe_characters,
358 bool allow_trailing_dollar)
362 ssize_t ls,lp,li,ld, i;
364 if (!insert || !pattern || !*pattern || !string || !*string)
369 in = SMB_STRDUP(insert);
371 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
374 ls = (ssize_t)strlen(s);
375 lp = (ssize_t)strlen(pattern);
376 li = (ssize_t)strlen(insert);
381 /* allow a trailing $
382 * (as in machine accounts) */
383 if (allow_trailing_dollar && (i == li - 1 )) {
393 if ( remove_unsafe_characters ) {
403 while ((p = strstr_m(s,pattern))) {
405 int offset = PTR_DIFF(s,string);
406 string = (char *)SMB_REALLOC(string, ls + ld + 1);
408 DEBUG(0, ("realloc_string_sub: "
409 "out of memory!\n"));
413 p = string + offset + (p - s);
416 memmove(p+li,p+lp,strlen(p+lp)+1);
426 char *realloc_string_sub(char *string,
430 return realloc_string_sub2(string, pattern, insert, true, false);
434 * Internal guts of talloc_string_sub and talloc_all_string_sub.
435 * talloc version of string_sub2.
438 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
441 bool remove_unsafe_characters,
443 bool allow_trailing_dollar)
448 ssize_t ls,lp,li,ld, i;
450 if (!insert || !pattern || !*pattern || !src) {
454 string = talloc_strdup(mem_ctx, src);
455 if (string == NULL) {
456 DEBUG(0, ("talloc_string_sub2: "
457 "talloc_strdup failed\n"));
463 in = SMB_STRDUP(insert);
465 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
468 ls = (ssize_t)strlen(s);
469 lp = (ssize_t)strlen(pattern);
470 li = (ssize_t)strlen(insert);
476 /* allow a trailing $
477 * (as in machine accounts) */
478 if (allow_trailing_dollar && (i == li - 1 )) {
488 if (remove_unsafe_characters) {
498 while ((p = strstr_m(s,pattern))) {
500 int offset = PTR_DIFF(s,string);
501 string = (char *)TALLOC_REALLOC(mem_ctx, string,
504 DEBUG(0, ("talloc_string_sub: out of "
509 p = string + offset + (p - s);
512 memmove(p+li,p+lp,strlen(p+lp)+1);
526 /* Same as string_sub, but returns a talloc'ed string */
528 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
533 return talloc_string_sub2(mem_ctx, src, pattern, insert,
537 char *talloc_all_string_sub(TALLOC_CTX *ctx,
542 return talloc_string_sub2(ctx, src, pattern, insert,
543 false, false, false);
547 Write an octal as a string.
550 char *octal_string(int i)
554 result = talloc_strdup(talloc_tos(), "-1");
557 result = talloc_asprintf(talloc_tos(), "0%o", i);
559 SMB_ASSERT(result != NULL);
565 Truncate a string at a specified length.
568 char *string_truncate(char *s, unsigned int length)
570 if (s && strlen(s) > length)
576 /***********************************************************************
577 Return the equivalent of doing strrchr 'n' times - always going
579 ***********************************************************************/
581 char *strnrchr_m(const char *s, char c, unsigned int n)
583 smb_ucs2_t *ws = NULL;
587 size_t converted_size;
589 if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
590 /* Too hard to try and get right. */
593 p = strnrchr_w(ws, UCS2_CHAR(c), n);
599 if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
601 /* Too hard to try and get right. */
604 ret = discard_const_p(char, (s+strlen(s2)));
610 static bool unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
613 smb_ucs2_t *buffer = NULL;
616 if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
617 (void **)(void *)&buffer, &size))
619 smb_panic("failed to create UCS2 buffer");
621 if (!strlower_w(buffer) && (dest == src)) {
625 ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
630 #if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
633 Convert a string to lower case.
635 _PUBLIC_ void strlower_m(char *s)
638 struct smb_iconv_handle *iconv_handle;
640 iconv_handle = get_iconv_handle();
645 size_t c_size, c_size2;
646 codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
647 c_size2 = push_codepoint_handle(iconv_handle, d, tolower_m(c));
648 if (c_size2 > c_size) {
649 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
650 c, tolower_m(c), (int)c_size, (int)c_size2));
651 smb_panic("codepoint expansion in strlower_m\n");
662 Convert a string to lower case.
665 void strlower_m(char *s)
670 /* this is quite a common operation, so we want it to be
671 fast. We optimise for the ascii case, knowing that all our
672 supported multi-byte character sets are ascii-compatible
673 (ie. they match for the first 128 chars) */
675 while (*s && !(((unsigned char)s[0]) & 0x80)) {
676 *s = tolower_ascii((unsigned char)*s);
683 /* I assume that lowercased string takes the same number of bytes
684 * as source string even in UTF-8 encoding. (VIV) */
688 unix_strlower(s,len,s,len);
689 /* Catch mb conversion errors that may not terminate. */
695 static bool unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
701 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
705 if (!strupper_w(buffer) && (dest == src)) {
710 ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
715 #if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
718 Convert a string to UPPER case.
720 _PUBLIC_ void strupper_m(char *s)
723 struct smb_iconv_handle *iconv_handle;
725 iconv_handle = get_iconv_handle();
730 size_t c_size, c_size2;
731 codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
732 c_size2 = push_codepoint_handle(iconv_handle, d, toupper_m(c));
733 if (c_size2 > c_size) {
734 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
735 c, toupper_m(c), (int)c_size, (int)c_size2));
736 smb_panic("codepoint expansion in strupper_m\n");
747 Convert a string to upper case.
750 void strupper_m(char *s)
755 /* this is quite a common operation, so we want it to be
756 fast. We optimise for the ascii case, knowing that all our
757 supported multi-byte character sets are ascii-compatible
758 (ie. they match for the first 128 chars) */
760 while (*s && !(((unsigned char)s[0]) & 0x80)) {
761 *s = toupper_ascii_fast((unsigned char)*s);
768 /* I assume that lowercased string takes the same number of bytes
769 * as source string even in multibyte encoding. (VIV) */
773 unix_strupper(s,len,s,len);
774 /* Catch mb conversion errors that may not terminate. */
781 Just a typesafety wrapper for snprintf into a fstring.
784 int fstr_sprintf(fstring s, const char *fmt, ...)
790 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
796 List of Strings manipulation functions
799 #define S_LIST_ABS 16 /* List Allocation Block Size */
801 /******************************************************************************
802 version of standard_sub_basic() for string lists; uses talloc_sub_basic()
804 *****************************************************************************/
806 bool str_list_sub_basic( char **list, const char *smb_name,
807 const char *domain_name )
809 TALLOC_CTX *ctx = list;
814 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
816 DEBUG(0,("str_list_sub_basic: "
817 "alloc_sub_basic() return NULL!\n"));
830 /******************************************************************************
831 substitute a specific pattern in a string list
832 *****************************************************************************/
834 bool str_list_substitute(char **list, const char *pattern, const char *insert)
836 TALLOC_CTX *ctx = list;
838 ssize_t ls, lp, li, ld, i, d;
847 lp = (ssize_t)strlen(pattern);
848 li = (ssize_t)strlen(insert);
853 ls = (ssize_t)strlen(s);
855 while ((p = strstr_m(s, pattern))) {
859 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
861 DEBUG(0,("str_list_substitute: "
862 "Unable to allocate memory"));
866 memcpy(t +d +li, p +lp, ls -d -lp +1);
873 for (i = 0; i < li; i++) {
898 #define IPSTR_LIST_SEP ","
899 #define IPSTR_LIST_CHAR ','
902 * Add ip string representation to ipstr list. Used also
903 * as part of @function ipstr_list_make
905 * @param ipstr_list pointer to string containing ip list;
906 * MUST BE already allocated and IS reallocated if necessary
907 * @param ipstr_size pointer to current size of ipstr_list (might be changed
908 * as a result of reallocation)
909 * @param ip IP address which is to be added to list
910 * @return pointer to string appended with new ip and possibly
911 * reallocated to new length
914 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
916 char *new_ipstr = NULL;
917 char addr_buf[INET6_ADDRSTRLEN];
920 /* arguments checking */
921 if (!ipstr_list || !service) {
925 print_sockaddr(addr_buf,
929 /* attempt to convert ip to a string and append colon separator to it */
931 if (service->ss.ss_family == AF_INET) {
933 ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
934 IPSTR_LIST_SEP, addr_buf,
938 ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
939 IPSTR_LIST_SEP, addr_buf,
942 SAFE_FREE(*ipstr_list);
944 if (service->ss.ss_family == AF_INET) {
946 ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
950 ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
957 *ipstr_list = new_ipstr;
962 * Allocate and initialise an ipstr list using ip adresses
963 * passed as arguments.
965 * @param ipstr_list pointer to string meant to be allocated and set
966 * @param ip_list array of ip addresses to place in the list
967 * @param ip_count number of addresses stored in ip_list
968 * @return pointer to allocated ip string
971 char *ipstr_list_make(char **ipstr_list,
972 const struct ip_service *ip_list,
977 /* arguments checking */
978 if (!ip_list || !ipstr_list) {
984 /* process ip addresses given as arguments */
985 for (i = 0; i < ip_count; i++) {
986 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
989 return (*ipstr_list);
994 * Parse given ip string list into array of ip addresses
995 * (as ip_service structures)
996 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
998 * @param ipstr ip string list to be parsed
999 * @param ip_list pointer to array of ip addresses which is
1000 * allocated by this function and must be freed by caller
1001 * @return number of successfully parsed addresses
1004 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
1007 char *token_str = NULL;
1011 if (!ipstr_list || !ip_list)
1014 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1015 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1016 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
1017 (unsigned long)count));
1021 frame = talloc_stackframe();
1022 for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
1023 IPSTR_LIST_SEP) && i<count; i++ ) {
1024 char *s = token_str;
1025 char *p = strrchr(token_str, ':');
1029 (*ip_list)[i].port = atoi(p+1);
1032 /* convert single token to ip address */
1033 if (token_str[0] == '[') {
1036 p = strchr(token_str, ']');
1042 if (!interpret_string_addr(&(*ip_list)[i].ss,
1053 * Safely free ip string list
1055 * @param ipstr_list ip string list to be freed
1058 void ipstr_list_free(char* ipstr_list)
1060 SAFE_FREE(ipstr_list);
1063 /* read a SMB_BIG_UINT from a string */
1064 uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1067 uint64_t val = (uint64_t)-1;
1068 const char *p = nptr;
1077 while (*p && isspace(*p))
1080 sscanf(p,"%"PRIu64,&val);
1082 while (*p && isdigit(*p))
1090 /* Convert a size specification to a count of bytes. We accept the following
1092 * bytes if there is no suffix
1097 * pP whatever the ISO name for petabytes is
1099 * Returns 0 if the string can't be converted.
1101 uint64_t conv_str_size(const char * str)
1107 if (str == NULL || *str == '\0') {
1111 lval = strtoull(str, &end, 10 /* base */);
1113 if (end == NULL || end == str) {
1123 if (strwicmp(end, "K") == 0) {
1125 } else if (strwicmp(end, "M") == 0) {
1126 lval *= (1024ULL * 1024ULL);
1127 } else if (strwicmp(end, "G") == 0) {
1128 lval *= (1024ULL * 1024ULL *
1130 } else if (strwicmp(end, "T") == 0) {
1131 lval *= (1024ULL * 1024ULL *
1133 } else if (strwicmp(end, "P") == 0) {
1134 lval *= (1024ULL * 1024ULL *
1144 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
1145 * error checking in between. The indiation that something weird happened is
1148 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
1149 size_t *bufsize, const char *fmt, ...)
1156 /* len<0 is an internal marker that something failed */
1160 if (*string == NULL) {
1164 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
1165 if (*string == NULL)
1170 ret = vasprintf(&newstr, fmt, ap);
1178 while ((*len)+ret >= *bufsize) {
1181 if (*bufsize >= (1024*1024*256))
1186 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
1188 if (*string == NULL) {
1193 StrnCpy((*string)+(*len), newstr, ret);
1204 * asprintf into a string and strupper_m it after that.
1207 int asprintf_strupper_m(char **strp, const char *fmt, ...)
1214 ret = vasprintf(&result, fmt, ap);
1225 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
1231 ret = talloc_vasprintf(t, fmt, ap);
1241 char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
1247 ret = talloc_vasprintf(t, fmt, ap);
1259 Returns the substring from src between the first occurrence of
1260 the char "front" and the first occurence of the char "back".
1261 Mallocs the return string which must be freed. Not for use
1262 with wide character strings.
1264 char *sstring_sub(const char *src, char front, char back)
1266 char *temp1, *temp2, *temp3;
1269 temp1 = strchr(src, front);
1270 if (temp1 == NULL) return NULL;
1271 temp2 = strchr(src, back);
1272 if (temp2 == NULL) return NULL;
1273 len = temp2 - temp1;
1274 if (len <= 0) return NULL;
1275 temp3 = (char*)SMB_MALLOC(len);
1276 if (temp3 == NULL) {
1277 DEBUG(1,("Malloc failure in sstring_sub\n"));
1280 memcpy(temp3, temp1+1, len-1);
1281 temp3[len-1] = '\0';
1285 /********************************************************************
1286 Check a string for any occurrences of a specified list of invalid
1288 ********************************************************************/
1290 bool validate_net_name( const char *name,
1291 const char *invalid_chars,
1300 for ( i=0; i<max_len && name[i]; i++ ) {
1301 /* fail if strchr_m() finds one of the invalid characters */
1302 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
1311 /*******************************************************************
1312 Add a shell escape character '\' to any character not in a known list
1313 of characters. UNIX charset format.
1314 *******************************************************************/
1316 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
1317 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
1319 char *escape_shell_string(const char *src)
1321 size_t srclen = strlen(src);
1322 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
1324 bool in_s_quote = false;
1325 bool in_d_quote = false;
1326 bool next_escaped = false;
1334 codepoint_t c = next_codepoint(src, &c_size);
1336 if (c == INVALID_CODEPOINT) {
1342 memcpy(dest, src, c_size);
1345 next_escaped = false;
1350 * Deal with backslash escaped state.
1351 * This only lasts for one character.
1356 next_escaped = false;
1361 * Deal with single quote state. The
1362 * only thing we care about is exiting
1375 * Deal with double quote state. The most
1376 * complex state. We must cope with \, meaning
1377 * possibly escape next char (depending what it
1378 * is), ", meaning exit this state, and possibly
1379 * add an \ escape to any unprotected character
1380 * (listed in INSIDE_DQUOTE_LIST).
1386 * Next character might be escaped.
1387 * We have to peek. Inside double
1388 * quotes only INSIDE_DQUOTE_LIST
1389 * characters are escaped by a \.
1394 c = next_codepoint(&src[1], &c_size);
1395 if (c == INVALID_CODEPOINT) {
1401 * Don't escape the next char.
1410 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
1412 next_escaped = true;
1419 /* Exit double quote state. */
1426 * We know the character isn't \ or ",
1427 * so escape it if it's any of the other
1428 * possible unprotected characters.
1431 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
1439 * From here to the end of the loop we're
1440 * not in the single or double quote state.
1444 /* Next character must be escaped. */
1445 next_escaped = true;
1451 /* Go into single quote state. */
1458 /* Go into double quote state. */
1464 /* Check if we need to escape the character. */
1466 if (!strchr(INCLUDE_LIST, (int)*src)) {
1475 /***************************************************
1476 str_list_make, v3 version. The v4 version does not
1477 look at quoted strings with embedded blanks, so
1478 do NOT merge this function please!
1479 ***************************************************/
1481 #define S_LIST_ABS 16 /* List Allocation Block Size */
1483 char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
1491 if (!string || !*string)
1494 list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
1500 s = talloc_strdup(list, string);
1502 DEBUG(0,("str_list_make: Unable to allocate memory"));
1506 if (!sep) sep = LIST_SEP;
1511 while (next_token_talloc(list, &str, &tok, sep)) {
1516 lsize += S_LIST_ABS;
1518 tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
1521 DEBUG(0,("str_list_make: "
1522 "Unable to allocate memory"));
1529 memset (&list[num], 0,
1530 ((sizeof(char**)) * (S_LIST_ABS +1)));
1543 char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
1547 alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
1548 return talloc_strdup(mem_ctx, tmp);