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 * Compare 2 strings up to and including the nth char.
41 * @note The comparison is case-insensitive.
43 bool strnequal(const char *s1,const char *s2,size_t n)
50 return(strncasecmp_m(s1,s2,n)==0);
54 Convert a string to "normal" form.
57 void strnorm(char *s, int case_default)
59 if (case_default == CASE_UPPER)
66 * Skip past some strings in a buffer - old version - no checks.
69 char *push_skip_string(char *buf)
71 buf += strlen(buf) + 1;
76 Skip past a string in a buffer. Buffer may not be
77 null terminated. end_ptr points to the first byte after
78 then end of the buffer.
81 char *skip_string(const char *base, size_t len, char *buf)
83 const char *end_ptr = base + len;
85 if (end_ptr < base || !base || !buf || buf >= end_ptr) {
102 Count the number of characters in a string. Normally this will
103 be the same as the number of bytes in a string for single byte strings,
104 but will be different for multibyte.
107 size_t str_charnum(const char *s)
109 size_t ret, converted_size;
110 smb_ucs2_t *tmpbuf2 = NULL;
111 if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
114 ret = strlen_w(tmpbuf2);
115 TALLOC_FREE(tmpbuf2);
119 bool trim_char(char *s,char cfront,char cback)
125 /* Ignore null or empty strings. */
126 if (!s || (s[0] == '\0'))
130 while (*fp && *fp == cfront)
133 /* We ate the string. */
141 ep = fp + strlen(fp) - 1;
143 /* Attempt ascii only. Bail for mb strings. */
144 while ((ep >= fp) && (*ep == cback)) {
146 if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
147 /* Could be mb... bail back to tim_string. */
155 return trim_string(s, cfront ? fs : NULL, bs);
161 /* We ate the string. */
168 memmove(s, fp, ep-fp+2);
173 Like strncpy but always null terminates. Make sure there is room!
174 The variable n should always be one less than the available size.
176 char *StrnCpy(char *dest,const char *src,size_t n)
181 smb_panic("ERROR: NULL dest in StrnCpy");
189 while (n-- && (*d = *src)) {
199 Check if a string is part of a list.
202 bool in_list(const char *s, const char *list, bool casesensitive)
212 frame = talloc_stackframe();
213 while (next_token_talloc(frame, &list, &tok,LIST_SEP)) {
215 if (strcmp(tok,s) == 0) {
220 if (strcasecmp_m(tok,s) == 0) {
230 /* this is used to prevent lots of mallocs of size 1 */
231 static const char null_string[] = "";
234 Set a string value, allocing the space for the string
237 static bool string_init(char **dest,const char *src)
247 *dest = discard_const_p(char, null_string);
249 (*dest) = SMB_STRDUP(src);
250 if ((*dest) == NULL) {
251 DEBUG(0,("Out of memory in string_init\n"));
262 void string_free(char **s)
266 if (*s == null_string)
272 Set a string value, deallocating any existing space, and allocing the space
276 bool string_set(char **dest,const char *src)
279 return(string_init(dest,src));
282 void fstring_sub(char *s,const char *pattern,const char *insert)
284 string_sub(s, pattern, insert, sizeof(fstring));
288 Similar to string_sub2, but it will accept only allocated strings
289 and may realloc them so pay attention at what you pass on no
290 pointers inside strings, no const may be passed
294 char *realloc_string_sub2(char *string,
297 bool remove_unsafe_characters,
298 bool allow_trailing_dollar)
302 ssize_t ls,lp,li,ld, i;
304 if (!insert || !pattern || !*pattern || !string || !*string)
309 in = SMB_STRDUP(insert);
311 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
314 ls = (ssize_t)strlen(s);
315 lp = (ssize_t)strlen(pattern);
316 li = (ssize_t)strlen(insert);
321 /* allow a trailing $
322 * (as in machine accounts) */
323 if (allow_trailing_dollar && (i == li - 1 )) {
333 if ( remove_unsafe_characters ) {
343 while ((p = strstr_m(s,pattern))) {
345 int offset = PTR_DIFF(s,string);
346 string = (char *)SMB_REALLOC(string, ls + ld + 1);
348 DEBUG(0, ("realloc_string_sub: "
349 "out of memory!\n"));
353 p = string + offset + (p - s);
356 memmove(p+li,p+lp,strlen(p+lp)+1);
366 char *realloc_string_sub(char *string,
370 return realloc_string_sub2(string, pattern, insert, true, false);
374 * Internal guts of talloc_string_sub and talloc_all_string_sub.
375 * talloc version of string_sub2.
378 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
381 bool remove_unsafe_characters,
383 bool allow_trailing_dollar)
388 ssize_t ls,lp,li,ld, i;
390 if (!insert || !pattern || !*pattern || !src) {
394 string = talloc_strdup(mem_ctx, src);
395 if (string == NULL) {
396 DEBUG(0, ("talloc_string_sub2: "
397 "talloc_strdup failed\n"));
403 in = SMB_STRDUP(insert);
405 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
408 ls = (ssize_t)strlen(s);
409 lp = (ssize_t)strlen(pattern);
410 li = (ssize_t)strlen(insert);
416 /* allow a trailing $
417 * (as in machine accounts) */
418 if (allow_trailing_dollar && (i == li - 1 )) {
428 if (remove_unsafe_characters) {
438 while ((p = strstr_m(s,pattern))) {
440 int offset = PTR_DIFF(s,string);
441 string = (char *)TALLOC_REALLOC(mem_ctx, string,
444 DEBUG(0, ("talloc_string_sub: out of "
449 p = string + offset + (p - s);
452 memmove(p+li,p+lp,strlen(p+lp)+1);
466 /* Same as string_sub, but returns a talloc'ed string */
468 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
473 return talloc_string_sub2(mem_ctx, src, pattern, insert,
477 char *talloc_all_string_sub(TALLOC_CTX *ctx,
482 return talloc_string_sub2(ctx, src, pattern, insert,
483 false, false, false);
487 Write an octal as a string.
490 char *octal_string(int i)
494 result = talloc_strdup(talloc_tos(), "-1");
497 result = talloc_asprintf(talloc_tos(), "0%o", i);
499 SMB_ASSERT(result != NULL);
505 Truncate a string at a specified length.
508 char *string_truncate(char *s, unsigned int length)
510 if (s && strlen(s) > length)
516 /***********************************************************************
517 Return the equivalent of doing strrchr 'n' times - always going
519 ***********************************************************************/
521 char *strnrchr_m(const char *s, char c, unsigned int n)
523 smb_ucs2_t *ws = NULL;
527 size_t converted_size;
529 if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
530 /* Too hard to try and get right. */
533 p = strnrchr_w(ws, UCS2_CHAR(c), n);
539 if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
541 /* Too hard to try and get right. */
544 ret = discard_const_p(char, (s+strlen(s2)));
550 static bool unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
553 smb_ucs2_t *buffer = NULL;
556 if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
557 (void **)(void *)&buffer, &size))
559 smb_panic("failed to create UCS2 buffer");
561 if (!strlower_w(buffer) && (dest == src)) {
565 ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
570 #if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
573 Convert a string to lower case.
575 _PUBLIC_ void strlower_m(char *s)
578 struct smb_iconv_handle *iconv_handle;
580 iconv_handle = get_iconv_handle();
585 size_t c_size, c_size2;
586 codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
587 c_size2 = push_codepoint_handle(iconv_handle, d, tolower_m(c));
588 if (c_size2 > c_size) {
589 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
590 c, tolower_m(c), (int)c_size, (int)c_size2));
591 smb_panic("codepoint expansion in strlower_m\n");
602 Convert a string to lower case.
605 void strlower_m(char *s)
610 /* this is quite a common operation, so we want it to be
611 fast. We optimise for the ascii case, knowing that all our
612 supported multi-byte character sets are ascii-compatible
613 (ie. they match for the first 128 chars) */
615 while (*s && !(((unsigned char)s[0]) & 0x80)) {
616 *s = tolower_ascii((unsigned char)*s);
623 /* I assume that lowercased string takes the same number of bytes
624 * as source string even in UTF-8 encoding. (VIV) */
628 unix_strlower(s,len,s,len);
629 /* Catch mb conversion errors that may not terminate. */
635 static bool unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
641 if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
645 if (!strupper_w(buffer) && (dest == src)) {
650 ret = convert_string(CH_UTF16LE, CH_UNIX, buffer, size, dest, destlen, &size);
655 #if 0 /* Alternate function that avoid talloc calls for ASCII and non ASCII */
658 Convert a string to UPPER case.
660 _PUBLIC_ void strupper_m(char *s)
663 struct smb_iconv_handle *iconv_handle;
665 iconv_handle = get_iconv_handle();
670 size_t c_size, c_size2;
671 codepoint_t c = next_codepoint_handle(iconv_handle, s, &c_size);
672 c_size2 = push_codepoint_handle(iconv_handle, d, toupper_m(c));
673 if (c_size2 > c_size) {
674 DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
675 c, toupper_m(c), (int)c_size, (int)c_size2));
676 smb_panic("codepoint expansion in strupper_m\n");
687 Convert a string to upper case.
690 void strupper_m(char *s)
695 /* this is quite a common operation, so we want it to be
696 fast. We optimise for the ascii case, knowing that all our
697 supported multi-byte character sets are ascii-compatible
698 (ie. they match for the first 128 chars) */
700 while (*s && !(((unsigned char)s[0]) & 0x80)) {
701 *s = toupper_ascii_fast((unsigned char)*s);
708 /* I assume that lowercased string takes the same number of bytes
709 * as source string even in multibyte encoding. (VIV) */
713 unix_strupper(s,len,s,len);
714 /* Catch mb conversion errors that may not terminate. */
721 Just a typesafety wrapper for snprintf into a fstring.
724 int fstr_sprintf(fstring s, const char *fmt, ...)
730 ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
736 List of Strings manipulation functions
739 #define S_LIST_ABS 16 /* List Allocation Block Size */
741 /******************************************************************************
742 version of standard_sub_basic() for string lists; uses talloc_sub_basic()
744 *****************************************************************************/
746 bool str_list_sub_basic( char **list, const char *smb_name,
747 const char *domain_name )
749 TALLOC_CTX *ctx = list;
754 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
756 DEBUG(0,("str_list_sub_basic: "
757 "alloc_sub_basic() return NULL!\n"));
770 /******************************************************************************
771 substitute a specific pattern in a string list
772 *****************************************************************************/
774 bool str_list_substitute(char **list, const char *pattern, const char *insert)
776 TALLOC_CTX *ctx = list;
778 ssize_t ls, lp, li, ld, i, d;
787 lp = (ssize_t)strlen(pattern);
788 li = (ssize_t)strlen(insert);
793 ls = (ssize_t)strlen(s);
795 while ((p = strstr_m(s, pattern))) {
799 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
801 DEBUG(0,("str_list_substitute: "
802 "Unable to allocate memory"));
806 memcpy(t +d +li, p +lp, ls -d -lp +1);
813 for (i = 0; i < li; i++) {
838 #define IPSTR_LIST_SEP ","
839 #define IPSTR_LIST_CHAR ','
842 * Add ip string representation to ipstr list. Used also
843 * as part of @function ipstr_list_make
845 * @param ipstr_list pointer to string containing ip list;
846 * MUST BE already allocated and IS reallocated if necessary
847 * @param ipstr_size pointer to current size of ipstr_list (might be changed
848 * as a result of reallocation)
849 * @param ip IP address which is to be added to list
850 * @return pointer to string appended with new ip and possibly
851 * reallocated to new length
854 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
856 char *new_ipstr = NULL;
857 char addr_buf[INET6_ADDRSTRLEN];
860 /* arguments checking */
861 if (!ipstr_list || !service) {
865 print_sockaddr(addr_buf,
869 /* attempt to convert ip to a string and append colon separator to it */
871 if (service->ss.ss_family == AF_INET) {
873 ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
874 IPSTR_LIST_SEP, addr_buf,
878 ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
879 IPSTR_LIST_SEP, addr_buf,
882 SAFE_FREE(*ipstr_list);
884 if (service->ss.ss_family == AF_INET) {
886 ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
890 ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
897 *ipstr_list = new_ipstr;
902 * Allocate and initialise an ipstr list using ip adresses
903 * passed as arguments.
905 * @param ipstr_list pointer to string meant to be allocated and set
906 * @param ip_list array of ip addresses to place in the list
907 * @param ip_count number of addresses stored in ip_list
908 * @return pointer to allocated ip string
911 char *ipstr_list_make(char **ipstr_list,
912 const struct ip_service *ip_list,
917 /* arguments checking */
918 if (!ip_list || !ipstr_list) {
924 /* process ip addresses given as arguments */
925 for (i = 0; i < ip_count; i++) {
926 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
929 return (*ipstr_list);
934 * Parse given ip string list into array of ip addresses
935 * (as ip_service structures)
936 * e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
938 * @param ipstr ip string list to be parsed
939 * @param ip_list pointer to array of ip addresses which is
940 * allocated by this function and must be freed by caller
941 * @return number of successfully parsed addresses
944 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
947 char *token_str = NULL;
951 if (!ipstr_list || !ip_list)
954 count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
955 if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
956 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
957 (unsigned long)count));
961 frame = talloc_stackframe();
962 for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
963 IPSTR_LIST_SEP) && i<count; i++ ) {
965 char *p = strrchr(token_str, ':');
969 (*ip_list)[i].port = atoi(p+1);
972 /* convert single token to ip address */
973 if (token_str[0] == '[') {
976 p = strchr(token_str, ']');
982 if (!interpret_string_addr(&(*ip_list)[i].ss,
993 * Safely free ip string list
995 * @param ipstr_list ip string list to be freed
998 void ipstr_list_free(char* ipstr_list)
1000 SAFE_FREE(ipstr_list);
1003 /* read a SMB_BIG_UINT from a string */
1004 uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1007 uint64_t val = (uint64_t)-1;
1008 const char *p = nptr;
1017 while (*p && isspace(*p))
1020 sscanf(p,"%"PRIu64,&val);
1022 while (*p && isdigit(*p))
1030 /* Convert a size specification to a count of bytes. We accept the following
1032 * bytes if there is no suffix
1037 * pP whatever the ISO name for petabytes is
1039 * Returns 0 if the string can't be converted.
1041 uint64_t conv_str_size(const char * str)
1047 if (str == NULL || *str == '\0') {
1051 lval = strtoull(str, &end, 10 /* base */);
1053 if (end == NULL || end == str) {
1063 if (strwicmp(end, "K") == 0) {
1065 } else if (strwicmp(end, "M") == 0) {
1066 lval *= (1024ULL * 1024ULL);
1067 } else if (strwicmp(end, "G") == 0) {
1068 lval *= (1024ULL * 1024ULL *
1070 } else if (strwicmp(end, "T") == 0) {
1071 lval *= (1024ULL * 1024ULL *
1073 } else if (strwicmp(end, "P") == 0) {
1074 lval *= (1024ULL * 1024ULL *
1084 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
1085 * error checking in between. The indiation that something weird happened is
1088 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
1089 size_t *bufsize, const char *fmt, ...)
1096 /* len<0 is an internal marker that something failed */
1100 if (*string == NULL) {
1104 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
1105 if (*string == NULL)
1110 ret = vasprintf(&newstr, fmt, ap);
1118 while ((*len)+ret >= *bufsize) {
1121 if (*bufsize >= (1024*1024*256))
1126 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
1128 if (*string == NULL) {
1133 StrnCpy((*string)+(*len), newstr, ret);
1144 * asprintf into a string and strupper_m it after that.
1147 int asprintf_strupper_m(char **strp, const char *fmt, ...)
1154 ret = vasprintf(&result, fmt, ap);
1165 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
1171 ret = talloc_vasprintf(t, fmt, ap);
1181 char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
1187 ret = talloc_vasprintf(t, fmt, ap);
1199 Returns the substring from src between the first occurrence of
1200 the char "front" and the first occurence of the char "back".
1201 Mallocs the return string which must be freed. Not for use
1202 with wide character strings.
1204 char *sstring_sub(const char *src, char front, char back)
1206 char *temp1, *temp2, *temp3;
1209 temp1 = strchr(src, front);
1210 if (temp1 == NULL) return NULL;
1211 temp2 = strchr(src, back);
1212 if (temp2 == NULL) return NULL;
1213 len = temp2 - temp1;
1214 if (len <= 0) return NULL;
1215 temp3 = (char*)SMB_MALLOC(len);
1216 if (temp3 == NULL) {
1217 DEBUG(1,("Malloc failure in sstring_sub\n"));
1220 memcpy(temp3, temp1+1, len-1);
1221 temp3[len-1] = '\0';
1225 /********************************************************************
1226 Check a string for any occurrences of a specified list of invalid
1228 ********************************************************************/
1230 bool validate_net_name( const char *name,
1231 const char *invalid_chars,
1240 for ( i=0; i<max_len && name[i]; i++ ) {
1241 /* fail if strchr_m() finds one of the invalid characters */
1242 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
1251 /*******************************************************************
1252 Add a shell escape character '\' to any character not in a known list
1253 of characters. UNIX charset format.
1254 *******************************************************************/
1256 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
1257 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
1259 char *escape_shell_string(const char *src)
1261 size_t srclen = strlen(src);
1262 char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
1264 bool in_s_quote = false;
1265 bool in_d_quote = false;
1266 bool next_escaped = false;
1274 codepoint_t c = next_codepoint(src, &c_size);
1276 if (c == INVALID_CODEPOINT) {
1282 memcpy(dest, src, c_size);
1285 next_escaped = false;
1290 * Deal with backslash escaped state.
1291 * This only lasts for one character.
1296 next_escaped = false;
1301 * Deal with single quote state. The
1302 * only thing we care about is exiting
1315 * Deal with double quote state. The most
1316 * complex state. We must cope with \, meaning
1317 * possibly escape next char (depending what it
1318 * is), ", meaning exit this state, and possibly
1319 * add an \ escape to any unprotected character
1320 * (listed in INSIDE_DQUOTE_LIST).
1326 * Next character might be escaped.
1327 * We have to peek. Inside double
1328 * quotes only INSIDE_DQUOTE_LIST
1329 * characters are escaped by a \.
1334 c = next_codepoint(&src[1], &c_size);
1335 if (c == INVALID_CODEPOINT) {
1341 * Don't escape the next char.
1350 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
1352 next_escaped = true;
1359 /* Exit double quote state. */
1366 * We know the character isn't \ or ",
1367 * so escape it if it's any of the other
1368 * possible unprotected characters.
1371 if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
1379 * From here to the end of the loop we're
1380 * not in the single or double quote state.
1384 /* Next character must be escaped. */
1385 next_escaped = true;
1391 /* Go into single quote state. */
1398 /* Go into double quote state. */
1404 /* Check if we need to escape the character. */
1406 if (!strchr(INCLUDE_LIST, (int)*src)) {
1415 /***************************************************
1416 str_list_make, v3 version. The v4 version does not
1417 look at quoted strings with embedded blanks, so
1418 do NOT merge this function please!
1419 ***************************************************/
1421 #define S_LIST_ABS 16 /* List Allocation Block Size */
1423 char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
1431 if (!string || !*string)
1434 list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
1440 s = talloc_strdup(list, string);
1442 DEBUG(0,("str_list_make: Unable to allocate memory"));
1446 if (!sep) sep = LIST_SEP;
1451 while (next_token_talloc(list, &str, &tok, sep)) {
1456 lsize += S_LIST_ABS;
1458 tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
1461 DEBUG(0,("str_list_make: "
1462 "Unable to allocate memory"));
1469 memset (&list[num], 0,
1470 ((sizeof(char**)) * (S_LIST_ABS +1)));
1483 char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
1487 alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
1488 return talloc_strdup(mem_ctx, tmp);