From 050126e6844519c0587776932063e54b5f2c527c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 14 Jul 2002 22:21:40 +0000 Subject: addedd new (t)alloc_sub_* functions they will get a const string and return a (t)alloced epanded one. also modified passdb/* stuff to use this one. (This used to be commit d378ac1e2efb0efc9a0f983d69cf678ca6255fd5) --- source3/lib/substitute.c | 330 +++++++++++++++++++++++++++++++++++++++++++---- source3/lib/util_str.c | 6 +- 2 files changed, 305 insertions(+), 31 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index dbd382a942..1e8d8c2555 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -83,6 +83,66 @@ static size_t expand_env_var(char *p, int len) return 0; /* Allow the environment contents to be parsed. */ } +/******************************************************************* + Given a pointer to a %$(NAME) in p and the whole string in str + expand it as an environment variable. + Return a new allocated and expanded string. + Based on code by Branko Cibej + When this is called p points at the '%' character. + May substitute multiple occurrencies of the same env var. +********************************************************************/ + + +static char * realloc_expand_env_var(char *str, char *p) +{ + char *envname; + char *envval; + char *q, *r; + int copylen; + + if (p[0] != '%' || p[1] != '$' || p[2] != '(') + return str; + + /* + * Look for the terminating ')'. + */ + + if ((q = strchr_m(p,')')) == NULL) { + DEBUG(0,("expand_env_var: Unterminated environment variable [%s]\n", p)); + return str; + } + + /* + * Extract the name from within the %$(NAME) string. + */ + + r = p + 3; + copylen = q - r; + envname = (char *)malloc(copylen + 1 + 4); // reserve space for use later add %$() chars + if (envname == NULL) return NULL; + strncpy(envname,r,copylen); + envname[copylen] = '\0'; + + if ((envval = getenv(envname)) == NULL) { + DEBUG(0,("expand_env_var: Environment variable [%s] not set\n", envname)); + SAFE_FREE(envname); + return str; + } + + /* + * Copy the full %$(NAME) into envname so it + * can be replaced. + */ + + copylen = q + 1 - p; + strncpy(envname,p,copylen); + envname[copylen] = '\0'; + r = realloc_string_sub(str, envname, envval); + SAFE_FREE(envname); + if (r == NULL) return NULL; + return r; +} + /******************************************************************* Patch from jkf@soton.ac.uk Added this to implement %p (NIS auto-map version of %H) @@ -244,10 +304,6 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len) } } -/**************************************************************************** - Do some standard substitutions in a string. -****************************************************************************/ - static void standard_sub_advanced(int snum, const char *user, const char *connectpath, gid_t gid, const char *smb_name, char *str, size_t len) @@ -305,55 +361,273 @@ static void standard_sub_advanced(int snum, const char *user, standard_sub_basic(smb_name, str, len); } -const char *standard_sub_specified(TALLOC_CTX *mem_ctx, const char *input_string, - const char *username, - const char *domain, - uid_t uid, - gid_t gid) +/**************************************************************************** + Do some standard substitutions in a string. + This function will return an allocated string that have to be freed. +****************************************************************************/ + +char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, const char *str) { - pstring input_pstring; - char *p, *s; + char *a, *t; + a = alloc_sub_basic(smb_name, str); + if (!a) return NULL; + t = talloc_strdup(mem_ctx, a); + SAFE_FREE(a); + return t; +} - pstrcpy(input_pstring, input_string); +char *alloc_sub_basic(const char *smb_name, const char *str) +{ + char *b, *p, *s, *t, *r, *a_string; + fstring pidstr; + struct passwd *pass; + + a_string = strdup(str); + if (a_string == NULL) { + DEBUG(0, ("alloc_sub_specified: Out of memory!\n")); + return NULL; + } - for (s=input_pstring; (p=strchr_m(s, '%')); s=p) { + for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) { + + r = NULL; + b = t = a_string; + + switch (*(p+1)) { + case 'U' : + r = strdup_lower(smb_name); + if (r == NULL) goto error; + t = realloc_string_sub(t, "%U", r); + break; + case 'G' : + r = strdup(smb_name); + if (r == NULL) goto error; + if ((pass = Get_Pwnam(r))!=NULL) { + t = realloc_string_sub(t, "%G", gidtoname(pass->pw_gid)); + } + break; + case 'D' : + r = strdup_upper(current_user_info.domain); + if (r == NULL) goto error; + t = realloc_string_sub(t, "%D", r); + break; + case 'I' : + t = realloc_string_sub(t, "%I", client_addr()); + break; + case 'L' : + if (*local_machine) + t = realloc_string_sub(t, "%L", local_machine); + else + t = realloc_string_sub(t, "%L", global_myname); + break; + case 'M' : + t = realloc_string_sub(t, "%M", client_name()); + break; + case 'R' : + t = realloc_string_sub(t, "%R", remote_proto); + break; + case 'T' : + t = realloc_string_sub(t, "%T", timestring(False)); + break; + case 'a' : + t = realloc_string_sub(t, "%a", remote_arch); + break; + case 'd' : + slprintf(pidstr,sizeof(pidstr)-1, "%d",(int)sys_getpid()); + t = realloc_string_sub(t, "%d", pidstr); + break; + case 'h' : + t = realloc_string_sub(t, "%h", myhostname()); + break; + case 'm' : + t = realloc_string_sub(t, "%m", remote_machine); + break; + case 'v' : + t = realloc_string_sub(t, "%v", VERSION); + break; + case '$' : + t = realloc_expand_env_var(t, p); /* Expand environment variables */ + break; + + default: + break; + } + + p++; + SAFE_FREE(r); + if (t == NULL) goto error; + a_string = t; + } + + return a_string; +error: + SAFE_FREE(a_string); + return NULL; +} + +/**************************************************************************** + Do some specific substitutions in a string. + This function will return an allocated string that have to be freed. +****************************************************************************/ - int l = sizeof(pstring) - (int)(p-input_pstring); +char *talloc_sub_specified(TALLOC_CTX *mem_ctx, + const char *input_string, + const char *username, + const char *domain, + uid_t uid, + gid_t gid) +{ + char *a, *t; + a = alloc_sub_specified(input_string, username, domain, uid, gid); + if (!a) return NULL; + t = talloc_strdup(mem_ctx, a); + SAFE_FREE(a); + return t; +} + +char *alloc_sub_specified(const char *input_string, + const char *username, + const char *domain, + uid_t uid, + gid_t gid) +{ + char *a_string, *ret_string; + char *b, *p, *s, *t; + + a_string = strdup(input_string); + if (a_string == NULL) { + DEBUG(0, ("alloc_sub_specified: Out of memory!\n")); + return NULL; + } + + for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) { + + b = t = a_string; switch (*(p+1)) { case 'U' : - string_sub(p,"%U",username,l); + t = realloc_string_sub(t, "%U", username); break; case 'u' : - string_sub(p,"%u",username,l); + t = realloc_string_sub(t, "%u", username); break; case 'G' : + if (gid != -1) { + t = realloc_string_sub(t, "%G", gidtoname(gid)); + } else { + t = realloc_string_sub(t, "%G", "NO_GROUP"); + } + break; case 'g' : if (gid != -1) { - string_sub(p,"%G",gidtoname(gid),l); - string_sub(p,"%g",gidtoname(gid),l); + t = realloc_string_sub(t, "%g", gidtoname(gid)); } else { - string_sub(p,"%G","NO_GROUP",l); - string_sub(p,"%g","NO_GROUP",l); + t = realloc_string_sub(t, "%g", "NO_GROUP"); } break; case 'D' : - string_sub(p,"%D", domain,l); + t = realloc_string_sub(t, "%D", domain); break; case 'N' : - string_sub(p,"%N", automount_server(username),l); + t = realloc_string_sub(t, "%N", automount_server(username)); + break; + default: + break; + } + + p++; + if (t == NULL) { + SAFE_FREE(a_string); + return NULL; + } + a_string = t; + } + + ret_string = alloc_sub_basic(username, a_string); + SAFE_FREE(a_string); + return ret_string; +} + +char *talloc_sub_advanced(TALLOC_CTX *mem_ctx, + int snum, + const char *user, + const char *connectpath, + gid_t gid, + const char *smb_name, + char *str) +{ + char *a, *t; + a = alloc_sub_advanced(snum, user, connectpath, gid, smb_name, str); + if (!a) return NULL; + t = talloc_strdup(mem_ctx, a); + SAFE_FREE(a); + return t; +} + +char *alloc_sub_advanced(int snum, const char *user, + const char *connectpath, gid_t gid, + const char *smb_name, char *str) +{ + char *a_string, *ret_string; + char *b, *p, *s, *t, *h; + + a_string = strdup(str); + if (a_string == NULL) { + DEBUG(0, ("alloc_sub_specified: Out of memory!\n")); + return NULL; + } + + for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) { + + b = t = a_string; + + switch (*(p+1)) { + case 'N' : + t = realloc_string_sub(t, "%N", automount_server(user)); + break; + case 'H': + if ((h = get_user_home_dir(user))) + t = realloc_string_sub(t, "%H", h); + break; + case 'P': + t = realloc_string_sub(t, "%P", connectpath); + break; + case 'S': + t = realloc_string_sub(t, "%S", lp_servicename(snum)); + break; + case 'g': + t = realloc_string_sub(t, "%g", gidtoname(gid)); + break; + case 'u': + t = realloc_string_sub(t, "%u", user); break; - case '\0': - p++; - break; /* don't run off the end of the string */ - default: p+=2; + /* Patch from jkf@soton.ac.uk Left the %N (NIS + * server name) in standard_sub_basic as it is + * a feature for logon servers, hence uses the + * username. The %p (NIS server path) code is + * here as it is used instead of the default + * "path =" string in [homes] and so needs the + * service name, not the username. */ + case 'p': + t = realloc_string_sub(t, "%p", automount_path(lp_servicename(snum))); break; + + default: + break; + } + + p++; + if (t == NULL) { + SAFE_FREE(a_string); + return NULL; } + a_string = t; } - standard_sub_basic(username, input_pstring, sizeof(pstring)); - return talloc_strdup(mem_ctx, input_pstring); + ret_string = alloc_sub_basic(smb_name, a_string); + SAFE_FREE(a_string); + return ret_string; } /**************************************************************************** diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 4c8d5d8bf7..88a72f1536 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -762,7 +762,7 @@ char *realloc_string_sub(char *string, const char *pattern, const char *insert) return NULL; } string = t; - s = t + (p - s); + p = t + (p - s); } if (li != lp) { memmove(p+li,p+lp,strlen(p+lp)+1); @@ -992,7 +992,7 @@ void strlower_m(char *s) /******************************************************************* duplicate convert a string to lower case ********************************************************************/ -char *strdup_lower(char *s) +char *strdup_lower(const char *s) { char *t = strdup(s); if (t == NULL) { @@ -1026,7 +1026,7 @@ void strupper_m(char *s) /******************************************************************* convert a string to upper case ********************************************************************/ -char *strdup_upper(char *s) +char *strdup_upper(const char *s) { char *t = strdup(s); if (t == NULL) { -- cgit From 369040ac5d7220a301b09c16b0a6f4a3ce14c8b6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 03:59:14 +0000 Subject: fixed a problem with getgroups() where it could include our current effective gid which could mean that the user gets group 0 in their group list for acl interpretation this is a replacement fix for the one richard did in 2.2 (which didn't cope wiith variable behaviour depending on which nss module was in use) (This used to be commit cfc5ca3416cea5ea5d2ac34f5521cb6367e42cd2) --- source3/lib/util_sec.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/util_sec.c b/source3/lib/util_sec.c index d59b1b0471..132748ce13 100644 --- a/source3/lib/util_sec.c +++ b/source3/lib/util_sec.c @@ -227,6 +227,7 @@ void set_effective_gid(gid_t gid) } static uid_t saved_euid, saved_ruid; +static gid_t saved_egid, saved_rgid; /**************************************************************************** save the real and effective uid for later restoration. Used by the quotas @@ -264,6 +265,41 @@ void restore_re_uid(void) assert_uid(saved_ruid, saved_euid); } + +/**************************************************************************** + save the real and effective gid for later restoration. Used by the + getgroups code +****************************************************************************/ +void save_re_gid(void) +{ + saved_rgid = getgid(); + saved_egid = getegid(); +} + +/**************************************************************************** + and restore them! +****************************************************************************/ +void restore_re_gid(void) +{ +#if USE_SETRESUID + setresgid(saved_rgid, saved_egid, -1); +#elif USE_SETREUID + setregid(saved_rgid, -1); + setregid(-1,saved_egid); +#elif USE_SETUIDX + setgidx(ID_REAL, saved_rgid); + setgidx(ID_EFFECTIVE, saved_egid); +#else + set_effective_gid(saved_egid); + if (getgid() != saved_rgid) + setgid(saved_rgid); + set_effective_gid(saved_egid); +#endif + + assert_gid(saved_rgid, saved_egid); +} + + /**************************************************************************** set the real AND effective uid to the current effective uid in a way that allows root to be regained. -- cgit From c238b5c6a19945c34cfdb524a828957772c74cda Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 09:43:34 +0000 Subject: don't use C++ comments in C - it doesn't work on many compilers (This used to be commit cf853314f9eda479c6f18bfc725fa0b5d88d0a38) --- source3/lib/substitute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index 1e8d8c2555..6d96a1820f 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -118,7 +118,7 @@ static char * realloc_expand_env_var(char *str, char *p) r = p + 3; copylen = q - r; - envname = (char *)malloc(copylen + 1 + 4); // reserve space for use later add %$() chars + envname = (char *)malloc(copylen + 1 + 4); /* reserve space for use later add %$() chars */ if (envname == NULL) return NULL; strncpy(envname,r,copylen); envname[copylen] = '\0'; -- cgit From 2afc1ca42c6a945fa1385328cd1c69065829d233 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 18 Jul 2002 22:55:48 +0000 Subject: The previous code would not allow things like string_sub(str, "\\", "/", 0). It complained about an overflow of 0 bytes. Jeremy please check since you modified this last. (This used to be commit a5aad760061e21635319a9b5628990cf59b827ed) --- source3/lib/util_str.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 88a72f1536..7da4358e66 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -670,7 +670,7 @@ void string_sub(char *s,const char *pattern, const char *insert, size_t len) len = ls; while (lp <= ls && (p = strstr(s,pattern))) { - if (ls + (li-lp) >= len) { + if (ls + (li-lp) > len) { DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", (int)(ls + (li-lp) - len), pattern, (int)len)); -- cgit From 06ae9ac5d98a752d8ca17686a4a3b1786fbe520d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 18 Jul 2002 23:00:24 +0000 Subject: virtual registry framework with initial printing hooks. (This used to be commit a43d9788fa8823d678ee72470421b980165ec2b0) --- source3/lib/adt_tree.c | 414 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 414 insertions(+) create mode 100644 source3/lib/adt_tree.c (limited to 'source3/lib') diff --git a/source3/lib/adt_tree.c b/source3/lib/adt_tree.c new file mode 100644 index 0000000000..e3519c6c41 --- /dev/null +++ b/source3/lib/adt_tree.c @@ -0,0 +1,414 @@ +/* + * Unix SMB/CIFS implementation. + * Generic Abstract Data Types + * Copyright (C) Gerald Carter 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 + * 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" + + +/************************************************************************** + Initialize the tree's root. The cmp_fn is a callback function used + for comparision of two children + *************************************************************************/ + +SORTED_TREE* sorted_tree_init( int (cmp_fn)(void*, void*), + void (free_fn)(void*) ) +{ + SORTED_TREE *tree = NULL; + + if ( !(tree = (SORTED_TREE*)malloc( sizeof(SORTED_TREE) )) ) + return NULL; + + ZERO_STRUCTP( tree ); + + tree->compare = cmp_fn; + tree->free = free_fn; + + if ( !(tree->root = (TREE_NODE*)malloc( sizeof(TREE_NODE) )) ) { + SAFE_FREE( tree ); + return NULL; + } + + ZERO_STRUCTP( tree->root ); + + return tree; +} + + +/************************************************************************** + Delete a tree and free all allocated memory + *************************************************************************/ + +static void sorted_tree_destroy_children( TREE_NODE *root ) +{ + int i; + + if ( !root ) + return; + + for ( i=0; inum_children; i++ ) + { + sorted_tree_destroy_children( root->children[i] ); + } + + SAFE_FREE( root->children ); + SAFE_FREE( root->key ); + + return; +} + +/************************************************************************** + Delete a tree and free all allocated memory + *************************************************************************/ + +void sorted_tree_destroy( SORTED_TREE *tree ) +{ + if ( tree->root ) + sorted_tree_destroy_children( tree->root ); + + if ( tree->free ) + tree->free( tree->root ); + + SAFE_FREE( tree ); +} + +/************************************************************************** + Find the next child given a key string + *************************************************************************/ + +static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key ) +{ + TREE_NODE *infant = NULL; + TREE_NODE *child, *crib; + TREE_NODE **siblings; + int i, result; + + if ( !(infant = (TREE_NODE*)malloc( sizeof(TREE_NODE) )) ) + return NULL; + + ZERO_STRUCTP( infant ); + + infant->key = strdup( key ); + infant->parent = node; + + siblings = Realloc( node->children, sizeof(TREE_NODE*)*(node->num_children+1) ); + + if ( siblings ) + node->children = siblings; + + node->num_children++; + + /* first child */ + + if ( node->num_children == 1 ) { + DEBUG(11,("sorted_tree_birth_child: First child of node [%s]! [%s]\n", + node->key ? node->key : "NULL", infant->key )); + node->children[0] = infant; + } + else + { + /* + * multiple siblings .... (at least 2 children) + * + * work from the end of the list forward + * The last child is not set at this point + * Insert the new infanct in ascending order + * from left to right + */ + + for ( i = node->num_children-1; i>=1; i-- ) + { + crib = node->children[i]; + child = node->children[i-1]; + + DEBUG(10,("sorted_tree_birth_child: Looking for crib; infant -> [%s], child -> [%s]\n", + infant->key, child->key)); + + /* the strings should never match assuming that we + have called sorted_tree_find_child() first */ + + result = StrCaseCmp( infant->key, child->key ); + if ( result > 0 ) { + crib = infant; + break; + } + + crib = child; + } + } + + return infant; +} +/************************************************************************** + Find the next child given a key string + *************************************************************************/ + +static TREE_NODE* sorted_tree_find_child( TREE_NODE *node, char* key ) +{ + TREE_NODE *next = NULL; + int i, result; + + if ( !node ) { + DEBUG(0,("sorted_tree_find_child: NULL node passed into function!\n")); + return NULL; + } + + if ( !key ) { + DEBUG(0,("sorted_tree_find_child: NULL key string passed into function!\n")); + return NULL; + } + + for ( i=0; i<(node->num_children); i++ ) + { + result = StrCaseCmp( key, node->children[i]->key ); + + if ( result == 0 ) + next = node->children[i]; + + /* if result > 0 then we've gone to far because + the list of children is sorted by key name + If result == 0, then we have a match */ + + if ( !(result < 0) ) + break; + } + + DEBUG(11,("sorted_tree_find_child: Did %s find [%s]\n", + next ? "" : "not", key )); + + return next; +} + +/************************************************************************** + Add a new node into the tree given a key path and a blob of data + *************************************************************************/ + +BOOL sorted_tree_add( SORTED_TREE *tree, const char *path, void *data_p ) +{ + char *str, *base, *path2; + TREE_NODE *current, *next; + BOOL ret = True; + + DEBUG(8,("sorted_tree_add: Enter\n")); + + if ( !path || *path != '/' ) { + DEBUG(0,("sorted_tree_add: Attempt to add a node with a bad path [%s]\n", + path ? path : "NULL" )); + return False; + } + + if ( !tree ) { + DEBUG(0,("sorted_tree_add: Attempt to add a node to an uninitialized tree!\n")); + return False; + } + + /* move past the first '/' */ + + path++; + path2 = strdup( path ); + if ( !path2 ) { + DEBUG(0,("sorted_tree_add: strdup() failed on string [%s]!?!?!\n", path)); + return False; + } + + + /* + * this works sort of like a 'mkdir -p' call, possibly + * creating an entire path to the new node at once + * The path should be of the form ///... + */ + + base = path2; + str = path2; + current = tree->root; + + do { + /* break off the remaining part of the path */ + + str = strchr( str, '/' ); + if ( str ) + *str = '\0'; + + /* iterate to the next child--birth it if necessary */ + + next = sorted_tree_find_child( current, base ); + if ( !next ) { + next = sorted_tree_birth_child( current, base ); + if ( !next ) { + DEBUG(0,("sorted_tree_add: Failed to create new child!\n")); + ret = False; + goto done; + } + } + current = next; + + /* setup the next part of the path */ + + base = str; + if ( base ) { + *base = '/'; + base++; + str = base; + } + + } while ( base != NULL ); + + current->data_p = data_p; + + DEBUG(10,("sorted_tree_add: Successfully added node [%s] to tree\n", + path )); + + DEBUG(8,("sorted_tree_add: Exit\n")); + +done: + SAFE_FREE( path2 ); + return ret; +} + + +/************************************************************************** + Recursive routine to print out all children of a TREE_NODE + *************************************************************************/ + +static void sorted_tree_print_children( TREE_NODE *node, int debug, char *path ) +{ + int i; + int num_children; + pstring path2; + + if ( !node ) + return; + + + if ( node->key ) + DEBUG(debug,("%s: [%s] (%s)\n", path ? path : "NULL", node->key, + node->data_p ? "data" : "NULL" )); + + *path2 = '\0'; + if ( path ) + pstrcpy( path2, path ); + pstrcat( path2, node->key ? node->key : "NULL" ); + pstrcat( path2, "/" ); + + num_children = node->num_children; + for ( i=0; ichildren[i], debug, path2 ); + + +} + +/************************************************************************** + Dump the kys for a tree to the log file + *************************************************************************/ + +void sorted_tree_print_keys( SORTED_TREE *tree, int debug ) +{ + int i; + int num_children = tree->root->num_children; + + if ( tree->root->key ) + DEBUG(debug,("ROOT/: [%s] (%s)\n", tree->root->key, + tree->root->data_p ? "data" : "NULL" )); + + for ( i=0; iroot->children[i], debug, + tree->root->key ? tree->root->key : "ROOT/" ); + } + +} + +/************************************************************************** + return the data_p for for the node in tree matching the key string + The key string is the full path. We must break it apart and walk + the tree + *************************************************************************/ + +void* sorted_tree_find( SORTED_TREE *tree, char *key ) +{ + char *keystr, *base, *str; + TREE_NODE *current; + void *result = NULL; + + DEBUG(10,("sorted_tree_find: Enter [%s]\n", key ? key : "NULL" )); + + /* sanity checks first */ + + if ( !key ) { + DEBUG(0,("sorted_tree_find: Attempt to search tree using NULL search string!\n")); + return NULL; + } + + if ( !tree ) { + DEBUG(0,("sorted_tree_find: Attempt to search an uninitialized tree using string [%s]!\n", + key ? key : "NULL" )); + return NULL; + } + + if ( !tree->root ) + return NULL; + + /* make a copy to play with */ + + keystr = strdup( key ); + if ( !keystr ) { + DEBUG(0,("sorted_tree_find: strdup() failed on string [%s]!?!?!\n", key)); + return NULL; + } + + /* start breaking the path apart */ + + base = keystr; + str = keystr; + current = tree->root; + + do + { + /* break off the remaining part of the path */ + + str = strchr( str, '/' ); + if ( str ) + *str = '\0'; + + DEBUG(10,("sorted_tree_find: [loop] key => [%s]\n", base)); + + /* iterate to the next child */ + + current = sorted_tree_find_child( current, base ); + + /* setup the next part of the path */ + + base = str; + if ( base ) { + *base = '/'; + base++; + str = base; + } + + } while ( base && current ); + + if ( current ) + result = current->data_p; + + SAFE_FREE( keystr ); + + DEBUG(10,("sorted_tree_find: Exit\n")); + + return result; +} + + -- cgit From 687624fc187db6c07b946046e46cbbfac90aeafe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Jul 2002 23:01:44 +0000 Subject: Another bug found by valgrind. Don't AND a src length of -1. Jeremy. (This used to be commit a67079882dd1b924d2e007e39b06da438533ef96) --- source3/lib/charcnv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index d42dc994b0..ea5bb87bc3 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -562,7 +562,8 @@ int pull_ucs2(const void *base_ptr, char *dest, const void *src, int dest_len, i } /* ucs2 is always a multiple of 2 bytes */ - src_len &= ~1; + if (src_len != -1) + src_len &= ~1; ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len); if (dest_len) dest[MIN(ret, dest_len-1)] = 0; -- cgit From 8e004fe00d2ff0faea35025de895dc72531981d9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Jul 2002 23:21:45 +0000 Subject: Formatting fixups. Jeremy. (This used to be commit 4aa922a1afdd538f51d5eff4cb7af2694a88c591) --- source3/lib/util_str.c | 139 ++++++++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 66 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 7da4358e66..be96718205 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -879,68 +879,59 @@ smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern, } /**************************************************************************** - splits out the front and back at a separator. + Splits out the front and back at a separator. ****************************************************************************/ + void split_at_last_component(char *path, char *front, char sep, char *back) { char *p = strrchr_m(path, sep); if (p != NULL) - { *p = 0; - } + if (front != NULL) - { pstrcpy(front, path); - } - if (p != NULL) - { + + if (p != NULL) { if (back != NULL) - { pstrcpy(back, p+1); - } *p = '\\'; - } - else - { + } else { if (back != NULL) - { back[0] = 0; - } } } - /**************************************************************************** -write an octal as a string + Write an octal as a string. ****************************************************************************/ + char *octal_string(int i) { static char ret[64]; - if (i == -1) { + if (i == -1) return "-1"; - } slprintf(ret, sizeof(ret)-1, "0%o", i); return ret; } /**************************************************************************** -truncate a string at a specified length + Truncate a string at a specified length. ****************************************************************************/ + char *string_truncate(char *s, int length) { - if (s && strlen(s) > length) { + if (s && strlen(s) > length) s[length] = 0; - } return s; } - /**************************************************************************** -strchr and strrchr_m are very hard to do on general multi-byte strings. -we convert via ucs2 for now + Strchr and strrchr_m are very hard to do on general multi-byte strings. + We convert via ucs2 for now. ****************************************************************************/ + char *strchr_m(const char *s, char c) { wpstring ws; @@ -949,7 +940,8 @@ char *strchr_m(const char *s, char c) push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); p = strchr_w(ws, UCS2_CHAR(c)); - if (!p) return NULL; + if (!p) + return NULL; *p = 0; pull_ucs2_pstring(s2, ws); return (char *)(s+strlen(s2)); @@ -963,26 +955,29 @@ char *strrchr_m(const char *s, char c) push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); p = strrchr_w(ws, UCS2_CHAR(c)); - if (!p) return NULL; + if (!p) + return NULL; *p = 0; pull_ucs2_pstring(s2, ws); return (char *)(s+strlen(s2)); } /******************************************************************* - convert a string to lower case + Convert a string to lower case. ********************************************************************/ + void strlower_m(char *s) { /* this is quite a common operation, so we want it to be fast. We optimise for the ascii case, knowing that all our supported multi-byte character sets are ascii-compatible (ie. they match for the first 128 chars) */ - while (*s && !(((unsigned char)s[0]) & 0x7F)) { + + while (*s && !(((unsigned char)s[0]) & 0x7F)) *s++ = tolower((unsigned char)*s); - } - if (!*s) return; + if (!*s) + return; /* I assume that lowercased string takes the same number of bytes * as source string even in UTF-8 encoding. (VIV) */ @@ -990,8 +985,9 @@ void strlower_m(char *s) } /******************************************************************* - duplicate convert a string to lower case + Duplicate convert a string to lower case. ********************************************************************/ + char *strdup_lower(const char *s) { char *t = strdup(s); @@ -1004,19 +1000,21 @@ char *strdup_lower(const char *s) } /******************************************************************* - convert a string to upper case + Convert a string to upper case. ********************************************************************/ + void strupper_m(char *s) { /* this is quite a common operation, so we want it to be fast. We optimise for the ascii case, knowing that all our supported multi-byte character sets are ascii-compatible (ie. they match for the first 128 chars) */ - while (*s && !(((unsigned char)s[0]) & 0x7F)) { + + while (*s && !(((unsigned char)s[0]) & 0x7F)) *s++ = toupper((unsigned char)*s); - } - if (!*s) return; + if (!*s) + return; /* I assume that lowercased string takes the same number of bytes * as source string even in multibyte encoding. (VIV) */ @@ -1024,8 +1022,9 @@ void strupper_m(char *s) } /******************************************************************* - convert a string to upper case + Convert a string to upper case. ********************************************************************/ + char *strdup_upper(const char *s) { char *t = strdup(s); @@ -1048,7 +1047,8 @@ char *binary_string(char *buf, int len) int i, j; const char *hex = "0123456789ABCDEF"; s = malloc(len * 3 + 1); - if (!s) return NULL; + if (!s) + return NULL; for (j=i=0;i> 4]; @@ -1059,8 +1059,8 @@ char *binary_string(char *buf, int len) return s; } - /* Just a typesafety wrapper for snprintf into a pstring */ + int pstr_sprintf(pstring s, const char *fmt, ...) { va_list ap; @@ -1072,8 +1072,8 @@ int pstr_sprintf(pstring s, const char *fmt, ...) return ret; } - /* Just a typesafety wrapper for snprintf into a fstring */ + int fstr_sprintf(fstring s, const char *fmt, ...) { va_list ap; @@ -1085,18 +1085,19 @@ int fstr_sprintf(fstring s, const char *fmt, ...) return ret; } - #ifndef HAVE_STRNDUP /******************************************************************* -some platforms don't have strndup + Some platforms don't have strndup. ********************************************************************/ + char *strndup(const char *s, size_t n) { char *ret; n = strnlen(s, n); ret = malloc(n+1); - if (!ret) return NULL; + if (!ret) + return NULL; memcpy(ret, s, n); ret[n] = 0; @@ -1111,13 +1112,12 @@ some platforms don't have strnlen size_t strnlen(const char *s, size_t n) { int i; - for (i=0; s[i] && i Date: Thu, 18 Jul 2002 23:22:11 +0000 Subject: Fixed off-by-one in all_string_sub also. Jeremy. (This used to be commit 8b0e47fc1f00c76dfccb6c2b58188d9a5ae67c65) --- source3/lib/util_str.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index be96718205..c1d20ffd2c 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -801,7 +801,7 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len) len = ls; while (lp <= ls && (p = strstr(s,pattern))) { - if (ls + (li-lp) >= len) { + if (ls + (li-lp) > len) { DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", (int)(ls + (li-lp) - len), pattern, (int)len)); -- cgit From 7f98456fb3002623773b84c9a785ff6b3bc03b2f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Jul 2002 23:28:47 +0000 Subject: Add useful VALGRIND #ifdef. Jeremy. (This used to be commit 07716f3a2316fedfe9a3210fd1dad8f7d1e4d9c8) --- source3/lib/util.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/util.c b/source3/lib/util.c index be108aa405..51c926dd0b 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -505,6 +505,7 @@ close the low 3 fd's and open dev/null in their place ********************************************************************/ void close_low_fds(void) { +#ifndef VALGRIND int fd; int i; close(0); close(1); @@ -525,6 +526,7 @@ void close_low_fds(void) return; } } +#endif } /**************************************************************************** -- cgit From 923a3a0e1ce0a89a2e9be85cc224729610092b3f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Jul 2002 23:43:33 +0000 Subject: Previous fix was incorrect. len in string_sub and all_string_sub is number of *bytes*. >= check was correct, the len=0 case needed changing to len = ls + 1. Jeremy. (This used to be commit 06a4a6d30ade5ea4d123ae640393677c9a510763) --- source3/lib/util_str.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index c1d20ffd2c..67d3b2108e 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -667,10 +667,10 @@ void string_sub(char *s,const char *pattern, const char *insert, size_t len) li = (ssize_t)strlen(insert); if (len == 0) - len = ls; + len = ls + 1; /* len is number of *bytes* */ while (lp <= ls && (p = strstr(s,pattern))) { - if (ls + (li-lp) > len) { + if (ls + (li-lp) >= len) { DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", (int)(ls + (li-lp) - len), pattern, (int)len)); @@ -798,10 +798,10 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len) return; if (len == 0) - len = ls; + len = ls + 1; /* len is number of *bytes* */ while (lp <= ls && (p = strstr(s,pattern))) { - if (ls + (li-lp) > len) { + if (ls + (li-lp) >= len) { DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", (int)(ls + (li-lp) - len), pattern, (int)len)); -- cgit From ce16d9a26df7a3012945ecaa5738cf63110fb5c5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 19 Jul 2002 04:00:21 +0000 Subject: fixed line buffer mode in XFILE thanks to tim for finding this bug (This used to be commit 91bff7545405ba88bc721f358ccdbf0aac0e3ba6) --- source3/lib/xfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/xfile.c b/source3/lib/xfile.c index 903dfb1ae0..b5710f3a39 100644 --- a/source3/lib/xfile.c +++ b/source3/lib/xfile.c @@ -171,7 +171,7 @@ int x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f) flush a bit more than necessary, but that is harmless */ if (f->buftype == X_IOLBF && f->bufused) { int i; - for (i=size-1; i>=0; i--) { + for (i=(size*nmemb)-1; i>=0; i--) { if (*(i+(const char *)p) == '\n') { x_fflush(f); break; -- cgit From 9fe3bd1259e7bda901f7a264bd7fc88c72d2112f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 19 Jul 2002 18:49:44 +0000 Subject: * refactored registry operations some. subkey lists and registry values are now passed around in containers (REGSUBKEY_CTR & REGVAL_CTR) which each possess a TALLOC_CTX. * removed subkey_specific_fn() from REGISTRY_OPS. Is implemented in the form of a wrapper * temporarily broke the printing registry ops. * implemented inheritence for the data_p of nodes in a SORTED_TREE * All REGISTRY_KEY instances now store a valid REGISTRY_HOOK since the default REGOSTRY_OPS structure is stored in the root of the cache_tree. * Probably some other change I forgot.... T (This used to be commit e7b55e8f017e638342d9c8c1a9259000745a0298) --- source3/lib/adt_tree.c | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/adt_tree.c b/source3/lib/adt_tree.c index e3519c6c41..3a6e722c97 100644 --- a/source3/lib/adt_tree.c +++ b/source3/lib/adt_tree.c @@ -26,7 +26,8 @@ for comparision of two children *************************************************************************/ -SORTED_TREE* sorted_tree_init( int (cmp_fn)(void*, void*), +SORTED_TREE* sorted_tree_init( void *data_p, + int (cmp_fn)(void*, void*), void (free_fn)(void*) ) { SORTED_TREE *tree = NULL; @@ -45,6 +46,7 @@ SORTED_TREE* sorted_tree_init( int (cmp_fn)(void*, void*), } ZERO_STRUCTP( tree->root ); + tree->root->data_p = data_p; return tree; } @@ -94,7 +96,6 @@ void sorted_tree_destroy( SORTED_TREE *tree ) static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key ) { TREE_NODE *infant = NULL; - TREE_NODE *child, *crib; TREE_NODE **siblings; int i, result; @@ -116,7 +117,7 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key ) /* first child */ if ( node->num_children == 1 ) { - DEBUG(11,("sorted_tree_birth_child: First child of node [%s]! [%s]\n", + DEBUG(10,("sorted_tree_birth_child: First child of node [%s]! [%s]\n", node->key ? node->key : "NULL", infant->key )); node->children[0] = infant; } @@ -133,23 +134,28 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key ) for ( i = node->num_children-1; i>=1; i-- ) { - crib = node->children[i]; - child = node->children[i-1]; - DEBUG(10,("sorted_tree_birth_child: Looking for crib; infant -> [%s], child -> [%s]\n", - infant->key, child->key)); + infant->key, node->children[i-1]->key)); /* the strings should never match assuming that we have called sorted_tree_find_child() first */ - result = StrCaseCmp( infant->key, child->key ); + result = StrCaseCmp( infant->key, node->children[i-1]->key ); if ( result > 0 ) { - crib = infant; + node->children[i] = infant; break; } - - crib = child; + + /* bump everything towards the end on slot */ + + node->children[i] = node->children[i-1]; } + + /* if we haven't found the correct clot yet, the child + will be first in the list */ + + if ( i == 0 ) + node->children[0] = infant; } return infant; @@ -376,6 +382,9 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key ) str = keystr; current = tree->root; + if ( tree->root->data_p ) + result = tree->root->data_p; + do { /* break off the remaining part of the path */ @@ -384,7 +393,7 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key ) if ( str ) *str = '\0'; - DEBUG(10,("sorted_tree_find: [loop] key => [%s]\n", base)); + DEBUG(11,("sorted_tree_find: [loop] key => [%s]\n", base)); /* iterate to the next child */ @@ -399,10 +408,18 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key ) str = base; } + /* + * the idea is that the data_p for a parent should + * be inherited by all children, but allow it to be + * overridden farther down + */ + + if ( current && current->data_p ) + result = current->data_p; + } while ( base && current ); - - if ( current ) - result = current->data_p; + + /* result should be the data_p from the lowest match node in the tree */ SAFE_FREE( keystr ); -- cgit From 3c9e5a94165afc30ba719aad513e09ead83276fb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 Jul 2002 19:56:27 +0000 Subject: Never ignore valgrind messages :-). Don't reference before the start of a string.... Jeremy. (This used to be commit 35f0fbd254c222d015bdc582277b90efbaade81e) --- source3/lib/util_str.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 67d3b2108e..1a2c2bef1f 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -299,7 +299,7 @@ BOOL trim_string(char *s,const char *front,const char *back) } if (back_len) { - while (strncmp(s+len-back_len,back,back_len)==0) { + while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) { s[len-back_len]='\0'; len -= back_len; ret=True; -- cgit From 3c0a9c46d8057b9499d7d48a67ba15f9942d558a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 19 Jul 2002 22:16:03 +0000 Subject: fixed seg fault in registry frontend caused by trying to use a destroyed TALLOC_CTX* (This used to be commit 432b9f8d7c20fbf3b2a0906c8a93272abbe43fb6) --- source3/lib/adt_tree.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/adt_tree.c b/source3/lib/adt_tree.c index 3a6e722c97..9c4ad423c1 100644 --- a/source3/lib/adt_tree.c +++ b/source3/lib/adt_tree.c @@ -420,6 +420,8 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key ) } while ( base && current ); /* result should be the data_p from the lowest match node in the tree */ + if ( result ) + DEBUG(10,("sorted_tree_find: Found data_p!\n")); SAFE_FREE( keystr ); -- cgit From 39bbeff5b361ffa6a5ff9273cf7fce5f46543703 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 20 Jul 2002 02:42:04 +0000 Subject: fixed a logic error in the sorted_tree_find_child() routine that caused a valid search to fail. The printing registry view now works again. (This used to be commit 2050859f03493d5135984ce1e42baf8f1f2566b9) --- source3/lib/adt_tree.c | 95 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 32 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/adt_tree.c b/source3/lib/adt_tree.c index 9c4ad423c1..2c18bb1198 100644 --- a/source3/lib/adt_tree.c +++ b/source3/lib/adt_tree.c @@ -21,6 +21,33 @@ #include "includes.h" +/************************************************************************** + Initialize the tree's root. The cmp_fn is a callback function used + for comparision of two children + *************************************************************************/ + +static BOOL trim_tree_keypath( char *path, char **base, char **new_path ) +{ + char *p; + + *new_path = *base = NULL; + + if ( !path ) + return False; + + *base = path; + + p = strchr( path, '/' ); + + if ( p ) { + *p = '\0'; + *new_path = p+1; + } + + return True; +} + + /************************************************************************** Initialize the tree's root. The cmp_fn is a callback function used for comparision of two children @@ -97,7 +124,7 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key ) { TREE_NODE *infant = NULL; TREE_NODE **siblings; - int i, result; + int i; if ( !(infant = (TREE_NODE*)malloc( sizeof(TREE_NODE) )) ) return NULL; @@ -117,7 +144,7 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key ) /* first child */ if ( node->num_children == 1 ) { - DEBUG(10,("sorted_tree_birth_child: First child of node [%s]! [%s]\n", + DEBUG(11,("sorted_tree_birth_child: First child of node [%s]! [%s]\n", node->key ? node->key : "NULL", infant->key )); node->children[0] = infant; } @@ -134,14 +161,15 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key ) for ( i = node->num_children-1; i>=1; i-- ) { - DEBUG(10,("sorted_tree_birth_child: Looking for crib; infant -> [%s], child -> [%s]\n", + DEBUG(11,("sorted_tree_birth_child: Looking for crib; infant -> [%s], child -> [%s]\n", infant->key, node->children[i-1]->key)); /* the strings should never match assuming that we have called sorted_tree_find_child() first */ - result = StrCaseCmp( infant->key, node->children[i-1]->key ); - if ( result > 0 ) { + if ( StrCaseCmp( infant->key, node->children[i-1]->key ) > 0 ) { + DEBUG(11,("sorted_tree_birth_child: storing infant in i == [%d]\n", + i)); node->children[i] = infant; break; } @@ -150,8 +178,10 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key ) node->children[i] = node->children[i-1]; } + + DEBUG(11,("sorted_tree_birth_child: Exiting loop (i == [%d])\n", i )); - /* if we haven't found the correct clot yet, the child + /* if we haven't found the correct slot yet, the child will be first in the list */ if ( i == 0 ) @@ -160,6 +190,7 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key ) return infant; } + /************************************************************************** Find the next child given a key string *************************************************************************/ @@ -179,9 +210,12 @@ static TREE_NODE* sorted_tree_find_child( TREE_NODE *node, char* key ) return NULL; } - for ( i=0; i<(node->num_children); i++ ) - { - result = StrCaseCmp( key, node->children[i]->key ); + for ( i=0; inum_children; i++ ) + { + DEBUG(11,("sorted_tree_find_child: child key => [%s]\n", + node->children[i]->key)); + + result = StrCaseCmp( node->children[i]->key, key ); if ( result == 0 ) next = node->children[i]; @@ -190,12 +224,12 @@ static TREE_NODE* sorted_tree_find_child( TREE_NODE *node, char* key ) the list of children is sorted by key name If result == 0, then we have a match */ - if ( !(result < 0) ) + if ( result > 0 ) break; } - DEBUG(11,("sorted_tree_find_child: Did %s find [%s]\n", - next ? "" : "not", key )); + DEBUG(11,("sorted_tree_find_child: %s [%s]\n", + next ? "Found" : "Did not find", key )); return next; } @@ -346,7 +380,7 @@ void sorted_tree_print_keys( SORTED_TREE *tree, int debug ) void* sorted_tree_find( SORTED_TREE *tree, char *key ) { - char *keystr, *base, *str; + char *keystr, *base, *str, *p; TREE_NODE *current; void *result = NULL; @@ -370,7 +404,11 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key ) /* make a copy to play with */ - keystr = strdup( key ); + if ( *key == '/' ) + keystr = strdup( key+1 ); + else + keystr = strdup( key ); + if ( !keystr ) { DEBUG(0,("sorted_tree_find: strdup() failed on string [%s]!?!?!\n", key)); return NULL; @@ -378,8 +416,7 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key ) /* start breaking the path apart */ - base = keystr; - str = keystr; + p = keystr; current = tree->root; if ( tree->root->data_p ) @@ -388,25 +425,15 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key ) do { /* break off the remaining part of the path */ - - str = strchr( str, '/' ); - if ( str ) - *str = '\0'; + + trim_tree_keypath( p, &base, &str ); - DEBUG(11,("sorted_tree_find: [loop] key => [%s]\n", base)); + DEBUG(11,("sorted_tree_find: [loop] base => [%s], new_path => [%s]\n", + base, str)); /* iterate to the next child */ current = sorted_tree_find_child( current, base ); - - /* setup the next part of the path */ - - base = str; - if ( base ) { - *base = '/'; - base++; - str = base; - } /* * the idea is that the data_p for a parent should @@ -416,12 +443,16 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key ) if ( current && current->data_p ) result = current->data_p; + + /* reset the path pointer 'p' to the remaining part of the key string */ + + p = str; - } while ( base && current ); + } while ( str && current ); /* result should be the data_p from the lowest match node in the tree */ if ( result ) - DEBUG(10,("sorted_tree_find: Found data_p!\n")); + DEBUG(11,("sorted_tree_find: Found data_p!\n")); SAFE_FREE( keystr ); -- cgit From b96de65b26c55247f4d0f218f0e3a4ceebb4fa26 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Jul 2002 06:50:47 +0000 Subject: Add a wrapper for dup2() to our system.c Andrew Bartlett (This used to be commit b24b6307f6b40e559aec441e0ebab8f666b87d9f) --- source3/lib/system.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/system.c b/source3/lib/system.c index 8b2ba800f5..edda54a78d 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -1219,6 +1219,16 @@ const char *sys_dlerror(void) #endif } +int sys_dup2(int oldfd, int newfd) +{ +#if defined(HAVE_DUP2) + return dup2(oldfd, newfd); +#else + errno = ENOSYS; + return -1; +#endif +} + /************************************************************************** Wrapper for Admin Logs. ****************************************************************************/ -- cgit From 714abda3e749ae364806633b2ccc17c03a453bf4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Jul 2002 07:02:45 +0000 Subject: Add support for duplicating stderr into our logfiles. This is for two things: To allow panic actions etc to pump out backtraces to stderr and to allow vangrind to put its stuff in a logfile - making it possible to debug smbd when launched from inetd. I've also cleaned up some of the duplicate names in procedures between smbd and nmbd. Andrew Bartlett (This used to be commit 4bcb32731984b4aef1d4911a168a4e7a10d32fd4) --- source3/lib/debug.c | 6 ++++++ source3/lib/util.c | 38 +++++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 17 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/debug.c b/source3/lib/debug.c index f41c3b6497..c43a98f4fa 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -602,6 +602,12 @@ BOOL reopen_logs( void ) force_check_log_size(); (void)umask(oldumask); + /* Take over stderr to catch ouput into logs */ + if (sys_dup2(dbf->fd, 2) == -1) { + close_low_fds(True); /* Close stderr too, if dup2 can't point it + at the logfile */ + } + return ret; } diff --git a/source3/lib/util.c b/source3/lib/util.c index 51c926dd0b..bcef3013f9 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -503,30 +503,33 @@ void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,ti /******************************************************************* close the low 3 fd's and open dev/null in their place ********************************************************************/ -void close_low_fds(void) +void close_low_fds(BOOL stderr_too) { -#ifndef VALGRIND int fd; int i; close(0); close(1); -#ifndef __INSURE__ - close(2); -#endif + + if (stderr_too) { + close(2); + } + /* try and use up these file descriptors, so silly library routines writing to stdout etc won't cause havoc */ for (i=0;i<3;i++) { - fd = sys_open("/dev/null",O_RDWR,0); - if (fd < 0) fd = sys_open("/dev/null",O_WRONLY,0); - if (fd < 0) { - DEBUG(0,("Can't open /dev/null\n")); - return; - } - if (fd != i) { - DEBUG(0,("Didn't get file descriptor %d\n",i)); - return; - } + if (i == 2 && !stderr_too) + continue; + + fd = sys_open("/dev/null",O_RDWR,0); + if (fd < 0) fd = sys_open("/dev/null",O_WRONLY,0); + if (fd < 0) { + DEBUG(0,("Can't open /dev/null\n")); + return; + } + if (fd != i) { + DEBUG(0,("Didn't get file descriptor %d\n",i)); + return; + } } -#endif } /**************************************************************************** @@ -680,7 +683,8 @@ void become_daemon(void) #endif /* HAVE_SETSID */ /* Close fd's 0,1,2. Needed if started by rsh */ - close_low_fds(); + close_low_fds(False); /* Don't close stderr, let the debug system + attach it to the logfile */ } -- cgit From aff20d822c267f0b2f348f7dfd3946aaf9c06817 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Jul 2002 11:06:37 +0000 Subject: Add some const to try and get less warnings. Andrew Bartlett (This used to be commit 2a3d821c77c7648de43b11dd951f6f16d7be5b3c) --- source3/lib/util_str.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 1a2c2bef1f..7e974269ec 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -826,7 +826,8 @@ return a new allocate unicode string. smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern, const smb_ucs2_t *insert) { - smb_ucs2_t *r, *rp, *sp; + smb_ucs2_t *r, *rp; + const smb_ucs2_t *sp; size_t lr, lp, li, lt; if (!insert || !pattern || !*pattern || !s) return NULL; @@ -836,7 +837,7 @@ smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern, li = (size_t)strlen_w(insert); if (li > lp) { - smb_ucs2_t *st = s; + const smb_ucs2_t *st = s; int ld = li - lp; while ((sp = strstr_w(st, pattern))) { st = sp + lp; -- cgit From 27211c55e2d8e474cef0abe80847a4387aa688e3 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sat, 20 Jul 2002 21:56:26 +0000 Subject: Don't try and sys_dup2(dbf->fd) if dbf == NULL. (This used to be commit 0fd155a06c24ec5d1310213baf7a4230242498be) --- source3/lib/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/debug.c b/source3/lib/debug.c index c43a98f4fa..be5f66a562 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -603,7 +603,7 @@ BOOL reopen_logs( void ) (void)umask(oldumask); /* Take over stderr to catch ouput into logs */ - if (sys_dup2(dbf->fd, 2) == -1) { + if (dbf && sys_dup2(dbf->fd, 2) == -1) { close_low_fds(True); /* Close stderr too, if dup2 can't point it at the logfile */ } -- cgit From afb7d1dc48fa3eab69212c3ffbd51d636c897ec0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 21 Jul 2002 03:26:10 +0000 Subject: Another smattering of static and const (This used to be commit 897cc4a610932e596f8a9807213166e380ef0203) --- source3/lib/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/util.c b/source3/lib/util.c index bcef3013f9..ae94b710b2 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -100,7 +100,7 @@ char *tmpdir(void) Determine whether we are in the specified group. ****************************************************************************/ -BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups) +BOOL in_group(gid_t group, gid_t current_gid, int ngroups, const gid_t *groups) { int i; -- cgit From fef9d6187ece53ae12670cc56b360e913e08f3bb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 23 Jul 2002 09:22:29 +0000 Subject: implemented getgrouplist() for systems that don't have it and use it in get_alias_user_groups(). The old method used getgrent() which is extremely slow when the number of groups is large (This used to be commit 44e92b6523ca2c119c2562df22eb71138dca9d9d) --- source3/lib/replace.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++ source3/lib/util_getent.c | 56 +++++++++++++++++++++++++--------------- 2 files changed, 101 insertions(+), 21 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/replace.c b/source3/lib/replace.c index 2cc7d48adb..e2664accfa 100644 --- a/source3/lib/replace.c +++ b/source3/lib/replace.c @@ -428,3 +428,69 @@ char *rep_inet_ntoa(struct in_addr ip) } #endif /* HAVE_SYSLOG */ #endif /* HAVE_VSYSLOG */ + + +#ifndef HAVE_GETGROUPLIST +/* + This is a *much* faster way of getting the list of groups for a user + without changing the current supplemenrary group list. The old + method used getgrent() which could take 20 minutes on a really big + network with hundeds of thousands of groups and users. The new method + takes a couple of seconds. + + NOTE!! this function only works if it is called as root! + */ + int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt) +{ + gid_t *gids_saved; + int ret, ngrp_saved; + + /* work out how many groups we need to save */ + ngrp_saved = getgroups(0, NULL); + if (ngrp_saved == -1) { + /* this shouldn't happen */ + return -1; + } + + gids_saved = (gid_t *)malloc(sizeof(gid_t) * (ngrp_saved+1)); + if (!gids_saved) { + errno = ENOMEM; + return -1; + } + + ngrp_saved = getgroups(ngrp_saved, gids_saved); + if (ngrp_saved == -1) { + free(gids_saved); + /* very strange! */ + return -1; + } + + if (initgroups(user, gid) != 0) { + free(gids_saved); + return -1; + } + + /* this must be done to cope with systems that put the current egid in the + return from getgroups() */ + save_re_gid(); + set_effective_gid(gid); + setgid(gid); + + ret = getgroups(*grpcnt, groups); + if (ret >= 0) { + *grpcnt = ret; + } + + restore_re_gid(); + + if (setgroups(ngrp_saved, gids_saved) != 0) { + /* yikes! */ + DEBUG(0,("ERROR: getgrouplist: failed to reset group list!\n")); + free(gids_saved); + return -1; + } + + free(gids_saved); + return ret; +} +#endif diff --git a/source3/lib/util_getent.c b/source3/lib/util_getent.c index 2e76121aae..5d2fcd7652 100644 --- a/source3/lib/util_getent.c +++ b/source3/lib/util_getent.c @@ -21,27 +21,6 @@ #include "includes.h" -#if 0 -static void print_grent_list(struct sys_grent *glist) -{ - DEBUG(100, ("print_grent_list: %x\n", glist )); - while (glist) { - DEBUG(100,("glist: %x ", glist)); - if (glist->gr_name) - DEBUG(100,(": gr_name = (%x) %s ", glist->gr_name, glist->gr_name)); - if (glist->gr_passwd) - DEBUG(100,(": gr_passwd = (%x) %s ", glist->gr_passwd, glist->gr_passwd)); - if (glist->gr_mem) { - int i; - for (i = 0; glist->gr_mem[i]; i++) - DEBUG(100,(" : gr_mem[%d] = (%x) %s ", i, glist->gr_mem[i], glist->gr_mem[i])); - } - DEBUG(100,(": gr_next = %x\n", glist->next )); - glist = glist->next; - } - DEBUG(100,("FINISHED !\n\n")); -} -#endif /**************************************************************** Returns a single linked list of group entries. @@ -320,3 +299,38 @@ void free_userlist(struct sys_userlist *list_head) SAFE_FREE(old_head); } } + + +/* + return a full list of groups for a user + + returns the number of groups the user is a member of. The return will include the + users primary group. + + remember to free the resulting gid_t array + + NOTE! you must be root to call this function on some systems +*/ +int getgroups_user(const char *user, gid_t **groups) +{ + struct passwd *pwd; + int ngrp, max_grp; + + pwd = getpwnam(user); + if (!pwd) return -1; + + max_grp = groups_max(); + (*groups) = (gid_t *)malloc(sizeof(gid_t) * max_grp); + if (! *groups) { + errno = ENOMEM; + return -1; + } + + ngrp = getgrouplist(user, pwd->pw_gid, *groups, &max_grp); + if (ngrp <= 0) { + free(*groups); + return ngrp; + } + + return ngrp; +} -- cgit From 24675d99e51609de542c70a8e6f39befeed46722 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 24 Jul 2002 05:26:32 +0000 Subject: Make it possible to query account policy values from pdbedit (set to come soon). Update account_pol.c to use just uint32, rather then uint32 for paramaters, int32 for storage. (The int32 functions didn't have seperate return/status values, uint32 functions use a pointer-paramater). Move the #define -> string from a swtich to a table, so we can look it up both ways. Andrew Bartlett (This used to be commit c5b5e3d653f5c38a283d901a409be6603d5103f7) --- source3/lib/account_pol.c | 88 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 26 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c index 07676e2202..f603f0f191 100644 --- a/source3/lib/account_pol.c +++ b/source3/lib/account_pol.c @@ -2,6 +2,7 @@ * Unix SMB/CIFS implementation. * account policy storage * Copyright (C) Jean François Micouleau 1998-2001. + * Copyright (C) Andrew Bartlett 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 @@ -31,6 +32,7 @@ BOOL init_account_policy(void) { static pid_t local_pid; char *vstring = "INFO/version"; + uint32 version; if (tdb && local_pid == sys_getpid()) return True; @@ -44,9 +46,9 @@ BOOL init_account_policy(void) /* handle a Samba upgrade */ tdb_lock_bystring(tdb, vstring); - if (tdb_fetch_int32(tdb, vstring) != DATABASE_VERSION) { + if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) { tdb_traverse(tdb, tdb_traverse_delete_fn, NULL); - tdb_store_int32(tdb, vstring, DATABASE_VERSION); + tdb_store_uint32(tdb, vstring, DATABASE_VERSION); account_policy_set(AP_MIN_PASSWORD_LEN, MINPASSWDLENGTH); /* 5 chars minimum */ account_policy_set(AP_PASSWORD_HISTORY, 0); /* don't keep any old password */ @@ -63,33 +65,50 @@ BOOL init_account_policy(void) return True; } +static const struct { + int field; + char *string; +} account_policy_names[] = { + {AP_MIN_PASSWORD_LEN, "min password length"}, + {AP_PASSWORD_HISTORY, "password history"}, + {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password"}, + {AP_MAX_PASSWORD_AGE, "maximum password age"}, + {AP_MIN_PASSWORD_AGE,"minimum password age"}, + {AP_LOCK_ACCOUNT_DURATION, "lockout duration"}, + {AP_RESET_COUNT_TIME, "reset count minutes"}, + {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt"}, + {AP_TIME_TO_LOGOUT, "disconnect time"}, + {0, NULL} +}; + +/**************************************************************************** +Get the account policy name as a string from its #define'ed number +****************************************************************************/ + +static const char *decode_account_policy_name(int field) +{ + int i; + for (i=0; account_policy_names[i].string; i++) { + if (field == account_policy_names[i].field) + return account_policy_names[i].string; + } + return NULL; + +} + /**************************************************************************** +Get the account policy name as a string from its #define'ed number ****************************************************************************/ -static char *decode_account_policy_name(int field) +int account_policy_name_to_feildnum(const char *name) { - switch (field) { - case AP_MIN_PASSWORD_LEN: - return "min password length"; - case AP_PASSWORD_HISTORY: - return "password history"; - case AP_USER_MUST_LOGON_TO_CHG_PASS: - return "user must logon to change password"; - case AP_MAX_PASSWORD_AGE: - return "maximum password age"; - case AP_MIN_PASSWORD_AGE: - return "minimum password age"; - case AP_LOCK_ACCOUNT_DURATION: - return "lockout duration"; - case AP_RESET_COUNT_TIME: - return "reset count minutes"; - case AP_BAD_ATTEMPT_LOCKOUT: - return "bad lockout attempt"; - case AP_TIME_TO_LOGOUT: - return "disconnect time"; - default: - return "undefined value"; + int i; + for (i=0; account_policy_names[i].string; i++) { + if (strcmp(name, account_policy_names[i].string) == 0) + return account_policy_names[i].field; } + return 0; + } @@ -101,8 +120,17 @@ BOOL account_policy_get(int field, uint32 *value) init_account_policy(); + *value = 0; + fstrcpy(name, decode_account_policy_name(field)); - *value=tdb_fetch_int32(tdb, name); + if (!*name) { + DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", field)); + return False; + } + if (!tdb_fetch_uint32(tdb, name, value)) { + DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for feild %d (%s), returning 0", field, name)); + return False; + } DEBUG(10,("account_policy_get: %s:%d\n", name, *value)); return True; } @@ -117,8 +145,16 @@ BOOL account_policy_set(int field, uint32 value) init_account_policy(); fstrcpy(name, decode_account_policy_name(field)); - if ( tdb_store_int32(tdb, name, value)== -1) + if (!*name) { + DEBUG(1, ("Field %d is not a valid account policy type! Cannot set.\n", field)); return False; + } + + if (!tdb_store_uint32(tdb, name, value)) { + DEBUG(1, ("tdb_store_uint32 failed for feild %d (%s) on value %u", field, name, value)); + return False; + } + DEBUG(10,("account_policy_set: %s:%d\n", name, value)); return True; -- cgit From 74d235ff1a08f931a85f7715526344d0e08ccfd4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 28 Jul 2002 02:20:15 +0000 Subject: It seems I didn't need to write a dup2() wrapper - as we already use it a lot. But as thats done, we might as well use it anyway. Andrew Bartlett (This used to be commit d78cce806d967d0442b153242ba2061f1b14b6b6) --- source3/lib/smbrun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c index 67f82ed0ad..592543bc43 100644 --- a/source3/lib/smbrun.c +++ b/source3/lib/smbrun.c @@ -143,7 +143,7 @@ int smbrun(char *cmd, int *outfd) /* point our stdout at the file we want output to go into */ if (outfd) { close(1); - if (dup2(*outfd,1) != 1) { + if (sys_dup2(*outfd,1) != 1) { DEBUG(2,("Failed to create stdout file descriptor\n")); close(*outfd); exit(80); -- cgit From c4fcf56380739cc58a2096aefe587bee50fde27d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 28 Jul 2002 06:08:30 +0000 Subject: good security patch from Timothy.Sell@unisys.com we could generate short passwords! samba-patches 880 (This used to be commit 1466acba7e18f5ce733b376d031f1596a1a674d8) --- source3/lib/genrand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/genrand.c b/source3/lib/genrand.c index ee8bc0b1d5..fe756169a6 100644 --- a/source3/lib/genrand.c +++ b/source3/lib/genrand.c @@ -259,7 +259,7 @@ char *generate_random_str(size_t len) len = sizeof(retstr) -1; generate_random_buffer( retstr, len, False); for (i = 0; i < len; i++) - retstr[i] = c_list[ retstr[i] % sizeof(c_list) ]; + retstr[i] = c_list[ retstr[i] % (sizeof(c_list)-1) ]; retstr[i] = '\0'; -- cgit From a4ec4acd61d58bca9c1f6d474ab16265e4113f7a Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 28 Jul 2002 18:10:39 +0000 Subject: found nasty bug in intl/lang_tdb.c tdb structure was not tested to not be null before close this one fixes swat not working with browsers that set more then one language. along the way implemented language priority in web/neg_lang.c with bubble sort also changet str_list_make to be able to use a different separator string Simo. (This used to be commit 69765e4faa8aaae74c97afc917891fc72d80703d) --- source3/lib/debug.c | 2 +- source3/lib/username.c | 2 +- source3/lib/util_str.c | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/debug.c b/source3/lib/debug.c index be5f66a562..842d2dac1d 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -423,7 +423,7 @@ BOOL debug_parse_levels(const char *params_str) if (AllowDebugChange == False) return True; - params = str_list_make(params_str); + params = str_list_make(params_str, NULL); if (debug_parse_params(params, DEBUGLEVEL_CLASS, DEBUGLEVEL_CLASS_ISSET)) diff --git a/source3/lib/username.c b/source3/lib/username.c index 4813c8fd19..5db7f58b1e 100644 --- a/source3/lib/username.c +++ b/source3/lib/username.c @@ -163,7 +163,7 @@ BOOL map_username(char *user) } } - dosuserlist = str_list_make(dosname); + dosuserlist = str_list_make(dosname, NULL); if (!dosuserlist) { DEBUG(0,("Unable to build user list\n")); return False; diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 7e974269ec..9dc80c89db 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -1125,7 +1125,7 @@ some platforms don't have strnlen #define S_LIST_ABS 16 /* List Allocation Block Size */ -char **str_list_make(const char *string) +char **str_list_make(const char *string, const char *sep) { char **list, **rlist; char *str, *s; @@ -1139,12 +1139,13 @@ char **str_list_make(const char *string) DEBUG(0,("str_list_make: Unable to allocate memory")); return NULL; } + if (!sep) sep = LIST_SEP; num = lsize = 0; list = NULL; str = s; - while (next_token(&str, tok, LIST_SEP, sizeof(tok))) { + while (next_token(&str, tok, sep, sizeof(tok))) { if (num == lsize) { lsize += S_LIST_ABS; rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1))); -- cgit From 6eaa06ac53840f36a9c75650f21565828e8fbbd4 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 29 Jul 2002 09:23:01 +0000 Subject: A place to store common popt routines. (This used to be commit b5b64a4e90792000fc377a032cd5c7cb9918261b) --- source3/lib/popt_common.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 source3/lib/popt_common.c (limited to 'source3/lib') diff --git a/source3/lib/popt_common.c b/source3/lib/popt_common.c new file mode 100644 index 0000000000..288cd41b27 --- /dev/null +++ b/source3/lib/popt_common.c @@ -0,0 +1,49 @@ +/* + Unix SMB/CIFS implementation. + Common popt routines + + Copyright (C) Tim Potter 2001,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 + 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" + +/* Handle -d,--debuglevel command line option */ + +static void debug_callback(poptContext con, + enum poptCallbackReason reason, + const struct poptOption *opt, + const char *arg, const void *data) +{ + extern BOOL AllowDebugChange; + + switch(opt->val) { + case 'd': + if (arg) { + DEBUGLEVEL = atoi(arg); + AllowDebugChange = False; + } + + break; + } +} + +struct poptOption popt_common_debug[] = { + { NULL, 0, POPT_ARG_CALLBACK, debug_callback }, + { "debuglevel", 'd', POPT_ARG_INT, NULL, 'd', "Set debug level", + "DEBUGLEVEL" }, + POPT_TABLEEND +}; -- cgit From 362f534fa1152e9fc3d195bd1200b4c5d3e037e2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 29 Jul 2002 23:50:54 +0000 Subject: Our include popt is starting to get a bit old - fixed some compile problems here. Also fixed some non-constant initialisers in samsync. (This used to be commit 33bd7214736dafd5927d63af5f8510646b81e7df) --- source3/lib/popt_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/popt_common.c b/source3/lib/popt_common.c index 288cd41b27..a3d6af4fbc 100644 --- a/source3/lib/popt_common.c +++ b/source3/lib/popt_common.c @@ -45,5 +45,5 @@ struct poptOption popt_common_debug[] = { { NULL, 0, POPT_ARG_CALLBACK, debug_callback }, { "debuglevel", 'd', POPT_ARG_INT, NULL, 'd', "Set debug level", "DEBUGLEVEL" }, - POPT_TABLEEND + { 0 } }; -- cgit From 01d9beba6cf2882dc30445b68b3ae54d3bb17679 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 30 Jul 2002 09:21:57 +0000 Subject: Make some of the charconv code a bit easier to read and work with - when we are dealing with utf8 we may as well specify char** for the pointer, save otherwise casting in the caller. Andrew Bartlett (This used to be commit 46021f85b6da4ba1e7f73ee7408079219d555dde) --- source3/lib/charcnv.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index ea5bb87bc3..6e96136643 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -249,15 +249,15 @@ convert: size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, void const *src, size_t srclen, void **dest) { - void *ob; + void *alloced_string; size_t dest_len; *dest = NULL; - dest_len=convert_string_allocate(from, to, src, srclen, (void **)&ob); + dest_len=convert_string_allocate(from, to, src, srclen, &alloced_string); if (dest_len == -1) return -1; - *dest = talloc_strdup(ctx, (char *)ob); - SAFE_FREE(ob); + *dest = talloc_memdup(ctx, alloced_string, dest_len); + SAFE_FREE(alloced_string); if (*dest == NULL) return -1; return dest_len; @@ -505,12 +505,12 @@ int push_utf8_pstring(void *dest, const char *src) * * @retval The number of bytes occupied by the string in the destination **/ -int push_utf8_talloc(TALLOC_CTX *ctx, void **dest, const char *src) +int push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src) { int src_len = strlen(src)+1; *dest = NULL; - return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, dest); + return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void**)dest); } /** @@ -659,11 +659,11 @@ int pull_utf8_fstring(char *dest, const void *src) * * @retval The number of bytes occupied by the string in the destination **/ -int pull_utf8_talloc(TALLOC_CTX *ctx, void **dest, const char *src) +int pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src) { int src_len = strlen(src)+1; *dest = NULL; - return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, dest); + return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest); } /** -- cgit From 4516a14dbbc03f2ae2ce3c4d4e22e11e24a8a42f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 31 Jul 2002 04:56:16 +0000 Subject: added support for smbd listening on port 445 and 139. It now listens on both by default, and you can specify a list of ports to listen on either with "smb ports = " in smb.conf or using the -p option to smbd. this is needed for proper netbiosless operation. (This used to be commit 5dee0a7b5e0fcb298a9d36661c80e60d8b9bcc3a) --- source3/lib/util_sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 4f1f2a1470..5e2b7c5ed9 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -708,7 +708,7 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb /* now we've got a socket - we need to bind it */ if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) { - if( DEBUGLVL(dlevel) && (port == SMB_PORT || port == NMB_PORT) ) { + if( DEBUGLVL(dlevel) && (port == SMB_PORT1 || port == SMB_PORT2 || port == NMB_PORT) ) { dbgtext( "bind failed on port %d ", port ); dbgtext( "socket_addr = %s.\n", inet_ntoa( sock.sin_addr ) ); dbgtext( "Error = %s\n", strerror(errno) ); -- cgit From ab0b4e6f581d583c8572a6ba351536eacc240db1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 31 Jul 2002 09:32:45 +0000 Subject: make sure we zero the unusued elements in a SID when parsing (This used to be commit aa5beb63f1b1133c4ad28118ddd33e21198d79bb) --- source3/lib/util_sid.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 5dd1d75c70..ad09f91234 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -365,6 +365,9 @@ BOOL sid_parse(char *inbuf, size_t len, DOM_SID *sid) { int i; if (len < 8) return False; + + ZERO_STRUCTP(sid); + sid->sid_rev_num = CVAL(inbuf, 0); sid->num_auths = CVAL(inbuf, 1); memcpy(sid->id_auth, inbuf+2, 6); -- cgit From 4da476001e13dd032059ddaf72676c998089272d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Aug 2002 00:56:39 +0000 Subject: fixed a memory corruption bug in the wins code (This used to be commit 3f6ca04003172c22d02111f2170ad60f0d7936d9) --- source3/lib/wins_srv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/wins_srv.c b/source3/lib/wins_srv.c index adf405ae7e..61e77aca58 100644 --- a/source3/lib/wins_srv.c +++ b/source3/lib/wins_srv.c @@ -236,7 +236,7 @@ char **wins_srv_tags(void) } /* add it to the list */ - ret = (char **)Realloc(ret, (count+1) * sizeof(char *)); + ret = (char **)Realloc(ret, (count+2) * sizeof(char *)); ret[count] = strdup(t_ip.tag); if (!ret[count]) break; count++; -- cgit From 6ddba1e99b48afc53cf5bc7a2900279490c7a8f6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 10 Aug 2002 23:20:04 +0000 Subject: Fix the %m security bug again - and try to make it harder to reintroduce in future. This moves us from fstrcpy() and global variables to 'get' and 'set' functions. In particular, the 'set' function sainity-checks the input, in the same way as we always have. Andrew Bartlett (This used to be commit e57a896f06b16fe7e336e1ae63a0c9e4cc75fd36) --- source3/lib/substitute.c | 49 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index 6d96a1820f..c47b5914f1 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -28,6 +28,36 @@ fstring remote_proto="UNKNOWN"; fstring remote_machine=""; extern pstring global_myname; +void set_local_machine_name(const char* local_name) +{ + fstring tmp_local_machine; + + fstrcpy(tmp_local_machine,local_name); + trim_string(tmp_local_machine," "," "); + strlower(tmp_local_machine); + alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1); +} + +void set_remote_machine_name(const char* remote_name) +{ + fstring tmp_remote_machine; + + fstrcpy(tmp_remote_machine,remote_name); + trim_string(tmp_remote_machine," "," "); + strlower(tmp_remote_machine); + alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1); +} + +const char* get_remote_machine_name(void) +{ + return remote_machine; +} + +const char* get_local_machine_name(void) +{ + return local_machine; +} + /******************************************************************* Given a pointer to a %$(NAME) expand it as an environment variable. Return the number of characters by which the pointer should be advanced. @@ -188,14 +218,15 @@ static char *automount_path(const char *user_name) moved out to a separate function. *******************************************************************/ -static char *automount_server(const char *user_name) +static const char *automount_server(const char *user_name) { static pstring server_name; + const char *local_machine_name = get_local_machine_name(); /* use the local machine name as the default */ /* this will be the default if WITH_AUTOMOUNT is not used or fails */ - if (*local_machine) - pstrcpy(server_name, local_machine); + if (local_machine_name && *local_machine_name) + pstrcpy(server_name, local_machine_name); else pstrcpy(server_name, global_myname); @@ -229,6 +260,7 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len) char *p, *s; fstring pidstr; struct passwd *pass; + const char *local_machine_name = get_local_machine_name(); for (s=str; (p=strchr_m(s, '%'));s=p) { fstring tmp_str; @@ -261,8 +293,8 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len) string_sub(p,"%I", client_addr(),l); break; case 'L' : - if (*local_machine) - string_sub(p,"%L", local_machine,l); + if (local_machine_name && *local_machine_name) + string_sub(p,"%L", local_machine_name,l); else string_sub(p,"%L", global_myname,l); break; @@ -286,7 +318,7 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len) string_sub(p,"%h", myhostname(),l); break; case 'm' : - string_sub(p,"%m", remote_machine,l); + string_sub(p,"%m", get_remote_machine_name(),l); break; case 'v' : string_sub(p,"%v", VERSION,l); @@ -381,6 +413,7 @@ char *alloc_sub_basic(const char *smb_name, const char *str) char *b, *p, *s, *t, *r, *a_string; fstring pidstr; struct passwd *pass; + const char *local_machine_name = get_local_machine_name(); a_string = strdup(str); if (a_string == NULL) { @@ -415,8 +448,8 @@ char *alloc_sub_basic(const char *smb_name, const char *str) t = realloc_string_sub(t, "%I", client_addr()); break; case 'L' : - if (*local_machine) - t = realloc_string_sub(t, "%L", local_machine); + if (local_machine_name && *local_machine_name) + t = realloc_string_sub(t, "%L", local_machine_name); else t = realloc_string_sub(t, "%L", global_myname); break; -- cgit From dd5615c04241ec09e6b877a0670a957fa7702902 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Aug 2002 02:30:35 +0000 Subject: Make 'remote_machine' private to lib/substitute.c, and fix all the user to use the new accessor functions. Andrew Bartlett (This used to be commit f393de2310e997d05674eb7f1268655373e03647) --- source3/lib/substitute.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index c47b5914f1..026df0f67f 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -25,9 +25,11 @@ fstring local_machine=""; fstring remote_arch="UNKNOWN"; userdom_struct current_user_info; fstring remote_proto="UNKNOWN"; -fstring remote_machine=""; extern pstring global_myname; +static fstring remote_machine=""; + + void set_local_machine_name(const char* local_name) { fstring tmp_local_machine; -- cgit From d8d1d65958fd00514aff92d9d2240b8ff89583fb Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 12 Aug 2002 13:48:19 +0000 Subject: Code to generate uuids for ADS setups. Uses our random generator but conforms to standard OSF/DCE uuid format. (This used to be commit 3b50c3b8cd86ff9a12a6e22ca3b3e904671be547) --- source3/lib/util_uuid.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 source3/lib/util_uuid.c (limited to 'source3/lib') diff --git a/source3/lib/util_uuid.c b/source3/lib/util_uuid.c new file mode 100644 index 0000000000..b70db8de5b --- /dev/null +++ b/source3/lib/util_uuid.c @@ -0,0 +1,108 @@ +/* + * Unix SMB/CIFS implementation. + * UUID server routines + * Copyright (C) Theodore Ts'o 1996, 1997, + * Copyright (C) Jim McDonough 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 + * 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" + +/* + * Offset between 15-Oct-1582 and 1-Jan-70 + */ +#define TIME_OFFSET_HIGH 0x01B21DD2 +#define TIME_OFFSET_LOW 0x13814000 + +struct uuid { + uint32 time_low; + uint16 time_mid; + uint16 time_hi_and_version; + uint16 clock_seq; + uint8 node[6]; +}; + + +static void uuid_pack(const struct uuid *uu, GUID *ptr) +{ + uint32 tmp; + uint8 *out = ptr->info; + + tmp = uu->time_low; + out[3] = (uint8) tmp; + tmp >>= 8; + out[2] = (uint8) tmp; + tmp >>= 8; + out[1] = (uint8) tmp; + tmp >>= 8; + out[0] = (uint8) tmp; + + tmp = uu->time_mid; + out[5] = (uint8) tmp; + tmp >>= 8; + out[4] = (uint8) tmp; + + tmp = uu->time_hi_and_version; + out[7] = (uint8) tmp; + tmp >>= 8; + out[6] = (uint8) tmp; + + tmp = uu->clock_seq; + out[9] = (uint8) tmp; + tmp >>= 8; + out[8] = (uint8) tmp; + + memcpy(out+10, uu->node, 6); +} + +static void uuid_unpack(const GUID in, struct uuid *uu) +{ + const uint8 *ptr = in.info; + uint32 tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_low = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_mid = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->time_hi_and_version = tmp; + + tmp = *ptr++; + tmp = (tmp << 8) | *ptr++; + uu->clock_seq = tmp; + + memcpy(uu->node, ptr, 6); +} + +void uuid_generate_random(GUID *out) +{ + GUID tmp; + struct uuid uu; + + generate_random_buffer(tmp.info, sizeof(tmp.info), True); + uuid_unpack(tmp, &uu); + + uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000; + uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000; + uuid_pack(&uu, out); +} -- cgit From f3a15363d82b5b6204948ef623ad87c855dd5f57 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 12 Aug 2002 16:39:10 +0000 Subject: Use byteorder.h macros (This used to be commit eb9004efc3580799063009a8298c35cbc420626f) --- source3/lib/util_uuid.c | 54 +++++++++---------------------------------------- 1 file changed, 9 insertions(+), 45 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_uuid.c b/source3/lib/util_uuid.c index b70db8de5b..63e2504982 100644 --- a/source3/lib/util_uuid.c +++ b/source3/lib/util_uuid.c @@ -38,60 +38,24 @@ struct uuid { static void uuid_pack(const struct uuid *uu, GUID *ptr) { - uint32 tmp; uint8 *out = ptr->info; - tmp = uu->time_low; - out[3] = (uint8) tmp; - tmp >>= 8; - out[2] = (uint8) tmp; - tmp >>= 8; - out[1] = (uint8) tmp; - tmp >>= 8; - out[0] = (uint8) tmp; - - tmp = uu->time_mid; - out[5] = (uint8) tmp; - tmp >>= 8; - out[4] = (uint8) tmp; - - tmp = uu->time_hi_and_version; - out[7] = (uint8) tmp; - tmp >>= 8; - out[6] = (uint8) tmp; - - tmp = uu->clock_seq; - out[9] = (uint8) tmp; - tmp >>= 8; - out[8] = (uint8) tmp; - + SIVAL(out, 0, uu->time_low); + SSVAL(out, 4, uu->time_mid); + SSVAL(out, 6, uu->time_hi_and_version); + SSVAL(out, 8, uu->clock_seq); memcpy(out+10, uu->node, 6); } static void uuid_unpack(const GUID in, struct uuid *uu) { const uint8 *ptr = in.info; - uint32 tmp; - - tmp = *ptr++; - tmp = (tmp << 8) | *ptr++; - tmp = (tmp << 8) | *ptr++; - tmp = (tmp << 8) | *ptr++; - uu->time_low = tmp; - - tmp = *ptr++; - tmp = (tmp << 8) | *ptr++; - uu->time_mid = tmp; - - tmp = *ptr++; - tmp = (tmp << 8) | *ptr++; - uu->time_hi_and_version = tmp; - - tmp = *ptr++; - tmp = (tmp << 8) | *ptr++; - uu->clock_seq = tmp; - memcpy(uu->node, ptr, 6); + uu->time_low = IVAL(ptr, 0); + uu->time_mid = SVAL(ptr, 4); + uu->time_hi_and_version = SVAL(ptr, 6); + uu->clock_seq = SVAL(ptr, 8); + memcpy(uu->node, ptr+10, 6); } void uuid_generate_random(GUID *out) -- cgit From 10712f9a22c539c0f84bca96d73e2cf4d304566e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 15 Aug 2002 13:25:25 +0000 Subject: *** empty log message *** (This used to be commit cb72eead70509eddaa051571f3eed3c46304b5f8) --- source3/lib/account_pol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c index f603f0f191..07b5e2ecfc 100644 --- a/source3/lib/account_pol.c +++ b/source3/lib/account_pol.c @@ -100,7 +100,7 @@ static const char *decode_account_policy_name(int field) Get the account policy name as a string from its #define'ed number ****************************************************************************/ -int account_policy_name_to_feildnum(const char *name) +int account_policy_name_to_fieldnum(const char *name) { int i; for (i=0; account_policy_names[i].string; i++) { -- cgit From 88d321becdcff10f52a629946fb300d158fcc2fa Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 16 Aug 2002 00:25:48 +0000 Subject: Merge of netbios namecache code from APPLIANCE_HEAD. Tridge suggested a generic caching mechanism for Samba to avoid the proliferation of little cache files hanging around limpet like in the locks directory. Someone should probably implement this at some stage. (This used to be commit dad31483b3bd1790356ef1e40ac62624a403bce8) --- source3/lib/util_str.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 9dc80c89db..3b5ceb2217 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -212,6 +212,18 @@ int strwicmp(const char *psz1, const char *psz2) } +/* Convert a string to upper case, but don't modify it */ + +char *strupper_static(char *s) +{ + static pstring str; + + pstrcpy(str, s); + strupper(str); + + return str; +} + /******************************************************************* convert a string to "normal" form ********************************************************************/ -- cgit From ba1d3482653d2bfef0a9d233f118654dd7144ab3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 Aug 2002 04:56:38 +0000 Subject: The idea of this function is not to touch the argument, so make it const too... (This used to be commit 8a63fe45058b15c15d79e15387e908564cfe5c2d) --- source3/lib/util_str.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 3b5ceb2217..19d92eec8f 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -214,7 +214,7 @@ int strwicmp(const char *psz1, const char *psz2) /* Convert a string to upper case, but don't modify it */ -char *strupper_static(char *s) +char *strupper_static(const char *s) { static pstring str; -- cgit From 8690b271a6a4feb112e0a6c03fe99ee25f86430b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 17 Aug 2002 07:09:22 +0000 Subject: Move tridge's getgrouplist() replacement function from replace.c to a new 'system_smbd.c' file, where it can link with become_root() and unbecome_root(), and therefore avoiding some nasty 'it workes on linux' bugs. (The replacement function is implemented in terms of initgroups(), which is naturally only avaliable to root). Andrew Bartlett (This used to be commit a91018dd026be3db473bb1cf1f4981295f9758e4) --- source3/lib/replace.c | 64 ---------------------------- source3/lib/system_smbd.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++ source3/lib/util_getent.c | 35 ---------------- source3/lib/util_smbd.c | 65 ++++++++++++++++++++++++++++ 4 files changed, 170 insertions(+), 99 deletions(-) create mode 100644 source3/lib/system_smbd.c create mode 100644 source3/lib/util_smbd.c (limited to 'source3/lib') diff --git a/source3/lib/replace.c b/source3/lib/replace.c index e2664accfa..fd7b2cf7f0 100644 --- a/source3/lib/replace.c +++ b/source3/lib/replace.c @@ -430,67 +430,3 @@ char *rep_inet_ntoa(struct in_addr ip) #endif /* HAVE_VSYSLOG */ -#ifndef HAVE_GETGROUPLIST -/* - This is a *much* faster way of getting the list of groups for a user - without changing the current supplemenrary group list. The old - method used getgrent() which could take 20 minutes on a really big - network with hundeds of thousands of groups and users. The new method - takes a couple of seconds. - - NOTE!! this function only works if it is called as root! - */ - int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt) -{ - gid_t *gids_saved; - int ret, ngrp_saved; - - /* work out how many groups we need to save */ - ngrp_saved = getgroups(0, NULL); - if (ngrp_saved == -1) { - /* this shouldn't happen */ - return -1; - } - - gids_saved = (gid_t *)malloc(sizeof(gid_t) * (ngrp_saved+1)); - if (!gids_saved) { - errno = ENOMEM; - return -1; - } - - ngrp_saved = getgroups(ngrp_saved, gids_saved); - if (ngrp_saved == -1) { - free(gids_saved); - /* very strange! */ - return -1; - } - - if (initgroups(user, gid) != 0) { - free(gids_saved); - return -1; - } - - /* this must be done to cope with systems that put the current egid in the - return from getgroups() */ - save_re_gid(); - set_effective_gid(gid); - setgid(gid); - - ret = getgroups(*grpcnt, groups); - if (ret >= 0) { - *grpcnt = ret; - } - - restore_re_gid(); - - if (setgroups(ngrp_saved, gids_saved) != 0) { - /* yikes! */ - DEBUG(0,("ERROR: getgrouplist: failed to reset group list!\n")); - free(gids_saved); - return -1; - } - - free(gids_saved); - return ret; -} -#endif diff --git a/source3/lib/system_smbd.c b/source3/lib/system_smbd.c new file mode 100644 index 0000000000..28ceaf3939 --- /dev/null +++ b/source3/lib/system_smbd.c @@ -0,0 +1,105 @@ +/* + Unix SMB/CIFS implementation. + system call wrapper interface. + Copyright (C) Andrew Tridgell 2002 + Copyright (C) Andrew Barteltt 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 + 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. +*/ + +/* + This file may assume linkage with smbd - for things like become_root() + etc. +*/ + +#include "includes.h" + +#ifndef HAVE_GETGROUPLIST +/* + This is a *much* faster way of getting the list of groups for a user + without changing the current supplemenrary group list. The old + method used getgrent() which could take 20 minutes on a really big + network with hundeds of thousands of groups and users. The new method + takes a couple of seconds. + + NOTE!! this function only works if it is called as root! + */ +static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, int *grpcnt) +{ + gid_t *gids_saved; + int ret, ngrp_saved; + + /* work out how many groups we need to save */ + ngrp_saved = getgroups(0, NULL); + if (ngrp_saved == -1) { + /* this shouldn't happen */ + return -1; + } + + gids_saved = (gid_t *)malloc(sizeof(gid_t) * (ngrp_saved+1)); + if (!gids_saved) { + errno = ENOMEM; + return -1; + } + + ngrp_saved = getgroups(ngrp_saved, gids_saved); + if (ngrp_saved == -1) { + free(gids_saved); + /* very strange! */ + return -1; + } + + if (initgroups(user, gid) != 0) { + free(gids_saved); + return -1; + } + + /* this must be done to cope with systems that put the current egid in the + return from getgroups() */ + save_re_gid(); + set_effective_gid(gid); + setgid(gid); + + ret = getgroups(*grpcnt, groups); + if (ret >= 0) { + *grpcnt = ret; + } + + restore_re_gid(); + + if (setgroups(ngrp_saved, gids_saved) != 0) { + /* yikes! */ + DEBUG(0,("ERROR: getgrouplist: failed to reset group list!\n")); + smb_panic("getgrouplist: failed to reset group list!\n"); + free(gids_saved); + return -1; + } + + free(gids_saved); + return ret; +} +#endif + +int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt) +{ +#ifdef HAVE_GETGROUPLIST + return getgrouplist(user, gid, groups, grpcnt); +#else + int retval; + become_root(); + retval = getgrouplist_internals(user, gid, groups, grpcnt); + unbecome_root(); +#endif +} diff --git a/source3/lib/util_getent.c b/source3/lib/util_getent.c index 5d2fcd7652..6699ce3e92 100644 --- a/source3/lib/util_getent.c +++ b/source3/lib/util_getent.c @@ -299,38 +299,3 @@ void free_userlist(struct sys_userlist *list_head) SAFE_FREE(old_head); } } - - -/* - return a full list of groups for a user - - returns the number of groups the user is a member of. The return will include the - users primary group. - - remember to free the resulting gid_t array - - NOTE! you must be root to call this function on some systems -*/ -int getgroups_user(const char *user, gid_t **groups) -{ - struct passwd *pwd; - int ngrp, max_grp; - - pwd = getpwnam(user); - if (!pwd) return -1; - - max_grp = groups_max(); - (*groups) = (gid_t *)malloc(sizeof(gid_t) * max_grp); - if (! *groups) { - errno = ENOMEM; - return -1; - } - - ngrp = getgrouplist(user, pwd->pw_gid, *groups, &max_grp); - if (ngrp <= 0) { - free(*groups); - return ngrp; - } - - return ngrp; -} diff --git a/source3/lib/util_smbd.c b/source3/lib/util_smbd.c new file mode 100644 index 0000000000..071f20b416 --- /dev/null +++ b/source3/lib/util_smbd.c @@ -0,0 +1,65 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions, used in smbd only + Copyright (C) Andrew Tridgell 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 + 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" + +/* + This function requires sys_getgrouplist - which is only + available in smbd due to it's use of become_root() in a + legacy systems hack. +*/ + +/* + return a full list of groups for a user + + returns the number of groups the user is a member of. The return will include the + users primary group. + + remember to free the resulting gid_t array + + NOTE! uses become_root() to gain correct priviages on systems + that lack a native getgroups() call (uses initgroups and getgroups) +*/ +int getgroups_user(const char *user, gid_t **groups) +{ + struct passwd *pwd; + int ngrp, max_grp; + + pwd = getpwnam_alloc(user); + if (!pwd) return -1; + + max_grp = groups_max(); + (*groups) = (gid_t *)malloc(sizeof(gid_t) * max_grp); + if (! *groups) { + passwd_free(&pwd); + errno = ENOMEM; + return -1; + } + + ngrp = sys_getgrouplist(user, pwd->pw_gid, *groups, &max_grp); + if (ngrp <= 0) { + passwd_free(&pwd); + free(*groups); + return ngrp; + } + + passwd_free(&pwd); + return ngrp; +} -- cgit