X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source3%2Flib%2Fsubstitute.c;h=dbb5f7d08adc15b785253d2ca8d028317387768f;hb=c136b84f0d28d1a88c5918b06f81766a271a3780;hp=ce88a78e776d900551c2dca966a335d788ce55a3;hpb=6c25260ec12552653eabed25451866e370108c37;p=kai%2Fsamba.git diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index ce88a78e776..dbb5f7d08ad 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -3,25 +3,27 @@ string substitution functions Copyright (C) Andrew Tridgell 1992-2000 Copyright (C) Gerald Carter 2006 - + 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 3 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, see . */ #include "includes.h" +#include "secrets.h" -extern struct current_user current_user; +static char *alloc_sub_basic(const char *smb_name, const char *domain_name, + const char *str); userdom_struct current_user_info; fstring remote_proto="UNKNOWN"; @@ -34,6 +36,11 @@ fstring remote_proto="UNKNOWN"; static char *local_machine; +void free_local_machine_name(void) +{ + SAFE_FREE(local_machine); +} + bool set_local_machine_name(const char *local_name, bool perm) { static bool already_perm = false; @@ -72,8 +79,9 @@ bool set_local_machine_name(const char *local_name, bool perm) SAFE_FREE(tmp_local_machine); return false; } + /* alpha_strcpy includes the space for the terminating nul. */ alpha_strcpy(local_machine,tmp_local_machine, - SAFE_NETBIOS_CHARS,len); + SAFE_NETBIOS_CHARS,len+1); strlower_m(local_machine); SAFE_FREE(tmp_local_machine); @@ -123,8 +131,9 @@ bool set_remote_machine_name(const char *remote_name, bool perm) return false; } + /* alpha_strcpy includes the space for the terminating nul. */ alpha_strcpy(remote_machine,tmp_remote_machine, - SAFE_NETBIOS_CHARS,len); + SAFE_NETBIOS_CHARS,len+1); strlower_m(remote_machine); SAFE_FREE(tmp_remote_machine); @@ -185,9 +194,10 @@ void sub_set_smb_name(const char *name) return; } + /* alpha_strcpy includes the space for the terminating nul. */ alpha_strcpy(smb_user_name, tmp, SAFE_NETBIOS_CHARS, - len); + len+1); SAFE_FREE(tmp); @@ -205,11 +215,17 @@ static const char *get_smb_user_name(void) /******************************************************************* Setup the strings used by substitutions. Called per packet. Ensure %U name is set correctly also. + + smb_name must be sanitized by alpha_strcpy ********************************************************************/ -void set_current_user_info(const userdom_struct *pcui) +void set_current_user_info(const char *smb_name, const char *unix_name, + const char *domain) { - current_user_info = *pcui; + fstrcpy(current_user_info.smb_name, smb_name); + fstrcpy(current_user_info.unix_name, unix_name); + fstrcpy(current_user_info.domain, domain); + /* The following is safe as current_user_info.smb_name * has already been sanitised in register_existing_vuid. */ @@ -264,12 +280,12 @@ static char * realloc_expand_env_var(char *str, char *p) r = p + 3; copylen = q - r; - + /* reserve space for use later add %$() chars */ if ( (envname = (char *)SMB_MALLOC(copylen + 1 + 4)) == NULL ) { return NULL; } - + strncpy(envname,r,copylen); envname[copylen] = '\0'; @@ -289,7 +305,7 @@ static char * realloc_expand_env_var(char *str, char *p) envname[copylen] = '\0'; r = realloc_string_sub(str, envname, envval); SAFE_FREE(envname); - + return r; } @@ -298,19 +314,20 @@ static char * realloc_expand_env_var(char *str, char *p) static char *longvar_domainsid( void ) { - DOM_SID sid; + struct dom_sid sid; + fstring tmp; char *sid_string; - + if ( !secrets_fetch_domain_sid( lp_workgroup(), &sid ) ) { return NULL; } - - sid_string = SMB_STRDUP( sid_string_static( &sid ) ); - + + sid_string = SMB_STRDUP( sid_to_fstring( tmp, &sid ) ); + if ( !sid_string ) { DEBUG(0,("longvar_domainsid: failed to dup SID string!\n")); } - + return sid_string; } @@ -330,15 +347,15 @@ static struct api_longvar longvar_table[] = { static char *get_longvar_val( const char *varname ) { int i; - + DEBUG(7,("get_longvar_val: expanding variable [%s]\n", varname)); - + for ( i=0; longvar_table[i].name; i++ ) { if ( strequal( longvar_table[i].name, varname ) ) { return longvar_table[i].fn(); } } - + return NULL; } @@ -404,7 +421,7 @@ static const char *automount_path(const char *user_name) /* use the passwd entry as the default */ /* this will be the default if WITH_AUTOMOUNT is not used or fails */ - server_path = talloc_strdup(ctx, get_user_home_dir(user_name)); + server_path = talloc_strdup(ctx, get_user_home_dir(ctx, user_name)); if (!server_path) { return ""; } @@ -413,9 +430,9 @@ static const char *automount_path(const char *user_name) if (lp_nis_home_map()) { const char *home_path_start; - const char *automount_value = automount_lookup(user_name); + char *automount_value = automount_lookup(ctx, user_name); - if(strlen(automount_value) > 0) { + if(automount_value && strlen(automount_value) > 0) { home_path_start = strchr_m(automount_value,':'); if (home_path_start != NULL) { DEBUG(5, ("NIS lookup succeeded. " @@ -424,6 +441,9 @@ static const char *automount_path(const char *user_name) (home_path_start+1):"")); server_path = talloc_strdup(ctx, home_path_start+1); + if (!server_path) { + server_path = ""; + } } } else { /* NIS key lookup failed: default to @@ -434,9 +454,6 @@ static const char *automount_path(const char *user_name) } #endif - if (!server_path) { - server_path = ""; - } DEBUG(4,("Home server path: %s\n", server_path)); return server_path; } @@ -469,11 +486,14 @@ static const char *automount_server(const char *user_name) if (lp_nis_home_map()) { char *p; char *srv; - char *automount_value = automount_lookup(user_name); + char *automount_value = automount_lookup(ctx, user_name); if (!automount_value) { return ""; } srv = talloc_strdup(ctx, automount_value); + if (!srv) { + return ""; + } p = strchr_m(srv, ':'); if (!p) { return ""; @@ -485,9 +505,6 @@ static const char *automount_server(const char *user_name) } #endif - if (!server_name) { - server_name = ""; - } DEBUG(4,("Home server: %s\n", server_name)); return server_name; } @@ -502,13 +519,12 @@ void standard_sub_basic(const char *smb_name, const char *domain_name, char *str, size_t len) { char *s; - + if ( (s = alloc_sub_basic( smb_name, domain_name, str )) != NULL ) { strncpy( str, s, len ); } - + SAFE_FREE( s ); - } /**************************************************************************** @@ -520,7 +536,7 @@ char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, const char *domain_name, const char *str) { char *a, *t; - + if ( (a = alloc_sub_basic(smb_name, domain_name, str)) == NULL ) { return NULL; } @@ -532,61 +548,75 @@ char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, /**************************************************************************** ****************************************************************************/ -char *alloc_sub_basic(const char *smb_name, const char *domain_name, - const char *str) +static char *alloc_sub_basic(const char *smb_name, const char *domain_name, + const char *str) { char *b, *p, *s, *r, *a_string; fstring pidstr, vnnstr; - struct passwd *pass; char addr[INET6_ADDRSTRLEN]; const char *local_machine_name = get_local_machine_name(); + TALLOC_CTX *tmp_ctx = NULL; /* workaround to prevent a crash while looking at bug #687 */ - + if (!str) { DEBUG(0,("alloc_sub_basic: NULL source string! This should not happen\n")); return NULL; } - + a_string = SMB_STRDUP(str); if (a_string == NULL) { DEBUG(0, ("alloc_sub_basic: Out of memory!\n")); return NULL; } - + + tmp_ctx = talloc_stackframe(); + for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) { r = NULL; b = a_string; - + switch (*(p+1)) { case 'U' : - r = strdup_lower(smb_name); + r = strlower_talloc(tmp_ctx, smb_name); if (r == NULL) { goto error; } a_string = realloc_string_sub(a_string, "%U", r); break; - case 'G' : - r = SMB_STRDUP(smb_name); + case 'G' : { + struct passwd *pass; + r = talloc_strdup(tmp_ctx, smb_name); if (r == NULL) { goto error; } - if ((pass = Get_Pwnam(r))!=NULL) { - a_string = realloc_string_sub(a_string, "%G", gidtoname(pass->pw_gid)); - } + pass = Get_Pwnam_alloc(tmp_ctx, r); + if (pass != NULL) { + a_string = realloc_string_sub( + a_string, "%G", + gidtoname(pass->pw_gid)); + } + TALLOC_FREE(pass); break; + } case 'D' : - r = strdup_upper(domain_name); + r = strupper_talloc(tmp_ctx, domain_name); if (r == NULL) { goto error; } a_string = realloc_string_sub(a_string, "%D", r); break; - case 'I' : + case 'I' : { + int offset = 0; + client_addr(get_client_fd(), addr, sizeof(addr)); + if (strnequal(addr,"::ffff:",7)) { + offset = 7; + } a_string = realloc_string_sub(a_string, "%I", - client_addr(get_client_fd(),addr, sizeof(addr))); + addr + offset); break; + } case 'i': a_string = realloc_string_sub( a_string, "%i", client_socket_addr(get_client_fd(), addr, sizeof(addr)) ); @@ -611,7 +641,7 @@ char *alloc_sub_basic(const char *smb_name, const char *domain_name, a_string = realloc_string_sub(a_string, "%R", remote_proto); break; case 'T' : - a_string = realloc_string_sub(a_string, "%T", current_timestring(False)); + a_string = realloc_string_sub(a_string, "%T", current_timestring(tmp_ctx, False)); break; case 'a' : a_string = realloc_string_sub(a_string, "%a", @@ -625,10 +655,13 @@ char *alloc_sub_basic(const char *smb_name, const char *domain_name, a_string = realloc_string_sub(a_string, "%h", myhostname()); break; case 'm' : - a_string = realloc_string_sub(a_string, "%m", remote_machine); + a_string = realloc_string_sub(a_string, "%m", + remote_machine + ? remote_machine + : ""); break; case 'v' : - a_string = realloc_string_sub(a_string, "%v", SAMBA_VERSION_STRING); + a_string = realloc_string_sub(a_string, "%v", samba_version_string()); break; case 'w' : a_string = realloc_string_sub(a_string, "%w", lp_winbind_separator()); @@ -648,18 +681,21 @@ char *alloc_sub_basic(const char *smb_name, const char *domain_name, } p++; - SAFE_FREE(r); - - if ( !a_string ) { - return NULL; + TALLOC_FREE(r); + + if (a_string == NULL) { + goto done; } } - return a_string; + goto done; error: SAFE_FREE(a_string); - return NULL; + +done: + TALLOC_FREE(tmp_ctx); + return a_string; } /**************************************************************************** @@ -689,11 +725,11 @@ char *talloc_sub_specified(TALLOC_CTX *mem_ctx, DEBUG(0, ("talloc_sub_specified: Out of memory!\n")); goto done; } - + for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) { - + b = a_string; - + switch (*(p+1)) { case 'U' : a_string = talloc_string_sub( @@ -762,26 +798,29 @@ static char *alloc_sub_advanced(const char *servicename, const char *user, const char *str) { char *a_string, *ret_string; - char *b, *p, *s, *h; + char *b, *p, *s; a_string = SMB_STRDUP(str); if (a_string == NULL) { DEBUG(0, ("alloc_sub_advanced: Out of memory!\n")); return NULL; } - + for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) { - + b = a_string; - + switch (*(p+1)) { case 'N' : a_string = realloc_string_sub(a_string, "%N", automount_server(user)); break; - case 'H': - if ((h = get_user_home_dir(user))) + case 'H': { + char *h; + if ((h = get_user_home_dir(talloc_tos(), user))) a_string = realloc_string_sub(a_string, "%H", h); + TALLOC_FREE(h); break; + } case 'P': a_string = realloc_string_sub(a_string, "%P", connectpath); break; @@ -794,7 +833,7 @@ static char *alloc_sub_advanced(const char *servicename, const char *user, case 'u': a_string = realloc_string_sub(a_string, "%u", user); break; - + /* 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 @@ -806,7 +845,7 @@ static char *alloc_sub_advanced(const char *servicename, const char *user, a_string = realloc_string_sub(a_string, "%p", automount_path(servicename)); break; - + default: break; } @@ -828,8 +867,8 @@ static char *alloc_sub_advanced(const char *servicename, const char *user, */ char *talloc_sub_advanced(TALLOC_CTX *mem_ctx, - const char *servicename, const char *user, - const char *connectpath, gid_t gid, + const char *servicename, const char *user, + const char *connectpath, gid_t gid, const char *smb_name, const char *domain_name, const char *str) { @@ -845,13 +884,13 @@ char *talloc_sub_advanced(TALLOC_CTX *mem_ctx, } -void standard_sub_advanced(const char *servicename, const char *user, - const char *connectpath, gid_t gid, +void standard_sub_advanced(const char *servicename, const char *user, + const char *connectpath, gid_t gid, const char *smb_name, const char *domain_name, char *str, size_t len) { char *s; - + s = alloc_sub_advanced(servicename, user, connectpath, gid, smb_name, domain_name, str); @@ -862,19 +901,17 @@ void standard_sub_advanced(const char *servicename, const char *user, } /**************************************************************************** - * Do some standard substitutions in a string. - * ****************************************************************************/ + Do some standard substitutions in a string. +****************************************************************************/ -void standard_sub_conn(connection_struct *conn, char *str, size_t len) +char *standard_sub_conn(TALLOC_CTX *ctx, connection_struct *conn, const char *str) { - char *s; - - s = alloc_sub_advanced(lp_servicename(SNUM(conn)), conn->user, conn->connectpath, - conn->gid, get_smb_user_name(), "", str); - - if ( s ) { - strncpy( str, s, len ); - SAFE_FREE( s ); - } + return talloc_sub_advanced(ctx, + lp_servicename(SNUM(conn)), + conn->server_info->unix_name, + conn->connectpath, + conn->server_info->utok.gid, + get_smb_user_name(), + "", + str); } -