diff options
Diffstat (limited to 'source/lib')
-rw-r--r-- | source/lib/access.c | 3 | ||||
-rw-r--r-- | source/lib/account_pol.c | 2 | ||||
-rw-r--r-- | source/lib/charcnv.c | 120 | ||||
-rw-r--r-- | source/lib/dummyroot.c | 33 | ||||
-rw-r--r-- | source/lib/module.c | 2 | ||||
-rw-r--r-- | source/lib/ms_fnmatch.c | 82 | ||||
-rw-r--r-- | source/lib/popt_common.c | 56 | ||||
-rw-r--r-- | source/lib/readline.c | 4 | ||||
-rw-r--r-- | source/lib/replace.c | 18 | ||||
-rw-r--r-- | source/lib/replace1.c | 42 | ||||
-rw-r--r-- | source/lib/smbldap.c | 75 | ||||
-rw-r--r-- | source/lib/snprintf.c | 6 | ||||
-rw-r--r-- | source/lib/substitute.c | 4 | ||||
-rw-r--r-- | source/lib/sysquotas.c | 234 | ||||
-rw-r--r-- | source/lib/system.c | 159 | ||||
-rw-r--r-- | source/lib/username.c | 4 | ||||
-rw-r--r-- | source/lib/util.c | 17 | ||||
-rw-r--r-- | source/lib/util_file.c | 4 | ||||
-rw-r--r-- | source/lib/util_sid.c | 2 | ||||
-rw-r--r-- | source/lib/util_sock.c | 184 | ||||
-rw-r--r-- | source/lib/util_str.c | 77 | ||||
-rw-r--r-- | source/lib/util_unistr.c | 76 | ||||
-rw-r--r-- | source/lib/util_uuid.c | 2 |
23 files changed, 818 insertions, 388 deletions
diff --git a/source/lib/access.c b/source/lib/access.c index c30b3c33cc2..a874c8b1e20 100644 --- a/source/lib/access.c +++ b/source/lib/access.c @@ -281,13 +281,12 @@ static BOOL only_ipaddrs_in_list(const char** list) } if (!is_ipaddress(*list)) { - char *p; /* * if we failed, make sure that it was not because the token * was a network/netmask pair. Only network/netmask pairs * have a '/' in them */ - if ((p=strchr_m(*list, '/')) == NULL) { + if ((strchr_m(*list, '/')) == NULL) { only_ip = False; DEBUG(3,("only_ipaddrs_in_list: list has non-ip address (%s)\n", *list)); break; diff --git a/source/lib/account_pol.c b/source/lib/account_pol.c index e8b382c7ab9..dc131985a1a 100644 --- a/source/lib/account_pol.c +++ b/source/lib/account_pol.c @@ -53,7 +53,7 @@ BOOL init_account_policy(void) account_policy_set(AP_MIN_PASSWORD_LEN, MINPASSWDLENGTH); /* 5 chars minimum */ account_policy_set(AP_PASSWORD_HISTORY, 0); /* don't keep any old password */ account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, 0); /* don't force user to logon */ - account_policy_set(AP_MAX_PASSWORD_AGE, MAX_PASSWORD_AGE); /* 21 days */ + account_policy_set(AP_MAX_PASSWORD_AGE, (uint32)-1); /* don't expire */ account_policy_set(AP_MIN_PASSWORD_AGE, 0); /* 0 days */ account_policy_set(AP_LOCK_ACCOUNT_DURATION, 0); /* lockout for 0 minutes */ account_policy_set(AP_RESET_COUNT_TIME, 0); /* reset immediatly */ diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c index 4e9c2c15923..ca5e378970c 100644 --- a/source/lib/charcnv.c +++ b/source/lib/charcnv.c @@ -190,8 +190,8 @@ size_t convert_string(charset_t from, charset_t to, break; case E2BIG: reason="No more room"; - DEBUG(0, ("convert_string: Required %d, available %d\n", - srclen, destlen)); + DEBUG(0, ("convert_string: Required %lu, available %lu\n", + (unsigned long)srclen, (unsigned long)destlen)); /* we are not sure we need srclen bytes, may be more, may be less. We only know we need more than destlen @@ -319,8 +319,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) size_t size; smb_ucs2_t *buffer; - size = convert_string_allocate(CH_UNIX, CH_UCS2, src, srclen, - (void **) &buffer); + size = push_ucs2_allocate(&buffer, src); if (size == -1) { smb_panic("failed to create UCS2 buffer"); } @@ -334,6 +333,33 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen) return size; } +/** + strdup() a unix string to upper case. +**/ + +char *strdup_upper(const char *s) +{ + size_t size; + smb_ucs2_t *buffer; + char *out_buffer; + + size = push_ucs2_allocate(&buffer, s); + if (size == -1) { + return NULL; + } + + strupper_w(buffer); + + size = pull_ucs2_allocate(&out_buffer, buffer); + SAFE_FREE(buffer); + + if (size == -1) { + return NULL; + } + + return out_buffer; +} + size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) { size_t size; @@ -353,6 +379,32 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen) return size; } +/** + strdup() a unix string to lower case. +**/ + +char *strdup_lower(const char *s) +{ + size_t size; + smb_ucs2_t *buffer; + char *out_buffer; + + size = push_ucs2_allocate(&buffer, s); + if (size == -1) { + return NULL; + } + + strlower_w(buffer); + + size = pull_ucs2_allocate(&out_buffer, buffer); + SAFE_FREE(buffer); + + if (size == -1) { + return NULL; + } + + return out_buffer; +} static size_t ucs2_align(const void *base_ptr, const void *p, int flags) { @@ -480,18 +532,11 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_ { size_t len=0; size_t src_len = strlen(src); - pstring tmpbuf; /* treat a pstring as "unlimited" length */ if (dest_len == (size_t)-1) dest_len = sizeof(pstring); - if (flags & STR_UPPER) { - pstrcpy(tmpbuf, src); - strupper_m(tmpbuf); - src = tmpbuf; - } - if (flags & STR_TERMINATE) src_len++; @@ -506,6 +551,18 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_ dest_len &= ~1; len += convert_string(CH_UNIX, CH_UCS2, src, src_len, dest, dest_len); + + if (flags & STR_UPPER) { + smb_ucs2_t *dest_ucs2 = dest; + size_t i; + for (i = 0; i < (dest_len / 2) && dest_ucs2[i]; i++) { + smb_ucs2_t v = toupper_w(dest_ucs2[i]); + if (v != dest_ucs2[i]) { + dest_ucs2[i] = v; + } + } + } + return len; } @@ -809,44 +866,3 @@ size_t align_string(const void *base_ptr, const char *p, int flags) return 0; } -/** - Convert from unix to ucs2 charset and return the - allocated and converted string or NULL if an error occurred. - You must provide a zero terminated string. - The returning string will be zero terminated. -**/ - -smb_ucs2_t *acnv_uxu2(const char *src) -{ - size_t slen; - size_t dlen; - void *dest; - - slen = strlen(src) + 1; - dlen = convert_string_allocate(CH_UNIX, CH_UCS2, src, slen, &dest); - if (dlen == (size_t)-1) - return NULL; - else - return dest; -} - -/** - Convert from dos to ucs2 charset and return the - allocated and converted string or NULL if an error occurred. - You must provide a zero terminated string. - The returning string will be zero terminated. -**/ - -smb_ucs2_t *acnv_dosu2(const char *src) -{ - size_t slen; - size_t dlen; - void *dest; - - slen = strlen(src) + 1; - dlen = convert_string_allocate(CH_DOS, CH_UCS2, src, slen, &dest); - if (dlen == (size_t)-1) - return NULL; - else - return dest; -} diff --git a/source/lib/dummyroot.c b/source/lib/dummyroot.c new file mode 100644 index 00000000000..c8465cb791a --- /dev/null +++ b/source/lib/dummyroot.c @@ -0,0 +1,33 @@ +/* + Unix SMB/CIFS implementation. + RPC pipe client + + Copyright (C) Tim Potter 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* Stupid dummy functions required due to the horrible dependency mess + in Samba. */ + +void become_root(void) +{ + return; +} + +void unbecome_root(void) +{ + return; +} diff --git a/source/lib/module.c b/source/lib/module.c index ac4fe57a2c8..d860cba8195 100644 --- a/source/lib/module.c +++ b/source/lib/module.c @@ -41,7 +41,7 @@ NTSTATUS smb_load_module(const char *module_name) return NT_STATUS_UNSUCCESSFUL; } - init = sys_dlsym(handle, "init_module"); + init = (init_module_function *)sys_dlsym(handle, "init_module"); /* we must check sys_dlerror() to determine if it worked, because sys_dlsym() can validly return NULL */ diff --git a/source/lib/ms_fnmatch.c b/source/lib/ms_fnmatch.c index 106efa5bbcf..24232c3b523 100644 --- a/source/lib/ms_fnmatch.c +++ b/source/lib/ms_fnmatch.c @@ -35,7 +35,8 @@ of the protocol. This is not yet perfect, but its a lot better than what we had */ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern, - const smb_ucs2_t *string) + const smb_ucs2_t *string, + BOOL case_sensitive) { const smb_ucs2_t *p = pattern, *n = string; smb_ucs2_t c; @@ -61,8 +62,8 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern, case UCS2_CHAR('>'): if (! *n) goto next; if (n[0] == UCS2_CHAR('.')) { - if (! n[1] && ms_fnmatch_lanman_core(p, n+1) == 0) goto match; - if (ms_fnmatch_lanman_core(p, n) == 0) goto match; + if (! n[1] && ms_fnmatch_lanman_core(p, n+1, case_sensitive) == 0) goto match; + if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match; goto nomatch; } n++; @@ -72,13 +73,13 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern, if (! *n) goto next; if (! *p) goto match; for (; *n; n++) { - if (ms_fnmatch_lanman_core(p, n) == 0) goto match; + if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match; } break; case UCS2_CHAR('<'): for (; *n; n++) { - if (ms_fnmatch_lanman_core(p, n) == 0) goto match; + if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match; if (*n == UCS2_CHAR('.') && !strchr_w(n+1,UCS2_CHAR('.'))) { n++; @@ -88,13 +89,17 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern, break; case UCS2_CHAR('"'): - if (*n == 0 && ms_fnmatch_lanman_core(p, n) == 0) goto match; + if (*n == 0 && ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match; if (*n != UCS2_CHAR('.')) goto nomatch; n++; break; default: - if (c != *n) goto nomatch; + if (case_sensitive) { + if (c != *n) goto nomatch; + } else { + if (tolower_w(c) != tolower_w(*n)) goto nomatch; + } n++; } } @@ -108,7 +113,7 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern, return -1; next: - if (ms_fnmatch_lanman_core(p, n) == 0) goto match; + if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match; goto nomatch; match: @@ -118,7 +123,8 @@ next: return 0; } -static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, const smb_ucs2_t *string) +static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, + const smb_ucs2_t *string, BOOL case_sensitive) { if (!strpbrk_wa(pattern, "?*<>\"")) { smb_ucs2_t s[] = {UCS2_CHAR('.'), 0}; @@ -129,11 +135,11 @@ static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, const smb_ucs2_t *strin if (strcmp_wa(string,"..") == 0 || strcmp_wa(string,".") == 0) { smb_ucs2_t dot[] = {UCS2_CHAR('.'), 0}; smb_ucs2_t dotdot[] = {UCS2_CHAR('.'), UCS2_CHAR('.'), 0}; - return ms_fnmatch_lanman_core(pattern, dotdot) && - ms_fnmatch_lanman_core(pattern, dot); + return ms_fnmatch_lanman_core(pattern, dotdot, case_sensitive) && + ms_fnmatch_lanman_core(pattern, dot, case_sensitive); } - return ms_fnmatch_lanman_core(pattern, string); + return ms_fnmatch_lanman_core(pattern, string, case_sensitive); } @@ -145,13 +151,14 @@ static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, const smb_ucs2_t *strin Returns 0 on match, -1 on fail. */ -static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, int protocol) +static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, + int protocol, BOOL case_sensitive) { const smb_ucs2_t *p = pattern, *n = string; smb_ucs2_t c; if (protocol <= PROTOCOL_LANMAN2) { - return ms_fnmatch_lanman1(pattern, string); + return ms_fnmatch_lanman1(pattern, string, case_sensitive); } while ((c = *p++)) { @@ -163,23 +170,23 @@ static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, int case UCS2_CHAR('>'): if (n[0] == UCS2_CHAR('.')) { - if (! n[1] && ms_fnmatch_w(p, n+1, protocol) == 0) return 0; - if (ms_fnmatch_w(p, n, protocol) == 0) return 0; + if (! n[1] && ms_fnmatch_w(p, n+1, protocol, case_sensitive) == 0) return 0; + if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0; return -1; } - if (! *n) return ms_fnmatch_w(p, n, protocol); + if (! *n) return ms_fnmatch_w(p, n, protocol, case_sensitive); n++; break; case UCS2_CHAR('*'): for (; *n; n++) { - if (ms_fnmatch_w(p, n, protocol) == 0) return 0; + if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0; } break; case UCS2_CHAR('<'): for (; *n; n++) { - if (ms_fnmatch_w(p, n, protocol) == 0) return 0; + if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0; if (*n == UCS2_CHAR('.') && !strchr_wa(n+1,'.')) { n++; break; @@ -188,13 +195,17 @@ static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, int break; case UCS2_CHAR('"'): - if (*n == 0 && ms_fnmatch_w(p, n, protocol) == 0) return 0; + if (*n == 0 && ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0; if (*n != UCS2_CHAR('.')) return -1; n++; break; default: - if (c != *n) return -1; + if (case_sensitive) { + if (c != *n) return -1; + } else { + if (tolower_w(c) != tolower_w(*n)) return -1; + } n++; } } @@ -204,22 +215,35 @@ static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, int return -1; } - -int ms_fnmatch(const char *pattern, const char *string, int protocol) +int ms_fnmatch(const char *pattern, const char *string, int protocol, + BOOL case_senstive) { - wpstring p, s; + wpstring buffer_pattern, buffer_string; int ret; + size_t size; + + size = push_ucs2(NULL, buffer_pattern, pattern, sizeof(buffer_pattern), STR_TERMINATE); + if (size == (size_t)-1) { + return -1; + /* Not quite the right answer, but finding the right one + under this failure case is expensive, and it's pretty close */ + } + + size = push_ucs2(NULL, buffer_string, string, sizeof(buffer_string), STR_TERMINATE); + if (size == (size_t)-1) { + return -1; + /* Not quite the right answer, but finding the right one + under this failure case is expensive, and it's pretty close */ + } - pstrcpy_wa(p, pattern); - pstrcpy_wa(s, string); + ret = ms_fnmatch_w(buffer_pattern, buffer_string, protocol, case_senstive); + DEBUG(10,("ms_fnmatch(%s,%s) -> %d\n", pattern, string, ret)); - ret = ms_fnmatch_w(p, s, protocol); -/* DEBUG(0,("ms_fnmatch(%s,%s) -> %d\n", pattern, string, ret)); */ return ret; } /* a generic fnmatch function - uses for non-CIFS pattern matching */ int gen_fnmatch(const char *pattern, const char *string) { - return ms_fnmatch(pattern, string, PROTOCOL_NT1); + return ms_fnmatch(pattern, string, PROTOCOL_NT1, True); } diff --git a/source/lib/popt_common.c b/source/lib/popt_common.c index b8e77b2d9ec..95a9a58b34f 100644 --- a/source/lib/popt_common.c +++ b/source/lib/popt_common.c @@ -119,6 +119,7 @@ struct poptOption popt_common_connection[] = { { "netbiosname", 'n', POPT_ARG_STRING, NULL, 'n', "Primary netbios name", "NETBIOSNAME" }, { "workgroup", 'W', POPT_ARG_STRING, NULL, 'W', "Set the workgroup name", "WORKGROUP" }, { "scope", 'i', POPT_ARG_STRING, NULL, 'i', "Use this Netbios scope", "SCOPE" }, + POPT_TABLEEND }; @@ -258,19 +259,22 @@ static void get_credentials_file(const char *file, struct user_auth_info *info) * -A,--authentication-file * -k,--use-kerberos * -N,--no-pass + * -S,--signing + * -P --machine-pass */ static void popt_common_credentials_callback(poptContext con, - enum poptCallbackReason reason, - const struct poptOption *opt, - const char *arg, const void *data) + enum poptCallbackReason reason, + const struct poptOption *opt, + const char *arg, const void *data) { char *p; if (reason == POPT_CALLBACK_REASON_PRE) { cmdline_auth_info.use_kerberos = False; cmdline_auth_info.got_pass = False; + cmdline_auth_info.signing_state = Undefined; pstrcpy(cmdline_auth_info.username, "GUEST"); if (getenv("LOGNAME"))pstrcpy(cmdline_auth_info.username,getenv("LOGNAME")); @@ -327,6 +331,50 @@ static void popt_common_credentials_callback(poptContext con, cmdline_auth_info.got_pass = True; #endif break; + + case 'S': + { + cmdline_auth_info.signing_state = -1; + if (strequal(arg, "off") || strequal(arg, "no") || strequal(arg, "false")) + cmdline_auth_info.signing_state = False; + else if (strequal(arg, "on") || strequal(arg, "yes") || strequal(arg, "true") || + strequal(arg, "auto") ) + cmdline_auth_info.signing_state = True; + else if (strequal(arg, "force") || strequal(arg, "required") || strequal(arg, "forced")) + cmdline_auth_info.signing_state = Required; + else { + fprintf(stderr, "Unknown signing option %s\n", arg ); + exit(1); + } + } + break; + case 'P': + { + char *opt_password = NULL; + /* it is very useful to be able to make ads queries as the + machine account for testing purposes and for domain leave */ + + if (!secrets_init()) { + d_printf("ERROR: Unable to open secrets database\n"); + exit(1); + } + + opt_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + + if (!opt_password) { + d_printf("ERROR: Unable to fetch machine password\n"); + exit(1); + } + pstr_sprintf(cmdline_auth_info.username, "%s$", + global_myname()); + pstrcpy(cmdline_auth_info.password,opt_password); + SAFE_FREE(opt_password); + + /* machine accounts only work with kerberos */ + cmdline_auth_info.use_kerberos = True; + cmdline_auth_info.got_pass = True; + } + break; } } @@ -338,5 +386,7 @@ struct poptOption popt_common_credentials[] = { { "no-pass", 'N', POPT_ARG_NONE, &cmdline_auth_info.got_pass, 0, "Don't ask for a password" }, { "kerberos", 'k', POPT_ARG_NONE, &cmdline_auth_info.use_kerberos, 'k', "Use kerberos (active directory) authentication" }, { "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" }, + { "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" }, + {"machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password" }, POPT_TABLEEND }; diff --git a/source/lib/readline.c b/source/lib/readline.c index ceb02ef749c..78b99fd7fb0 100644 --- a/source/lib/readline.c +++ b/source/lib/readline.c @@ -51,7 +51,7 @@ ****************************************************************************/ static char *smb_readline_replacement(char *prompt, void (*callback)(void), - char **(completion_fn)(char *text, int start, int end)) + char **(completion_fn)(const char *text, int start, int end)) { fd_set fds; static pstring line; @@ -83,7 +83,7 @@ static char *smb_readline_replacement(char *prompt, void (*callback)(void), ****************************************************************************/ char *smb_readline(char *prompt, void (*callback)(void), - char **(completion_fn)(char *text, int start, int end)) + char **(completion_fn)(const char *text, int start, int end)) { #if HAVE_LIBREADLINE if (isatty(x_fileno(x_stdin))) { diff --git a/source/lib/replace.c b/source/lib/replace.c index 0c62ec9bfa5..cd48b8d160f 100644 --- a/source/lib/replace.c +++ b/source/lib/replace.c @@ -447,21 +447,3 @@ char *rep_inet_ntoa(struct in_addr ip) return t; } #endif - -#ifndef HAVE_SETENV - int setenv(const char *name, const char *value, int overwrite) -{ - char *p = NULL; - int ret = -1; - - asprintf(&p, "%s=%s", name, value); - - if (overwrite || getenv(name)) { - if (p) ret = putenv(p); - } else { - ret = 0; - } - - return ret; -} -#endif diff --git a/source/lib/replace1.c b/source/lib/replace1.c new file mode 100644 index 00000000000..e1be56eb128 --- /dev/null +++ b/source/lib/replace1.c @@ -0,0 +1,42 @@ +/* + Unix SMB/CIFS implementation. + replacement routines for broken systems + Copyright (C) Andrew Tridgell 1992-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + + void replace1_dummy(void); + void replace1_dummy(void) {} + +#ifndef HAVE_SETENV + int setenv(const char *name, const char *value, int overwrite) +{ + char *p = NULL; + int ret = -1; + + asprintf(&p, "%s=%s", name, value); + + if (overwrite || getenv(name)) { + if (p) ret = putenv(p); + } else { + ret = 0; + } + + return ret; +} +#endif diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c index 39c1990decb..1ce03491da1 100644 --- a/source/lib/smbldap.c +++ b/source/lib/smbldap.c @@ -5,7 +5,7 @@ Copyright (C) Gerald Carter 2001-2003 Copyright (C) Shahms King 2001 Copyright (C) Andrew Bartlett 2002-2003 - Copyright (C) Stefan (metze) Metzmacher 2002 + Copyright (C) Stefan (metze) Metzmacher 2002-2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,6 +35,8 @@ #define SMBLDAP_DONT_PING_TIME 10 /* ping only all 10 seconds */ #define SMBLDAP_NUM_RETRIES 8 /* retry only 8 times */ +#define SMBLDAP_IDLE_TIME 150 /* After 2.5 minutes disconnect */ + /* attributes used by Samba 2.2 */ @@ -925,6 +927,8 @@ int smbldap_search(struct smbldap_state *ldap_state, smbldap_close(ldap_state); } + ldap_state->last_use = time(NULL); + SAFE_FREE(utf8_filter); return rc; } @@ -954,6 +958,8 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at smbldap_close(ldap_state); } + ldap_state->last_use = time(NULL); + SAFE_FREE(utf8_dn); return rc; } @@ -983,6 +989,8 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs smbldap_close(ldap_state); } + ldap_state->last_use = time(NULL); + SAFE_FREE(utf8_dn); return rc; } @@ -1012,6 +1020,8 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn) smbldap_close(ldap_state); } + ldap_state->last_use = time(NULL); + SAFE_FREE(utf8_dn); return rc; } @@ -1041,6 +1051,8 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state, smbldap_close(ldap_state); } + ldap_state->last_use = time(NULL); + return rc; } @@ -1071,6 +1083,24 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter, return rc; } +static void smbldap_idle_fn(void **data, time_t *interval, time_t now) +{ + struct smbldap_state *state = (struct smbldap_state *)(*data); + + if (state->ldap_struct == NULL) { + DEBUG(10,("ldap connection not connected...\n")); + return; + } + + if ((state->last_use+SMBLDAP_IDLE_TIME) > now) { + DEBUG(10,("ldap connection not idle...\n")); + return; + } + + DEBUG(7,("ldap connection idle...closing connection\n")); + smbldap_close(state); +} + /********************************************************************** Housekeeping *********************************************************************/ @@ -1086,6 +1116,8 @@ void smbldap_free_struct(struct smbldap_state **ldap_state) SAFE_FREE((*ldap_state)->bind_dn); SAFE_FREE((*ldap_state)->bind_secret); + smb_unregister_idle_event((*ldap_state)->event_id); + *ldap_state = NULL; /* No need to free any further, as it is talloc()ed */ @@ -1109,6 +1141,16 @@ NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_ } else { (*smbldap_state)->uri = "ldap://localhost"; } + + (*smbldap_state)->event_id = + smb_register_idle_event(smbldap_idle_fn, (void *)(*smbldap_state), + SMBLDAP_IDLE_TIME); + + if ((*smbldap_state)->event_id == SMB_EVENT_ID_INVALID) { + DEBUG(0,("Failed to register LDAP idle event!\n")); + return NT_STATUS_INVALID_HANDLE; + } + return NT_STATUS_OK; } @@ -1130,6 +1172,9 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state, LDAPMessage *result = NULL; int num_result; char **attr_list; + uid_t u_low, u_high; + gid_t g_low, g_high; + uint32 rid_low, rid_high; slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), @@ -1155,7 +1200,7 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state, DEBUG(3,("Adding new domain\n")); ldap_op = LDAP_MOD_ADD; - snprintf(dn, sizeof(dn), "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), + pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), domain_name, lp_ldap_suffix()); /* Free original search */ @@ -1175,6 +1220,30 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state, smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE), algorithmic_rid_base_string); smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO); + + /* add the sambaNext[User|Group]Rid attributes if the idmap ranges are set. + TODO: fix all the places where the line between idmap and normal operations + needed by smbd gets fuzzy --jerry 2003-08-11 */ + + if ( lp_idmap_uid(&u_low, &u_high) && lp_idmap_gid(&g_low, &g_high) + && get_free_rid_range(&rid_low, &rid_high) ) + { + fstring rid_str; + + fstr_sprintf( rid_str, "%i", rid_high|USER_RID_TYPE ); + DEBUG(10,("setting next available user rid [%s]\n", rid_str)); + smbldap_set_mod(&mods, LDAP_MOD_ADD, + get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), + rid_str); + + fstr_sprintf( rid_str, "%i", rid_high|GROUP_RID_TYPE ); + DEBUG(10,("setting next available group rid [%s]\n", rid_str)); + smbldap_set_mod(&mods, LDAP_MOD_ADD, + get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID), + rid_str); + + } + switch(ldap_op) { @@ -1220,7 +1289,7 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, char **attr_list; int count; - snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))", + pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))", LDAP_OBJ_DOMINFO, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN), domain_name); diff --git a/source/lib/snprintf.c b/source/lib/snprintf.c index 9b9ceb60cac..a2f9f592db3 100644 --- a/source/lib/snprintf.c +++ b/source/lib/snprintf.c @@ -823,12 +823,10 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) * * The logic for these two is that we need our own definition if the * OS *either* has no definition of *sprintf, or if it does have one - * that doesn't work properly according to the autoconf test. Perhaps - * these should really be smb_snprintf to avoid conflicts with buggy - * linkers? -- mbp + * that doesn't work properly according to the autoconf test. */ #if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) - int snprintf(char *str,size_t count,const char *fmt,...) +int smb_snprintf(char *str,size_t count,const char *fmt,...) { size_t ret; va_list ap; diff --git a/source/lib/substitute.c b/source/lib/substitute.c index ac2cf687c49..c0d0096806a 100644 --- a/source/lib/substitute.c +++ b/source/lib/substitute.c @@ -58,8 +58,8 @@ void set_local_machine_name(const char* local_name, BOOL perm) fstrcpy(tmp_local_machine,local_name); trim_string(tmp_local_machine," "," "); - strlower_m(tmp_local_machine); alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1); + strlower_m(local_machine); } /** @@ -80,8 +80,8 @@ void set_remote_machine_name(const char* remote_name, BOOL perm) fstrcpy(tmp_remote_machine,remote_name); trim_string(tmp_remote_machine," "," "); - strlower_m(tmp_remote_machine); alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1); + strlower_m(remote_machine); } const char* get_remote_machine_name(void) diff --git a/source/lib/sysquotas.c b/source/lib/sysquotas.c index efc9e65b9de..617f624daea 100644 --- a/source/lib/sysquotas.c +++ b/source/lib/sysquotas.c @@ -48,12 +48,6 @@ static int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ switch (qtype) { case SMB_USER_QUOTA_TYPE: - /* we use id.uid == 0 for default quotas */ - if (id.uid == 0) { - ret = 0; - break; - } - if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))) { return ret; } @@ -88,13 +82,19 @@ static int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ qflags |= QUOTAS_DENY_DISK; } - /* get the default quotas stored in the root's (uid =0) record */ - if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, 0, (CADDR_T)&D))) { - return ret; + ret = 0; + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + id.gid = getgid(); + + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))==0) { + qflags |= QUOTAS_DENY_DISK; } ret = 0; break; +#endif /* HAVE_GROUP_QUOTA */ default: errno = ENOSYS; return -1; @@ -122,6 +122,7 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ { int ret = -1; uint32 qflags = 0; + uint32 oldqflags = 0; struct SYS_DQBLK D; SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE; @@ -146,10 +147,7 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ switch (qtype) { case SMB_USER_QUOTA_TYPE: - /* we use id.uid == 0 for default quotas */ - if (id.uid>0) { - ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D); - } + ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D); break; #ifdef HAVE_GROUP_QUOTA case SMB_GROUP_QUOTA_TYPE: @@ -160,7 +158,7 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ /* this stuff didn't work as it should: * switching on/off quota via quotactl() * didn't work! - * So we only set the default limits + * So we just return 0 * --metze * * On HPUX we didn't have the mount path, @@ -168,9 +166,9 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ * */ #if 0 - uid = getuid(); + id.uid = getuid(); - ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, uid, (CADDR_T)&D); + ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D); if ((qflags"AS_DENY_DISK)||(qflags"AS_ENABLED)) { if (ret == 0) { @@ -197,14 +195,79 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ } DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n", - ret,errno,strerror(errno),uid,bdev)); + ret,errno,strerror(errno),id.uid,bdev)); +#else + id.uid = getuid(); + + if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))==0) { + oldqflags |= QUOTAS_DENY_DISK; + } + + if (oldqflags == qflags) { + ret = 0; + } else { + ret = -1; + } #endif - - /* we use uid == 0 for default quotas */ - ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, 0, (CADDR_T)&D); - break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + /* this stuff didn't work as it should: + * switching on/off quota via quotactl() + * didn't work! + * So we just return 0 + * --metze + * + * On HPUX we didn't have the mount path, + * we need to fix sys_path_to_bdev() + * + */ +#if 0 + id.gid = getgid(); + + ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (CADDR_T)&D); + + if ((qflags"AS_DENY_DISK)||(qflags"AS_ENABLED)) { + if (ret == 0) { + char *quota_file = NULL; + + asprintf("a_file,"/%s/%s%s",path, QUOTAFILENAME,GROUPQUOTAFILE_EXTENSION); + if (quota_file == NULL) { + DEBUG(0,("asprintf() failed!\n")); + errno = ENOMEM; + return -1; + } + + ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), bdev, -1,(CADDR_T)quota_file); + } else { + ret = 0; + } + } else { + if (ret != 0) { + /* turn off */ + ret = quotactl(QCMD(Q_QUOTAOFF,GRPQUOTA), bdev, -1, (CADDR_T)0); + } else { + ret = 0; + } + } + + DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n", + ret,errno,strerror(errno),id.gid,bdev)); +#else + id.gid = getgid(); + + if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))==0) { + oldqflags |= QUOTAS_DENY_DISK; + } + if (oldqflags == qflags) { + ret = 0; + } else { + ret = -1; + } +#endif + break; +#endif /* HAVE_GROUP_QUOTA */ default: errno = ENOSYS; return -1; @@ -383,7 +446,7 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char ****************************************************************************/ static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) { - int ret; + int ret = -1; uint32 qflags = 0; SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE; struct fs_disk_quota D; @@ -399,11 +462,6 @@ static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ switch (qtype) { case SMB_USER_QUOTA_TYPE: - /* we use id.uid == 0 for default quotas */ - if (id.uid == 0) { - ret = 0; - break; - } if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))) return ret; break; @@ -413,10 +471,8 @@ static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ return ret; break; #endif /* HAVE_GROUP_QUOTA */ - case SMB_USER_FS_QUOTA_TYPE: - /* TODO: get quota status from quotactl() ... */ - if ((ret = quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F))) - return ret; + case SMB_USER_FS_QUOTA_TYPE: + quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F); if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) { qflags |= QUOTAS_DENY_DISK; @@ -425,11 +481,24 @@ static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ qflags |= QUOTAS_ENABLED; } - /* we use uid == 0 for default quotas */ - if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, 0, (CADDR_T)&D))) - return ret; + ret = 0; break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (CADDR_T)&F); + + if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) { + qflags |= QUOTAS_DENY_DISK; + } + else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) { + qflags |= QUOTAS_ENABLED; + } + + ret = 0; + + break; +#endif /* HAVE_GROUP_QUOTA */ default: errno = ENOSYS; return -1; @@ -481,11 +550,8 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ switch (qtype) { case SMB_USER_QUOTA_TYPE: - /* we use uid == 0 for default quotas */ - if (id.uid>0) { - D.d_fieldmask |= FS_DQ_LIMIT_MASK; - ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D); - } + D.d_fieldmask |= FS_DQ_LIMIT_MASK; + ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D); break; #ifdef HAVE_GROUP_QUOTA case SMB_GROUP_QUOTA_TYPE: @@ -494,7 +560,6 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ break; #endif /* HAVE_GROUP_QUOTA */ case SMB_USER_FS_QUOTA_TYPE: - /* TODO */ quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F); if (qflags & QUOTAS_DENY_DISK) { @@ -505,6 +570,8 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ if (q_on != 0) { ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (CADDR_T)&q_on); + } else { + ret = 0; } } else if (qflags & QUOTAS_ENABLED) { @@ -513,6 +580,8 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ if (q_off != 0) { ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (CADDR_T)&q_off); + } else { + ret = 0; } if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT)) @@ -520,6 +589,8 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ if (q_on != 0) { ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (CADDR_T)&q_on); + } else { + ret = 0; } } else { #if 0 @@ -533,14 +604,71 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_ if (q_off !=0) { ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (CADDR_T)&q_off); + } else { + ret = 0; } +#else + ret = -1; #endif } + + break; +#ifdef HAVE_GROUP_QUOTA + case SMB_GROUP_FS_QUOTA_TYPE: + quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (CADDR_T)&F); - /* we use uid == 0 for default quotas */ - D.d_fieldmask |= FS_DQ_LIMIT_MASK; - ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, 0, (CADDR_T)&D); + if (qflags & QUOTAS_DENY_DISK) { + if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD)) + q_on |= XFS_QUOTA_UDQ_ENFD; + if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT)) + q_on |= XFS_QUOTA_UDQ_ACCT; + + if (q_on != 0) { + ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (CADDR_T)&q_on); + } else { + ret = 0; + } + + } else if (qflags & QUOTAS_ENABLED) { + if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) + q_off |= XFS_QUOTA_UDQ_ENFD; + + if (q_off != 0) { + ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (CADDR_T)&q_off); + } else { + ret = 0; + } + + if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT)) + q_on |= XFS_QUOTA_UDQ_ACCT; + + if (q_on != 0) { + ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (CADDR_T)&q_on); + } else { + ret = 0; + } + } else { +#if 0 + /* Switch on XFS_QUOTA_UDQ_ACCT didn't work! + * only swittching off XFS_QUOTA_UDQ_ACCT work + */ + if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) + q_off |= XFS_QUOTA_UDQ_ENFD; + if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) + q_off |= XFS_QUOTA_UDQ_ACCT; + + if (q_off !=0) { + ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (CADDR_T)&q_off); + } else { + ret = 0; + } +#else + ret = -1; +#endif + } + break; +#endif /* HAVE_GROUP_QUOTA */ default: errno = ENOSYS; return -1; @@ -783,12 +911,17 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI } if ((ret=sys_path_to_bdev(path,&mntpath,&bdev,&fs))!=0) { + DEBUG(0,("sys_path_to_bdev() failed for path [%s]!\n",path)); return ret; } for (i=0;(fs && sys_quota_backends[i].name && sys_quota_backends[i].get_quota);i++) { if (strcmp(fs,sys_quota_backends[i].name)==0) { ret = sys_quota_backends[i].get_quota(mntpath, bdev, qtype, id, dp); + if (ret!=0) { + DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n", + fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret)); + } ready = True; break; } @@ -796,7 +929,11 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI if (!ready) { /* use the default vfs quota functions */ - ret = sys_get_vfs_quota(mntpath, bdev, qtype, id, dp); + ret=sys_get_vfs_quota(mntpath, bdev, qtype, id, dp); + if (ret!=0) { + DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n", + "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret)); + } } SAFE_FREE(mntpath); @@ -831,12 +968,17 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI } if ((ret=sys_path_to_bdev(path,&mntpath,&bdev,&fs))!=0) { + DEBUG(0,("sys_path_to_bdev() failed for path [%s]!\n",path)); return ret; } for (i=0;(fs && sys_quota_backends[i].name && sys_quota_backends[i].set_quota);i++) { if (strcmp(fs,sys_quota_backends[i].name)==0) { ret = sys_quota_backends[i].set_quota(mntpath, bdev, qtype, id, dp); + if (ret!=0) { + DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n", + fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret)); + } ready = True; break; } @@ -845,6 +987,10 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI if (!ready) { /* use the default vfs quota functions */ ret=sys_set_vfs_quota(mntpath, bdev, qtype, id, dp); + if (ret!=0) { + DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n", + "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret)); + } } SAFE_FREE(mntpath); diff --git a/source/lib/system.c b/source/lib/system.c index a7024c852df..b020a203730 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -1263,6 +1263,16 @@ ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t si { #if defined(HAVE_GETXATTR) return getxattr(path, name, value, size); +#elif defined(HAVE_ATTR_GET) + int retval, flags = 0; + int valuelength = (int)size; + char *attrname = strchr(name,'.') +1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + retval = attr_get(path, attrname, (char *)value, &valuelength, flags); + + return retval ? retval : valuelength; #else errno = ENOSYS; return -1; @@ -1273,6 +1283,16 @@ ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t s { #if defined(HAVE_LGETXATTR) return lgetxattr(path, name, value, size); +#elif defined(HAVE_ATTR_GET) + int retval, flags = ATTR_DONTFOLLOW; + int valuelength = (int)size; + char *attrname = strchr(name,'.') +1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + retval = attr_get(path, attrname, (char *)value, &valuelength, flags); + + return retval ? retval : valuelength; #else errno = ENOSYS; return -1; @@ -1283,16 +1303,96 @@ ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size) { #if defined(HAVE_FGETXATTR) return fgetxattr(filedes, name, value, size); +#elif defined(HAVE_ATTR_GETF) + int retval, flags = 0; + int valuelength = (int)size; + char *attrname = strchr(name,'.') +1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags); + + return retval ? retval : valuelength; #else errno = ENOSYS; return -1; #endif } +#if defined(HAVE_ATTR_LIST) +static char attr_buffer[ATTR_MAX_VALUELEN]; + +static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags) +{ + int retval = 0, index; + attrlist_cursor_t *cursor = 0; + int total_size = 0; + attrlist_t * al = (attrlist_t *)attr_buffer; + attrlist_ent_t *ae; + size_t ent_size, left = size; + char *bp = list; + + while (True) { + if (filedes) + retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); + else + retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); + if (retval) break; + for (index = 0; index < al->al_count; index++) { + ae = ATTR_ENTRY(attr_buffer, index); + ent_size = strlen(ae->a_name) + sizeof("user."); + if (left >= ent_size) { + strncpy(bp, "user.", sizeof("user.")); + strncat(bp, ae->a_name, ent_size - sizeof("user.")); + bp += ent_size; + left -= ent_size; + } else if (size) { + errno = ERANGE; + retval = -1; + break; + } + total_size += ent_size; + } + if (al->al_more == 0) break; + } + if (retval == 0) { + flags |= ATTR_ROOT; + cursor = 0; + while (True) { + if (filedes) + retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); + else + retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); + if (retval) break; + for (index = 0; index < al->al_count; index++) { + ae = ATTR_ENTRY(attr_buffer, index); + ent_size = strlen(ae->a_name) + sizeof("system."); + if (left >= ent_size) { + strncpy(bp, "system.", sizeof("system.")); + strncat(bp, ae->a_name, ent_size - sizeof("system.")); + bp += ent_size; + left -= ent_size; + } else if (size) { + errno = ERANGE; + retval = -1; + break; + } + total_size += ent_size; + } + if (al->al_more == 0) break; + } + } + return (ssize_t)(retval ? retval : total_size); +} + +#endif + ssize_t sys_listxattr (const char *path, char *list, size_t size) { #if defined(HAVE_LISTXATTR) return listxattr(path, list, size); +#elif defined(HAVE_ATTR_LIST) + return irix_attr_list(path, 0, list, size, 0); #else errno = ENOSYS; return -1; @@ -1301,8 +1401,10 @@ ssize_t sys_listxattr (const char *path, char *list, size_t size) ssize_t sys_llistxattr (const char *path, char *list, size_t size) { -#if defined(HAVE_GETXATTR) +#if defined(HAVE_LLISTXATTR) return llistxattr(path, list, size); +#elif defined(HAVE_ATTR_LIST) + return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW); #else errno = ENOSYS; return -1; @@ -1313,6 +1415,8 @@ ssize_t sys_flistxattr (int filedes, char *list, size_t size) { #if defined(HAVE_FLISTXATTR) return flistxattr(filedes, list, size); +#elif defined(HAVE_ATTR_LISTF) + return irix_attr_list(NULL, filedes, list, size, 0); #else errno = ENOSYS; return -1; @@ -1323,6 +1427,13 @@ int sys_removexattr (const char *path, const char *name) { #if defined(HAVE_REMOVEXATTR) return removexattr(path, name); +#elif defined(HAVE_ATTR_REMOVE) + int flags = 0; + char *attrname = strchr(name,'.') +1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + return attr_remove(path, attrname, flags); #else errno = ENOSYS; return -1; @@ -1333,6 +1444,13 @@ int sys_lremovexattr (const char *path, const char *name) { #if defined(HAVE_LREMOVEXATTR) return lremovexattr(path, name); +#elif defined(HAVE_ATTR_REMOVE) + int flags = ATTR_DONTFOLLOW; + char *attrname = strchr(name,'.') +1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + return attr_remove(path, attrname, flags); #else errno = ENOSYS; return -1; @@ -1343,16 +1461,37 @@ int sys_fremovexattr (int filedes, const char *name) { #if defined(HAVE_FREMOVEXATTR) return fremovexattr(filedes, name); +#elif defined(HAVE_ATTR_REMOVEF) + int flags = 0; + char *attrname = strchr(name,'.') +1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + return attr_removef(filedes, attrname, flags); #else errno = ENOSYS; return -1; #endif } +#if !defined(HAVE_SETXATTR) +#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ +#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ +#endif + int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags) { #if defined(HAVE_SETXATTR) return setxattr(path, name, value, size, flags); +#elif defined(HAVE_ATTR_SET) + int myflags = 0; + char *attrname = strchr(name,'.') +1; + + if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; + if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; + if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; + + return attr_set(path, attrname, (const char *)value, size, myflags); #else errno = ENOSYS; return -1; @@ -1363,6 +1502,15 @@ int sys_lsetxattr (const char *path, const char *name, const void *value, size_t { #if defined(HAVE_LSETXATTR) return lsetxattr(path, name, value, size, flags); +#elif defined(HAVE_ATTR_SET) + int myflags = ATTR_DONTFOLLOW; + char *attrname = strchr(name,'.') +1; + + if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; + if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; + if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; + + return attr_set(path, attrname, (const char *)value, size, myflags); #else errno = ENOSYS; return -1; @@ -1373,6 +1521,15 @@ int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size { #if defined(HAVE_FSETXATTR) return fsetxattr(filedes, name, value, size, flags); +#elif defined(HAVE_ATTR_SETF) + int myflags = 0; + char *attrname = strchr(name,'.') +1; + + if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; + if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; + if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; + + return attr_setf(filedes, attrname, (const char *)value, size, myflags); #else errno = ENOSYS; return -1; diff --git a/source/lib/username.c b/source/lib/username.c index 98b8f33aae3..6321d470212 100644 --- a/source/lib/username.c +++ b/source/lib/username.c @@ -386,7 +386,7 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL if ( DEBUGLEVEL >= 10 ) { DEBUG(10,("user_in_winbind_group_list: using groups -- ")); for ( i=0; i<num_groups; i++ ) - DEBUGADD(10,("%d ", groups[i])); + DEBUGADD(10,("%lu ", (unsigned long)groups[i])); DEBUGADD(10,("\n")); } @@ -593,7 +593,7 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups, size_t n_gr will return domain local groups; while NT4 or mixed mode 2k DCs will not */ - if ( winbind_lookup_name(NULL, *list, &g_sid, &name_type) + if ( winbind_lookup_name(domain, groupname, &g_sid, &name_type) && ( name_type==SID_NAME_DOM_GRP || (strequal(lp_workgroup(), domain) && name_type==SID_NAME_ALIAS) ) ) { diff --git a/source/lib/util.c b/source/lib/util.c index a7c939fe5a0..5f4fae9baa2 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -4,7 +4,7 @@ Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Jeremy Allison 2001-2002 Copyright (C) Simo Sorce 2001 - Copyright (C) Anthony Liguori 2003 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -311,7 +311,7 @@ BOOL in_group(gid_t group, gid_t current_gid, int ngroups, const gid_t *groups) static const char *Atoic(const char *p, int *n, const char *c) { - if (!isdigit((const int)*p)) { + if (!isdigit((int)*p)) { DEBUG(5, ("Atoic: malformed number\n")); return NULL; } @@ -2247,7 +2247,7 @@ char *pid_path(const char *name) char *lib_path(const char *name) { static pstring fname; - snprintf(fname, sizeof(fname), "%s/%s", dyn_LIBDIR, name); + fstr_sprintf(fname, "%s/%s", dyn_LIBDIR, name); return fname; } @@ -2335,21 +2335,12 @@ BOOL ms_has_wild_w(const smb_ucs2_t *s) BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive) { - fstring p2, s2; - if (strcmp(string,"..") == 0) string = "."; if (strcmp(pattern,".") == 0) return False; - if (is_case_sensitive) - return ms_fnmatch(pattern, string, Protocol) == 0; - - fstrcpy(p2, pattern); - fstrcpy(s2, string); - strlower_m(p2); - strlower_m(s2); - return ms_fnmatch(p2, s2, Protocol) == 0; + return ms_fnmatch(pattern, string, Protocol, is_case_sensitive) == 0; } /********************************************************* diff --git a/source/lib/util_file.c b/source/lib/util_file.c index 02acbd4d7e1..638a6ca3429 100644 --- a/source/lib/util_file.c +++ b/source/lib/util_file.c @@ -455,8 +455,8 @@ void *map_file(char *fname, size_t size) p = file_load(fname, &s2); if (!p) return NULL; if (s2 != size) { - DEBUG(1,("incorrect size for %s - got %d expected %d\n", - fname, s2, size)); + DEBUG(1,("incorrect size for %s - got %lu expected %lu\n", + fname, (unsigned long)s2, (unsigned long)size)); if (p) free(p); return NULL; } diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c index 00f14d7d26b..fbb393770d5 100644 --- a/source/lib/util_sid.c +++ b/source/lib/util_sid.c @@ -93,7 +93,7 @@ static const struct { {SID_NAME_UNKNOWN, "UNKNOWN"}, {SID_NAME_COMPUTER, "Computer"}, - {0, NULL} + {(enum SID_NAME_USE)0, NULL} }; const char *sid_type_lookup(uint32 sid_type) diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c index 1bd4c3a96be..b8b84717084 100644 --- a/source/lib/util_sock.c +++ b/source/lib/util_sock.c @@ -289,7 +289,7 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un } /**************************************************************************** - read data from the client, reading exactly N bytes. + Read data from the client, reading exactly N bytes. ****************************************************************************/ ssize_t read_data(int fd,char *buffer,size_t N) @@ -397,7 +397,7 @@ static ssize_t write_socket_data(int fd,char *buffer,size_t N) } /**************************************************************************** -write to a socket + Write to a socket. ****************************************************************************/ ssize_t write_socket(int fd,char *buf,size_t len) @@ -416,7 +416,7 @@ ssize_t write_socket(int fd,char *buf,size_t len) } /**************************************************************************** -send a keepalive packet (rfc1002) + Send a keepalive packet (rfc1002). ****************************************************************************/ BOOL send_keepalive(int client) @@ -431,11 +431,11 @@ BOOL send_keepalive(int client) /**************************************************************************** -read 4 bytes of a smb packet and return the smb length of the packet -store the result in the buffer -This version of the function will return a length of zero on receiving -a keepalive packet. -timeout is in milliseconds. + Read 4 bytes of a smb packet and return the smb length of the packet. + Store the result in the buffer. + This version of the function will return a length of zero on receiving + a keepalive packet. + Timeout is in milliseconds. ****************************************************************************/ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout) @@ -466,10 +466,10 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int } /**************************************************************************** -read 4 bytes of a smb packet and return the smb length of the packet -store the result in the buffer. This version of the function will -never return a session keepalive (length of zero). -timeout is in milliseconds. + Read 4 bytes of a smb packet and return the smb length of the packet. + Store the result in the buffer. This version of the function will + never return a session keepalive (length of zero). + Timeout is in milliseconds. ****************************************************************************/ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) @@ -493,11 +493,10 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) } /**************************************************************************** - read an smb from a fd. Note that the buffer *MUST* be of size - BUFFER_SIZE+SAFETY_MARGIN. - The timeout is in milliseconds. - This function will return on a - receipt of a session keepalive packet. + Read an smb from a fd. Note that the buffer *MUST* be of size + BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds. + This function will return on receipt of a session keepalive packet. ****************************************************************************/ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) @@ -553,11 +552,19 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout) } } + /* Check the incoming SMB signature. */ + if (!srv_check_sign_mac(buffer)) { + DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n")); + if (smb_read_error == 0) + smb_read_error = READ_BAD_SIG; + return False; + }; + return(True); } /**************************************************************************** - send an smb to a fd + Send an smb to a fd. ****************************************************************************/ BOOL send_smb(int fd,char *buffer) @@ -565,6 +572,10 @@ BOOL send_smb(int fd,char *buffer) size_t len; size_t nwritten=0; ssize_t ret; + + /* Sign the outgoing packet if required. */ + srv_calculate_sign_mac(buffer); + len = smb_len(buffer) + 4; while (nwritten < len) { @@ -647,80 +658,86 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb } /**************************************************************************** - create an outgoing socket. timeout is in milliseconds. - **************************************************************************/ + Create an outgoing socket. timeout is in milliseconds. +**************************************************************************/ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) { - struct sockaddr_in sock_out; - int res,ret; - int connect_loop = 10; - int increment = 10; + struct sockaddr_in sock_out; + int res,ret; + int connect_loop = 10; + int increment = 10; - /* create a socket to write to */ - res = socket(PF_INET, type, 0); - if (res == -1) - { DEBUG(0,("socket error\n")); return -1; } + /* create a socket to write to */ + res = socket(PF_INET, type, 0); + if (res == -1) { + DEBUG(0,("socket error\n")); + return -1; + } - if (type != SOCK_STREAM) return(res); + if (type != SOCK_STREAM) + return(res); - memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)addr); + memset((char *)&sock_out,'\0',sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)addr); - sock_out.sin_port = htons( port ); - sock_out.sin_family = PF_INET; + sock_out.sin_port = htons( port ); + sock_out.sin_family = PF_INET; - /* set it non-blocking */ - set_blocking(res,False); + /* set it non-blocking */ + set_blocking(res,False); - DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); + DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); - /* and connect it to the destination */ -connect_again: - ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); - - /* Some systems return EAGAIN when they mean EINPROGRESS */ - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN) && (connect_loop < timeout) ) { - msleep(connect_loop); - connect_loop += increment; - if (increment < 250) { - /* After 8 rounds we end up at a max of 255 msec */ - increment *= 1.5; - } - goto connect_again; - } - - if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || - errno == EAGAIN)) { - DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port)); - close(res); - return -1; - } + /* and connect it to the destination */ + connect_again: + + ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); + + /* Some systems return EAGAIN when they mean EINPROGRESS */ + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || + errno == EAGAIN) && (connect_loop < timeout) ) { + msleep(connect_loop); + connect_loop += increment; + if (increment < 250) { + /* After 8 rounds we end up at a max of 255 msec */ + increment *= 1.5; + } + goto connect_again; + } + + if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || + errno == EAGAIN)) { + DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port)); + close(res); + return -1; + } #ifdef EISCONN - if (ret < 0 && errno == EISCONN) { - errno = 0; - ret = 0; - } + + if (ret < 0 && errno == EISCONN) { + errno = 0; + ret = 0; + } #endif - if (ret < 0) { - DEBUG(2,("error connecting to %s:%d (%s)\n", - inet_ntoa(*addr),port,strerror(errno))); - close(res); - return -1; - } + if (ret < 0) { + DEBUG(2,("error connecting to %s:%d (%s)\n", + inet_ntoa(*addr),port,strerror(errno))); + close(res); + return -1; + } - /* set it blocking again */ - set_blocking(res,True); + /* set it blocking again */ + set_blocking(res,True); - return res; + return res; } -/* - open a connected UDP socket to host on port -*/ +/**************************************************************************** + Open a connected UDP socket to host on port +**************************************************************************/ + int open_udp_socket(const char *host, int port) { int type = SOCK_DGRAM; @@ -783,9 +800,10 @@ struct in_addr *client_inaddr(struct sockaddr *sa) } /******************************************************************* - matchname - determine if host name matches IP address. Used to - confirm a hostname lookup to prevent spoof attacks - ******************************************************************/ + Matchname - determine if host name matches IP address. Used to + confirm a hostname lookup to prevent spoof attacks. +******************************************************************/ + static BOOL matchname(char *remotehost,struct in_addr addr) { struct hostent *hp; @@ -828,10 +846,10 @@ static BOOL matchname(char *remotehost,struct in_addr addr) return False; } - /******************************************************************* - return the DNS name of the remote end of a socket - ******************************************************************/ + Return the DNS name of the remote end of a socket. +******************************************************************/ + char *get_socket_name(int fd, BOOL force_lookup) { static pstring name_buf; @@ -881,8 +899,9 @@ char *get_socket_name(int fd, BOOL force_lookup) } /******************************************************************* - return the IP addr of the remote end of a socket as a string + Return the IP addr of the remote end of a socket as a string. ******************************************************************/ + char *get_socket_addr(int fd) { struct sockaddr sa; @@ -906,7 +925,6 @@ char *get_socket_addr(int fd) return addr_buf; } - /******************************************************************* Create protected unix domain socket. @@ -968,7 +986,7 @@ int create_pipe_sock(const char *socket_dir, goto out_umask; } - snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name); + pstr_sprintf(path, "%s/%s", socket_dir, socket_name); unlink(path); memset(&sunaddr, 0, sizeof(sunaddr)); diff --git a/source/lib/util_str.c b/source/lib/util_str.c index 96fbc3f1247..eb1c70d4129 100644 --- a/source/lib/util_str.c +++ b/source/lib/util_str.c @@ -37,7 +37,7 @@ **/ BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize) { - const char *s; + char *s; char *pbuf; BOOL quoted; size_t len=1; @@ -45,7 +45,7 @@ BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize) if (!ptr) return(False); - s = *ptr; + s = (char *)*ptr; /* default to simple separators */ if (!sep) @@ -88,7 +88,7 @@ BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize) { BOOL ret; if (!ptr) - ptr = (const char **)&last_ptr; + ptr = &last_ptr; ret = next_token(ptr, buff, sep, bufsize); last_ptr = *ptr; @@ -109,7 +109,7 @@ void set_first_token(char *ptr) char **toktocliplist(int *ctok, const char *sep) { - char *s=last_ptr; + char *s=(char *)last_ptr; int ictok=0; char **ret, **iret; @@ -132,7 +132,7 @@ char **toktocliplist(int *ctok, const char *sep) } while(*s); *ctok=ictok; - s=last_ptr; + s=(char *)last_ptr; if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL; @@ -181,7 +181,9 @@ int StrCaseCmp(const char *s, const char *t) { const char * ps, * pt; - pstring buf1, buf2; + size_t size; + smb_ucs2_t *buffer_s, *buffer_t; + int ret; for (ps = s, pt = t; ; ps++, pt++) { char us, ut; @@ -206,16 +208,25 @@ int StrCaseCmp(const char *s, const char *t) return +1; } - /* TODO: Don't do this with a fixed-length buffer. This could - * still be much more efficient. */ - /* TODO: Hardcode a char-by-char comparison for UTF-8, which - * can be much faster. */ - /* TODO: Test case for this! */ - - unix_strupper(ps, strlen(ps)+1, buf1, sizeof(buf1)); - unix_strupper(pt, strlen(pt)+1, buf2, sizeof(buf2)); - - return strcmp(buf1, buf2); + size = push_ucs2_allocate(&buffer_s, s); + if (size == (size_t)-1) { + return strcmp(s, t); + /* Not quite the right answer, but finding the right one + under this failure case is expensive, and it's pretty close */ + } + + size = push_ucs2_allocate(&buffer_t, t); + if (size == (size_t)-1) { + SAFE_FREE(buffer_s); + return strcmp(s, t); + /* Not quite the right answer, but finding the right one + under this failure case is expensive, and it's pretty close */ + } + + ret = strcasecmp_w(buffer_s, buffer_t); + SAFE_FREE(buffer_s); + SAFE_FREE(buffer_t); + return ret; } @@ -351,7 +362,7 @@ BOOL strisnormal(const char *s) NOTE: oldc and newc must be 7 bit characters **/ -void string_replace(char *s,char oldc,char newc) +void string_replace(pstring s,char oldc,char newc) { push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE); string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc)); @@ -1156,21 +1167,6 @@ void strlower_m(char *s) } /** - Duplicate convert a string to lower case. -**/ - -char *strdup_lower(const char *s) -{ - char *t = strdup(s); - if (t == NULL) { - DEBUG(0, ("strdup_lower: Out of memory!\n")); - return NULL; - } - strlower_m(t); - return t; -} - -/** Convert a string to upper case. **/ @@ -1195,21 +1191,6 @@ void strupper_m(char *s) } /** - Convert a string to upper case. -**/ - -char *strdup_upper(const char *s) -{ - char *t = strdup(s); - if (t == NULL) { - DEBUG(0, ("strdup_upper: Out of memory!\n")); - return NULL; - } - strupper_m(t); - return t; -} - -/** Return a RFC2254 binary string representation of a buffer. Used in LDAP filters. Caller must free. @@ -1575,7 +1556,7 @@ int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list) count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1; if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) { - DEBUG(0,("ipstr_list_parse: malloc failed for %d entries\n", count)); + DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count)); return 0; } diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c index ae000fba023..fd51f3c57d9 100644 --- a/source/lib/util_unistr.c +++ b/source/lib/util_unistr.c @@ -759,82 +759,6 @@ smb_ucs2_t *strstr_wa(const smb_ucs2_t *s, const char *ins) return NULL; } -/******************************************************************* -copy a string with max len -********************************************************************/ - -smb_ucs2_t *strncpy_wa(smb_ucs2_t *dest, const char *src, const size_t max) -{ - smb_ucs2_t *ucs2_src; - - if (!dest || !src) return NULL; - if (!(ucs2_src = acnv_uxu2(src))) - return NULL; - - strncpy_w(dest, ucs2_src, max); - SAFE_FREE(ucs2_src); - return dest; -} - -/******************************************************************* -convert and duplicate an ascii string -********************************************************************/ -smb_ucs2_t *strdup_wa(const char *src) -{ - return strndup_wa(src, 0); -} - -/* if len == 0 then duplicate the whole string */ -smb_ucs2_t *strndup_wa(const char *src, size_t len) -{ - smb_ucs2_t *dest, *s; - - s = acnv_dosu2(src); - if (!len) len = strlen_w(s); - dest = (smb_ucs2_t *)malloc((len + 1) * sizeof(smb_ucs2_t)); - if (!dest) { - DEBUG(0,("strdup_w: out of memory!\n")); - SAFE_FREE(s); - return NULL; - } - - memcpy(dest, src, len * sizeof(smb_ucs2_t)); - dest[len] = 0; - - SAFE_FREE(s); - return dest; -} - -/******************************************************************* -append a string of len bytes and add a terminator -********************************************************************/ - -smb_ucs2_t *strncat_wa(smb_ucs2_t *dest, const char *src, const size_t max) -{ - smb_ucs2_t *ucs2_src; - - if (!dest || !src) return NULL; - if (!(ucs2_src = acnv_uxu2(src))) - return NULL; - - strncat_w(dest, ucs2_src, max); - SAFE_FREE(ucs2_src); - return dest; -} - -smb_ucs2_t *strcat_wa(smb_ucs2_t *dest, const char *src) -{ - smb_ucs2_t *ucs2_src; - - if (!dest || !src) return NULL; - if (!(ucs2_src = acnv_uxu2(src))) - return NULL; - - strcat_w(dest, ucs2_src); - SAFE_FREE(ucs2_src); - return dest; -} - BOOL trim_string_wa(smb_ucs2_t *s, const char *front, const char *back) { diff --git a/source/lib/util_uuid.c b/source/lib/util_uuid.c index 83553ec28ec..56f0ecd85b9 100644 --- a/source/lib/util_uuid.c +++ b/source/lib/util_uuid.c @@ -2,7 +2,7 @@ * Unix SMB/CIFS implementation. * UUID server routines * Copyright (C) Theodore Ts'o 1996, 1997, - * Copyright (C) Jim McDonough 2002. + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by |