summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/charcnv.c45
-rw-r--r--source3/lib/gencache.c29
-rw-r--r--source3/lib/module.c23
-rw-r--r--source3/lib/popt_common.c4
-rw-r--r--source3/lib/substitute.c20
-rw-r--r--source3/lib/system.c125
-rw-r--r--source3/lib/system_smbd.c24
-rw-r--r--source3/lib/time.c3
-rw-r--r--source3/lib/username.c76
-rw-r--r--source3/lib/util.c49
-rw-r--r--source3/lib/util_sid.c6
-rw-r--r--source3/lib/util_sock.c24
-rw-r--r--source3/lib/util_str.c107
-rw-r--r--source3/lib/util_unistr.c31
-rw-r--r--source3/lib/util_uuid.c6
-rw-r--r--source3/lib/wins_srv.c20
16 files changed, 470 insertions, 122 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index eb427cc0fc..4e9c2c1592 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -55,6 +55,30 @@ static const char *charset_name(charset_t ch)
else if (ch == CH_DISPLAY) ret = lp_display_charset();
else if (ch == CH_UTF8) ret = "UTF8";
+#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
+ if (ret && strcasecmp(ret, "LOCALE") == 0) {
+ const char *ln = NULL;
+
+#ifdef HAVE_SETLOCALE
+ setlocale(LC_ALL, "");
+#endif
+ ln = nl_langinfo(CODESET);
+ if (ln) {
+ /* Check whether the charset name is supported
+ by iconv */
+ smb_iconv_t handle = smb_iconv_open(ln,"UCS-2LE");
+ if (handle == (smb_iconv_t) -1) {
+ DEBUG(5,("Locale charset '%s' unsupported, using ASCII instead\n", ln));
+ ln = NULL;
+ } else {
+ DEBUG(5,("Substituting charset '%s' for LOCALE\n", ln));
+ smb_iconv_close(handle);
+ }
+ }
+ ret = ln;
+ }
+#endif
+
if (!ret || !*ret) ret = "ASCII";
return ret;
}
@@ -363,11 +387,11 @@ size_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
if (flags & STR_UPPER) {
pstrcpy(tmpbuf, src);
- strupper(tmpbuf);
+ strupper_m(tmpbuf);
src = tmpbuf;
}
- if (flags & STR_TERMINATE)
+ if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
src_len++;
return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len);
@@ -464,7 +488,7 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_
if (flags & STR_UPPER) {
pstrcpy(tmpbuf, src);
- strupper(tmpbuf);
+ strupper_m(tmpbuf);
src = tmpbuf;
}
@@ -542,7 +566,7 @@ static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags)
if (flags & STR_UPPER) {
pstrcpy(tmpbuf, src);
- strupper(tmpbuf);
+ strupper_m(tmpbuf);
src = tmpbuf;
}
@@ -723,8 +747,21 @@ size_t pull_utf8_allocate(void **dest, const char *src)
size_t push_string_fn(const char *function, unsigned int line, const void *base_ptr, void *dest, const char *src, size_t dest_len, int flags)
{
+#ifdef DEVELOPER
+ /* We really need to zero fill here, not clobber
+ * region, as we want to ensure that valgrind thinks
+ * all of the outgoing buffer has been written to
+ * so a send() or write() won't trap an error.
+ * JRA.
+ */
+#if 0
if (dest_len != (size_t)-1)
clobber_region(function, line, dest, dest_len);
+#else
+ if (dest_len != (size_t)-1)
+ memset(dest, '\0', dest_len);
+#endif
+#endif
if (!(flags & STR_ASCII) && \
((flags & STR_UNICODE || \
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index 40b4d1390d..f3740e3e12 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -319,9 +319,8 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
while (node) {
/* ensure null termination of the key string */
- node->node_key.dptr[node->node_key.dsize] = '\0';
- keystr = node->node_key.dptr;
-
+ keystr = strndup(node->node_key.dptr, node->node_key.dsize);
+
/*
* We don't use gencache_get function, because we need to iterate through
* all of the entries. Validity verification is up to fn routine.
@@ -329,6 +328,8 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
databuf = tdb_fetch(cache, node->node_key);
if (!databuf.dptr || databuf.dsize <= TIMEOUT_LEN) {
SAFE_FREE(databuf.dptr);
+ SAFE_FREE(keystr);
+ node = node->next;
continue;
}
entry = strndup(databuf.dptr, databuf.dsize);
@@ -342,8 +343,30 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
SAFE_FREE(valstr);
SAFE_FREE(entry);
+ SAFE_FREE(keystr);
node = node->next;
}
tdb_search_list_free(first_node);
}
+
+/********************************************************************
+ lock a key
+********************************************************************/
+
+int gencache_lock_entry( const char *key )
+{
+ return tdb_lock_bystring(cache, key, 0);
+}
+
+/********************************************************************
+ unlock a key
+********************************************************************/
+
+void gencache_unlock_entry( const char *key )
+{
+ tdb_unlock_bystring(cache, key);
+ return;
+}
+
+
diff --git a/source3/lib/module.c b/source3/lib/module.c
index 4437d085f9..ac4fe57a2c 100644
--- a/source3/lib/module.c
+++ b/source3/lib/module.c
@@ -130,29 +130,6 @@ void init_modules(void)
}
-/*************************************************************************
- * This functions /path/to/foobar.so -> foobar
- ************************************************************************/
-void module_path_get_name(const char *path, pstring name)
-{
- char *s;
-
- /* First, make the path relative */
- s = strrchr(path, '/');
- if(s) pstrcpy(name, s+1);
- else pstrcpy(name, path);
-
- if (dyn_SHLIBEXT && *dyn_SHLIBEXT && strlen(dyn_SHLIBEXT) < strlen(name)) {
- int n = strlen(name) - strlen(dyn_SHLIBEXT);
-
- /* Remove extension if necessary */
- if (name[n-1] == '.' && !strcmp(name+n, dyn_SHLIBEXT)) {
- name[n-1] = '\0';
- }
- }
-}
-
-
/***************************************************************************
* This Function registers a idle event
*
diff --git a/source3/lib/popt_common.c b/source3/lib/popt_common.c
index 6920ef4d5f..b8e77b2d9e 100644
--- a/source3/lib/popt_common.c
+++ b/source3/lib/popt_common.c
@@ -335,8 +335,8 @@ static void popt_common_credentials_callback(poptContext con,
struct poptOption popt_common_credentials[] = {
{ NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE, popt_common_credentials_callback },
{ "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set the network username", "USERNAME" },
- { "no-pass", 'N', POPT_ARG_NONE, &cmdline_auth_info.got_pass, True, "Don't ask for a password" },
- { "kerberos", 'k', POPT_ARG_NONE, &cmdline_auth_info.use_kerberos, True, "Use kerberos (active directory) authentication" },
+ { "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" },
POPT_TABLEEND
};
diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c
index 7ba8648156..ac2cf687c4 100644
--- a/source3/lib/substitute.c
+++ b/source3/lib/substitute.c
@@ -58,7 +58,7 @@ void set_local_machine_name(const char* local_name, BOOL perm)
fstrcpy(tmp_local_machine,local_name);
trim_string(tmp_local_machine," "," ");
- strlower(tmp_local_machine);
+ strlower_m(tmp_local_machine);
alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
}
@@ -80,7 +80,7 @@ void set_remote_machine_name(const char* remote_name, BOOL perm)
fstrcpy(tmp_remote_machine,remote_name);
trim_string(tmp_remote_machine," "," ");
- strlower(tmp_remote_machine);
+ strlower_m(tmp_remote_machine);
alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1);
}
@@ -111,7 +111,7 @@ void sub_set_smb_name(const char *name)
fstrcpy(tmp,name);
trim_string(tmp," "," ");
- strlower(tmp);
+ strlower_m(tmp);
alpha_strcpy(smb_user_name,tmp,SAFE_NETBIOS_CHARS,sizeof(smb_user_name)-1);
}
@@ -331,7 +331,7 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
switch (*(p+1)) {
case 'U' :
fstrcpy(tmp_str, smb_name);
- strlower(tmp_str);
+ strlower_m(tmp_str);
string_sub(p,"%U",tmp_str,l);
break;
case 'G' :
@@ -344,7 +344,7 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
break;
case 'D' :
fstrcpy(tmp_str, current_user_info.domain);
- strupper(tmp_str);
+ strupper_m(tmp_str);
string_sub(p,"%D", tmp_str,l);
break;
case 'I' :
@@ -357,7 +357,7 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
pstring temp_name;
pstrcpy(temp_name, global_myname());
- strlower(temp_name);
+ strlower_m(temp_name);
string_sub(p,"%L", temp_name,l);
}
break;
@@ -650,7 +650,7 @@ char *talloc_sub_advanced(TALLOC_CTX *mem_ctx,
const char *connectpath,
gid_t gid,
const char *smb_name,
- char *str)
+ const char *str)
{
char *a, *t;
a = alloc_sub_advanced(snum, user, connectpath, gid, smb_name, str);
@@ -662,7 +662,7 @@ char *talloc_sub_advanced(TALLOC_CTX *mem_ctx,
char *alloc_sub_advanced(int snum, const char *user,
const char *connectpath, gid_t gid,
- const char *smb_name, char *str)
+ const char *smb_name, const char *str)
{
char *a_string, *ret_string;
char *b, *p, *s, *t, *h;
@@ -736,14 +736,14 @@ void standard_sub_conn(connection_struct *conn, char *str, size_t len)
conn->gid, smb_user_name, str, len);
}
-char *talloc_sub_conn(TALLOC_CTX *mem_ctx, connection_struct *conn, char *str)
+char *talloc_sub_conn(TALLOC_CTX *mem_ctx, connection_struct *conn, const char *str)
{
return talloc_sub_advanced(mem_ctx, SNUM(conn), conn->user,
conn->connectpath, conn->gid,
smb_user_name, str);
}
-char *alloc_sub_conn(connection_struct *conn, char *str)
+char *alloc_sub_conn(connection_struct *conn, const char *str)
{
return alloc_sub_advanced(SNUM(conn), conn->user, conn->connectpath,
conn->gid, smb_user_name, str);
diff --git a/source3/lib/system.c b/source3/lib/system.c
index 6ff97b88da..a7024c852d 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -1253,3 +1253,128 @@ int sys_dup2(int oldfd, int newfd)
#endif
SAFE_FREE(msgbuf);
}
+
+/**************************************************************************
+ Wrappers for extented attribute calls. Based on the Linux package with
+ support for IRIX also. Expand as other systems have them.
+****************************************************************************/
+
+ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
+{
+#if defined(HAVE_GETXATTR)
+ return getxattr(path, name, value, size);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
+{
+#if defined(HAVE_LGETXATTR)
+ return lgetxattr(path, name, value, size);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
+{
+#if defined(HAVE_FGETXATTR)
+ return fgetxattr(filedes, name, value, size);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+ssize_t sys_listxattr (const char *path, char *list, size_t size)
+{
+#if defined(HAVE_LISTXATTR)
+ return listxattr(path, list, size);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+ssize_t sys_llistxattr (const char *path, char *list, size_t size)
+{
+#if defined(HAVE_GETXATTR)
+ return llistxattr(path, list, size);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+ssize_t sys_flistxattr (int filedes, char *list, size_t size)
+{
+#if defined(HAVE_FLISTXATTR)
+ return flistxattr(filedes, list, size);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int sys_removexattr (const char *path, const char *name)
+{
+#if defined(HAVE_REMOVEXATTR)
+ return removexattr(path, name);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int sys_lremovexattr (const char *path, const char *name)
+{
+#if defined(HAVE_LREMOVEXATTR)
+ return lremovexattr(path, name);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int sys_fremovexattr (int filedes, const char *name)
+{
+#if defined(HAVE_FREMOVEXATTR)
+ return fremovexattr(filedes, name);
+#else
+ errno = ENOSYS;
+ return -1;
+#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);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
+{
+#if defined(HAVE_LSETXATTR)
+ return lsetxattr(path, name, value, size, flags);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
+{
+#if defined(HAVE_FSETXATTR)
+ return fsetxattr(filedes, name, value, size, flags);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
diff --git a/source3/lib/system_smbd.c b/source3/lib/system_smbd.c
index 3ae0a6395e..bcbc8c61e6 100644
--- a/source3/lib/system_smbd.c
+++ b/source3/lib/system_smbd.c
@@ -107,13 +107,31 @@ static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, in
int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
{
+ char *p;
+ int retval;
+
+ DEBUG(10,("sys_getgrouplist: user [%s]\n", user));
+
+ /* see if we should disable winbindd lookups for local users */
+ if ( (p = strchr(user, *lp_winbind_separator())) == NULL ) {
+ if ( !winbind_off() )
+ DEBUG(0,("sys_getgroup_list: Insufficient environment space for %s\n",
+ WINBINDD_DONT_ENV));
+ else
+ DEBUG(10,("sys_getgrouplist(): disabled winbindd for group lookup [user == %s]\n",
+ user));
+ }
+
#ifdef HAVE_GETGROUPLIST
- return getgrouplist(user, gid, groups, grpcnt);
+ retval = getgrouplist(user, gid, groups, grpcnt);
#else
- int retval;
become_root();
retval = getgrouplist_internals(user, gid, groups, grpcnt);
unbecome_root();
- return retval;
#endif
+
+ /* allow winbindd lookups */
+ winbind_on();
+
+ return retval;
}
diff --git a/source3/lib/time.c b/source3/lib/time.c
index f76a1bdc0d..5309711a05 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -308,7 +308,8 @@ time_t nt_time_to_unix(NTTIME *nt)
time_t l_time_min = TIME_T_MIN;
time_t l_time_max = TIME_T_MAX;
- if (nt->high == 0) return(0);
+ if (nt->high == 0 || (nt->high == 0xffffffff && nt->low == 0xffffffff))
+ return(0);
d = ((double)nt->high)*4.0*(double)(1<<30);
d += (nt->low&0xFFF00000);
diff --git a/source3/lib/username.c b/source3/lib/username.c
index d8f4ff80ed..98b8f33aae 100644
--- a/source3/lib/username.c
+++ b/source3/lib/username.c
@@ -219,7 +219,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
/* Try in all lower case first as this is the most
common case on UNIX systems */
- strlower(user2);
+ strlower_m(user2);
DEBUG(5,("Trying _Get_Pwnam(), username as lowercase is %s\n",user2));
ret = getpwnam_alloc(user2);
if(ret)
@@ -234,7 +234,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
}
/* Try as uppercase, if username wasn't originally uppercase */
- strupper(user2);
+ strupper_m(user2);
if(strcmp(user, user2) != 0) {
DEBUG(5,("Trying _Get_Pwnam(), username as uppercase is %s\n", user2));
ret = getpwnam_alloc(user2);
@@ -243,7 +243,7 @@ static struct passwd *Get_Pwnam_internals(const char *user, char *user2)
}
/* Try all combinations up to usernamelevel */
- strlower(user2);
+ strlower_m(user2);
DEBUG(5,("Checking combinations of %d uppercase letters in %s\n", lp_usernamelevel(), user2));
ret = uname_string_combinations(user2, getpwnam_alloc, lp_usernamelevel());
@@ -325,11 +325,12 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL *winbind_answered)
{
- int num_groups;
int i;
- gid_t *groups = NULL;
gid_t gid, gid_low, gid_high;
BOOL ret = False;
+ static gid_t *groups = NULL;
+ static int num_groups = 0;
+ static fstring last_user = "";
*winbind_answered = False;
@@ -349,27 +350,44 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL
goto err;
}
- /*
- * Get the gid's that this user belongs to.
- */
-
- if ((num_groups = winbind_getgroups(user, 0, NULL)) == -1)
- return False;
+ /* try to user the last user we looked up */
+ /* otherwise fall back to lookups */
+
+ if ( !strequal( last_user, user ) || !groups )
+ {
+ /* clear any cached information */
+
+ SAFE_FREE(groups);
+ fstrcpy( last_user, "" );
+
+ /*
+ * Get the gid's that this user belongs to.
+ */
- if (num_groups == 0) {
- *winbind_answered = True;
- return False;
- }
+ if ((num_groups = winbind_getgroups(user, &groups)) == -1)
+ return False;
+
+ if ( num_groups == -1 )
+ return False;
- if ((groups = (gid_t *)malloc(sizeof(gid_t) * num_groups )) == NULL) {
- DEBUG(0,("user_in_winbind_group_list: malloc fail.\n"));
- goto err;
- }
+ if ( num_groups == 0 ) {
+ *winbind_answered = True;
+ return False;
+ }
+
+ /* save the last username */
+
+ fstrcpy( last_user, user );
+
+ }
+ else
+ DEBUG(10,("user_in_winbind_group_list: using cached user groups for [%s]\n", user));
- if ((num_groups = winbind_getgroups(user, num_groups, groups)) == -1) {
- DEBUG(0,("user_in_winbind_group_list: second winbind_getgroups call \
-failed with error %s\n", strerror(errno) ));
- goto err;
+ 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,("\n"));
}
/*
@@ -571,10 +589,16 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups, size_t n_gr
fstrcpy(domain, *list);
domain[PTR_DIFF(p, *list)] = 0;
- /* Check to see if name is a Windows group */
- if (winbind_lookup_name(domain, groupname, &g_sid, &name_type) && name_type == SID_NAME_DOM_GRP) {
+ /* Check to see if name is a Windows group; Win2k native mode DCs
+ will return domain local groups; while NT4 or mixed mode 2k DCs
+ will not */
+
+ if ( winbind_lookup_name(NULL, *list, &g_sid, &name_type)
+ && ( name_type==SID_NAME_DOM_GRP ||
+ (strequal(lp_workgroup(), domain) && name_type==SID_NAME_ALIAS) ) )
+ {
- /* Check if user name is in the Windows group */
+ /* Check if user name is in the Windows group */
ret = user_in_winbind_group_list(user, *list, &winbind_answered);
if (winbind_answered && ret == True) {
diff --git a/source3/lib/util.c b/source3/lib/util.c
index e1ddd57883..a7c939fe5a 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -99,7 +99,7 @@ BOOL set_global_myname(const char *myname)
smb_myname = strdup(myname);
if (!smb_myname)
return False;
- strupper(smb_myname);
+ strupper_m(smb_myname);
return True;
}
@@ -118,7 +118,7 @@ BOOL set_global_myworkgroup(const char *myworkgroup)
smb_myworkgroup = strdup(myworkgroup);
if (!smb_myworkgroup)
return False;
- strupper(smb_myworkgroup);
+ strupper_m(smb_myworkgroup);
return True;
}
@@ -137,7 +137,7 @@ BOOL set_global_scope(const char *scope)
smb_scope = strdup(scope);
if (!smb_scope)
return False;
- strupper(smb_scope);
+ strupper_m(smb_scope);
return True;
}
@@ -184,7 +184,7 @@ static BOOL set_my_netbios_names(const char *name, int i)
smb_my_netbios_names[i] = strdup(name);
if (!smb_my_netbios_names[i])
return False;
- strupper(smb_my_netbios_names[i]);
+ strupper_m(smb_my_netbios_names[i]);
return True;
}
@@ -265,7 +265,7 @@ BOOL init_names(void)
p = strchr( local_machine, ' ' );
if (p)
*p = 0;
- strlower( local_machine );
+ strlower_m( local_machine );
DEBUG( 5, ("Netbios name list:-\n") );
for( n=0; my_netbios_names(n); n++ )
@@ -937,6 +937,19 @@ void *Realloc(void *p,size_t size)
return(ret);
}
+void *Realloc_zero(void *ptr, size_t size)
+{
+ void *tptr = NULL;
+
+ tptr = Realloc(ptr, size);
+ if(tptr == NULL)
+ return NULL;
+
+ memset((char *)tptr,'\0',size);
+
+ return tptr;
+}
+
/****************************************************************************
Free memory, checks for NULL.
Use directly SAFE_FREE()
@@ -1367,7 +1380,7 @@ char *gidtoname(gid_t gid)
Convert a user name into a uid.
********************************************************************/
-uid_t nametouid(char *name)
+uid_t nametouid(const char *name)
{
struct passwd *pass;
char *p;
@@ -1898,6 +1911,17 @@ void dump_data(int level, const char *buf1,int len)
}
}
+void dump_data_pw(const char *msg, const uchar * data, size_t len)
+{
+#ifdef DEBUG_PASSWORD
+ DEBUG(11, ("%s", msg));
+ if (data != NULL && len > 0)
+ {
+ dump_data(11, data, len);
+ }
+#endif
+}
+
char *tab_depth(int depth)
{
static pstring spaces;
@@ -2323,8 +2347,8 @@ BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
fstrcpy(p2, pattern);
fstrcpy(s2, string);
- strlower(p2);
- strlower(s2);
+ strlower_m(p2);
+ strlower_m(s2);
return ms_fnmatch(p2, s2, Protocol) == 0;
}
@@ -2332,9 +2356,9 @@ BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
Recursive routine that is called by unix_wild_match.
*********************************************************/
-static BOOL unix_do_match(char *regexp, char *str)
+static BOOL unix_do_match(const char *regexp, const char *str)
{
- char *p;
+ const char *p;
for( p = regexp; *p && *str; ) {
@@ -2440,8 +2464,8 @@ BOOL unix_wild_match(const char *pattern, const char *string)
pstrcpy(p2, pattern);
pstrcpy(s2, string);
- strlower(p2);
- strlower(s2);
+ strlower_m(p2);
+ strlower_m(s2);
/* Remove any *? and ** from the pattern as they are meaningless */
for(p = p2; *p; p++)
@@ -2454,6 +2478,7 @@ BOOL unix_wild_match(const char *pattern, const char *string)
return unix_do_match(p2, s2) == 0;
}
+
#ifdef __INSURE__
/*******************************************************************
diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c
index 9dc0c8ca18..00f14d7d26 100644
--- a/source3/lib/util_sid.c
+++ b/source3/lib/util_sid.c
@@ -391,6 +391,9 @@ BOOL sid_peek_check_rid(const DOM_SID *exp_dom_sid, const DOM_SID *sid, uint32 *
if (!exp_dom_sid || !sid || !rid)
return False;
+ if (sid->num_auths != (exp_dom_sid->num_auths+1)) {
+ return False;
+ }
if (sid_compare_domain(exp_dom_sid, sid)!=0){
*rid=(-1);
@@ -642,8 +645,9 @@ DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, DOM_SID *src)
if(!src)
return NULL;
- if((dst = talloc_zero(ctx, sizeof(DOM_SID))) != NULL)
+ if((dst = talloc_zero(ctx, sizeof(DOM_SID))) != NULL) {
sid_copy( dst, src);
+ }
return dst;
}
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index c974050b43..1bd4c3a96b 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -654,8 +654,8 @@ 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 = 250; /* 250 milliseconds */
- int loops = (timeout) / connect_loop;
+ int connect_loop = 10;
+ int increment = 10;
/* create a socket to write to */
res = socket(PF_INET, type, 0);
@@ -681,8 +681,13 @@ connect_again:
/* Some systems return EAGAIN when they mean EINPROGRESS */
if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
- errno == EAGAIN) && loops--) {
+ 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;
}
@@ -764,6 +769,19 @@ char *client_addr(void)
return get_socket_addr(client_fd);
}
+struct in_addr *client_inaddr(struct sockaddr *sa)
+{
+ struct sockaddr_in *sockin = (struct sockaddr_in *) (sa);
+ int length = sizeof(*sa);
+
+ if (getpeername(client_fd, sa, &length) < 0) {
+ DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
+ return NULL;
+ }
+
+ return &sockin->sin_addr;
+}
+
/*******************************************************************
matchname - determine if host name matches IP address. Used to
confirm a hostname lookup to prevent spoof attacks
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index e561d15f61..96fbc3f124 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -38,6 +38,7 @@
BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
{
const char *s;
+ char *pbuf;
BOOL quoted;
size_t len=1;
@@ -59,17 +60,18 @@ BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
return(False);
/* copy over the token */
+ pbuf = buff;
for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
if (*s == '\"') {
quoted = !quoted;
} else {
len++;
- *buff++ = *s;
+ *pbuf++ = *s;
}
}
*ptr = (*s) ? s+1 : s;
- *buff = 0;
+ *pbuf = 0;
return(True);
}
@@ -312,7 +314,7 @@ char *strupper_static(const char *s)
static pstring str;
pstrcpy(str, s);
- strupper(str);
+ strupper_m(str);
return str;
}
@@ -325,9 +327,9 @@ void strnorm(char *s)
{
extern int case_default;
if (case_default == CASE_UPPER)
- strupper(s);
+ strupper_m(s);
else
- strlower(s);
+ strlower_m(s);
}
/**
@@ -1109,6 +1111,26 @@ char *strrchr_m(const char *s, char c)
return (char *)(s+strlen(s2));
}
+/***********************************************************************
+ Return the equivalent of doing strrchr 'n' times - always going
+ backwards.
+***********************************************************************/
+
+char *strnrchr_m(const char *s, char c, unsigned int n)
+{
+ wpstring ws;
+ pstring s2;
+ smb_ucs2_t *p;
+
+ push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
+ p = strnrchr_w(ws, UCS2_CHAR(c), n);
+ if (!p)
+ return NULL;
+ *p = 0;
+ pull_ucs2_pstring(s2, ws);
+ return (char *)(s+strlen(s2));
+}
+
/**
Convert a string to lower case.
**/
@@ -1469,6 +1491,7 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
#define IPSTR_LIST_SEP ","
+#define IPSTR_LIST_CHAR ','
/**
* Add ip string representation to ipstr list. Used also
@@ -1483,19 +1506,20 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
* reallocated to new length
**/
-char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
+char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
{
char* new_ipstr = NULL;
/* arguments checking */
- if (!ipstr_list || !ip) return NULL;
+ if (!ipstr_list || !service) return NULL;
/* attempt to convert ip to a string and append colon separator to it */
if (*ipstr_list) {
- asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
+ asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
+ inet_ntoa(service->ip), service->port);
SAFE_FREE(*ipstr_list);
} else {
- asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
+ asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
}
*ipstr_list = new_ipstr;
return *ipstr_list;
@@ -1512,7 +1536,7 @@ char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
* @return pointer to allocated ip string
**/
-char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
+char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
{
int i;
@@ -1531,7 +1555,8 @@ char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_c
/**
* Parse given ip string list into array of ip addresses
- * (as in_addr structures)
+ * (as ip_service structures)
+ * e.g. 192.168.1.100:389,192.168.1.78, ...
*
* @param ipstr ip string list to be parsed
* @param ip_list pointer to array of ip addresses which is
@@ -1539,28 +1564,40 @@ char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_c
* @return number of succesfully parsed addresses
**/
-int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
+int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
{
fstring token_str;
- int count;
+ size_t count;
+ int i;
- if (!ipstr_list || !ip_list) return 0;
+ if (!ipstr_list || !ip_list)
+ return 0;
+
+ 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));
+ return 0;
+ }
- for (*ip_list = NULL, count = 0;
- next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
- count++) {
-
+ for ( i=0;
+ next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
+ i++ )
+ {
struct in_addr addr;
+ unsigned port = 0;
+ char *p = strchr(token_str, ':');
+
+ if (p) {
+ *p = 0;
+ port = atoi(p+1);
+ }
/* convert single token to ip address */
if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
break;
-
- /* prepare place for another in_addr structure */
- *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
- if (!*ip_list) return -1;
-
- (*ip_list)[count] = addr;
+
+ (*ip_list)[i].ip = addr;
+ (*ip_list)[i].port = port;
}
return count;
@@ -1713,3 +1750,25 @@ char * base64_encode_data_blob(DATA_BLOB data)
return result;
}
+/* read a SMB_BIG_UINT from a string */
+SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
+{
+
+ SMB_BIG_UINT val = -1;
+ const char *p = nptr;
+
+ while (p && *p && isspace(*p))
+ p++;
+#ifdef LARGE_SMB_OFF_T
+ sscanf(p,"%llu",&val);
+#else /* LARGE_SMB_OFF_T */
+ sscanf(p,"%lu",&val);
+#endif /* LARGE_SMB_OFF_T */
+ if (entptr) {
+ while (p && *p && isdigit(*p))
+ p++;
+ *entptr = p;
+ }
+
+ return val;
+}
diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c
index 5df0828295..ae000fba02 100644
--- a/source3/lib/util_unistr.c
+++ b/source3/lib/util_unistr.c
@@ -391,8 +391,9 @@ size_t strnlen_w(const smb_ucs2_t *src, size_t max)
}
/*******************************************************************
-wide strchr()
+ Wide strchr().
********************************************************************/
+
smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
{
while (*s != 0) {
@@ -409,6 +410,10 @@ smb_ucs2_t *strchr_wa(const smb_ucs2_t *s, char c)
return strchr_w(s, UCS2_CHAR(c));
}
+/*******************************************************************
+ Wide strrchr().
+********************************************************************/
+
smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
{
const smb_ucs2_t *p = s;
@@ -422,8 +427,30 @@ smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
}
/*******************************************************************
-wide strstr()
+ Wide version of strrchr that returns after doing strrchr 'n' times.
********************************************************************/
+
+smb_ucs2_t *strnrchr_w(const smb_ucs2_t *s, smb_ucs2_t c, unsigned int n)
+{
+ const smb_ucs2_t *p = s;
+ int len = strlen_w(s);
+ if (len == 0 || !n)
+ return NULL;
+ p += (len - 1);
+ do {
+ if (c == *p)
+ n--;
+
+ if (!n)
+ return (smb_ucs2_t *)p;
+ } while (p-- != s);
+ return NULL;
+}
+
+/*******************************************************************
+ Wide strstr().
+********************************************************************/
+
smb_ucs2_t *strstr_w(const smb_ucs2_t *s, const smb_ucs2_t *ins)
{
smb_ucs2_t *r;
diff --git a/source3/lib/util_uuid.c b/source3/lib/util_uuid.c
index 699f2cd632..83553ec28e 100644
--- a/source3/lib/util_uuid.c
+++ b/source3/lib/util_uuid.c
@@ -58,7 +58,7 @@ static void uuid_unpack(const GUID in, struct uuid *uu)
memcpy(uu->node, ptr+10, 6);
}
-void uuid_generate_random(GUID *out)
+void smb_uuid_generate_random(GUID *out)
{
GUID tmp;
struct uuid uu;
@@ -71,7 +71,7 @@ void uuid_generate_random(GUID *out)
uuid_pack(&uu, out);
}
-char *guid_to_string(const GUID in)
+char *smb_uuid_to_string(const GUID in)
{
struct uuid uu;
char *out;
@@ -87,7 +87,7 @@ char *guid_to_string(const GUID in)
return out;
}
-const char *uuid_string_static(const GUID in)
+const char *smb_uuid_string_static(const GUID in)
{
struct uuid uu;
static char out[37];
diff --git a/source3/lib/wins_srv.c b/source3/lib/wins_srv.c
index 3372f74dcb..4a54762fde 100644
--- a/source3/lib/wins_srv.c
+++ b/source3/lib/wins_srv.c
@@ -70,14 +70,24 @@
static char *wins_srv_keystr(struct in_addr wins_ip, struct in_addr src_ip)
{
- char *keystr;
+ char *keystr = NULL, *wins_ip_addr = NULL, *src_ip_addr = NULL;
- if (asprintf(&keystr, WINS_SRV_FMT, inet_ntoa(wins_ip),
- inet_ntoa(src_ip)) == -1) {
- DEBUG(0, ("wins_srv_is_dead: malloc error\n"));
- return NULL;
+ wins_ip_addr = strdup(inet_ntoa(wins_ip));
+ src_ip_addr = strdup(inet_ntoa(src_ip));
+
+ if ( !wins_ip_addr || !src_ip_addr ) {
+ DEBUG(0,("wins_srv_keystr: malloc error\n"));
+ goto done;
}
+ if (asprintf(&keystr, WINS_SRV_FMT, wins_ip_addr, src_ip_addr) == -1) {
+ DEBUG(0, (": ns_srv_keystr: malloc error for key string\n"));
+ }
+
+done:
+ SAFE_FREE(wins_ip_addr);
+ SAFE_FREE(src_ip_addr);
+
return keystr;
}