LCOV - code coverage report
Current view: top level - source3/lib - substitute.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 235 305 77.0 %
Date: 2021-09-23 10:06:22 Functions: 13 14 92.9 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    string substitution functions
       4             :    Copyright (C) Andrew Tridgell 1992-2000
       5             :    Copyright (C) Gerald Carter   2006
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : 
      22             : #include "includes.h"
      23             : #include "system/passwd.h"
      24             : #include "secrets.h"
      25             : #include "auth.h"
      26             : #include "lib/util/string_wrappers.h"
      27             : 
      28             : /* Max DNS name is 253 + '\0' */
      29             : #define MACHINE_NAME_SIZE 254
      30             : 
      31             : static char local_machine[MACHINE_NAME_SIZE];
      32             : static char remote_machine[MACHINE_NAME_SIZE];
      33             : 
      34             : userdom_struct current_user_info;
      35             : fstring remote_proto="UNKNOWN";
      36             : 
      37             : /**
      38             :  * Set the 'local' machine name
      39             :  * @param local_name the name we are being called
      40             :  * @param if this is the 'final' name for us, not be be changed again
      41             :  */
      42        1082 : bool set_local_machine_name(const char *local_name, bool perm)
      43             : {
      44             :         static bool already_perm = false;
      45             :         char tmp[MACHINE_NAME_SIZE];
      46             : 
      47        1082 :         if (already_perm) {
      48           0 :                 return true;
      49             :         }
      50             : 
      51        1082 :         strlcpy(tmp, local_name, sizeof(tmp));
      52        1082 :         trim_char(tmp, ' ', ' ');
      53             : 
      54        1082 :         alpha_strcpy(local_machine,
      55             :                      tmp,
      56             :                      SAFE_NETBIOS_CHARS,
      57             :                      sizeof(local_machine) - 1);
      58        1082 :         if (!strlower_m(local_machine)) {
      59           0 :                 return false;
      60             :         }
      61             : 
      62        1082 :         already_perm = perm;
      63             : 
      64        1082 :         return true;
      65             : }
      66             : 
      67    13900687 : const char *get_local_machine_name(void)
      68             : {
      69    13900687 :         if (local_machine[0] == '\0') {
      70    13412746 :                 return lp_netbios_name();
      71             :         }
      72             : 
      73      487941 :         return local_machine;
      74             : }
      75             : 
      76             : /**
      77             :  * Set the 'remote' machine name
      78             :  *
      79             :  * @param remote_name the name our client wants to be called by
      80             :  * @param if this is the 'final' name for them, not be be changed again
      81             :  */
      82       48355 : bool set_remote_machine_name(const char *remote_name, bool perm)
      83             : {
      84             :         static bool already_perm = False;
      85             :         char tmp[MACHINE_NAME_SIZE];
      86             : 
      87       48355 :         if (already_perm) {
      88        3447 :                 return true;
      89             :         }
      90             : 
      91       44908 :         strlcpy(tmp, remote_name, sizeof(tmp));
      92       44908 :         trim_char(tmp, ' ', ' ');
      93             : 
      94       44908 :         alpha_strcpy(remote_machine,
      95             :                      tmp,
      96             :                      SAFE_NETBIOS_CHARS,
      97             :                      sizeof(remote_machine) - 1);
      98       44908 :         if (!strlower_m(remote_machine)) {
      99           0 :                 return false;
     100             :         }
     101             : 
     102       44908 :         already_perm = perm;
     103             : 
     104       44908 :         return true;
     105             : }
     106             : 
     107        1149 : const char *get_remote_machine_name(void)
     108             : {
     109        1149 :         return remote_machine;
     110             : }
     111             : 
     112             : static char sub_peeraddr[INET6_ADDRSTRLEN];
     113             : static const char *sub_peername = NULL;
     114             : static char sub_sockaddr[INET6_ADDRSTRLEN];
     115             : 
     116       27259 : void sub_set_socket_ids(const char *peeraddr, const char *peername,
     117             :                         const char *sockaddr)
     118             : {
     119       27259 :         const char *addr = peeraddr;
     120             : 
     121       27259 :         if (strnequal(addr, "::ffff:", 7)) {
     122           0 :                 addr += 7;
     123             :         }
     124       27259 :         strlcpy(sub_peeraddr, addr, sizeof(sub_peeraddr));
     125             : 
     126       27259 :         if (sub_peername != NULL &&
     127           0 :                         sub_peername != sub_peeraddr) {
     128           0 :                 talloc_free(discard_const_p(char,sub_peername));
     129           0 :                 sub_peername = NULL;
     130             :         }
     131       27259 :         sub_peername = talloc_strdup(NULL, peername);
     132       27259 :         if (sub_peername == NULL) {
     133           0 :                 sub_peername = sub_peeraddr;
     134             :         }
     135             : 
     136             :         /*
     137             :          * Shouldn't we do the ::ffff: cancellation here as well? The
     138             :          * original code in talloc_sub_basic() did not do it, so I'm
     139             :          * leaving it out here as well for compatibility.
     140             :          */
     141       27259 :         strlcpy(sub_sockaddr, sockaddr, sizeof(sub_sockaddr));
     142       27259 : }
     143             : 
     144             : /*******************************************************************
     145             :  Setup the strings used by substitutions. Called per packet. Ensure
     146             :  %U name is set correctly also.
     147             : 
     148             :  smb_name must be sanitized by alpha_strcpy
     149             : ********************************************************************/
     150             : 
     151     5526218 : void set_current_user_info(const char *smb_name, const char *unix_name,
     152             :                            const char *domain)
     153             : {
     154             :         static const void *last_smb_name;
     155             :         static const void *last_unix_name;
     156             :         static const void *last_domain;
     157             : 
     158     5526218 :         if (likely(last_smb_name == smb_name &&
     159             :             last_unix_name == unix_name &&
     160             :             last_domain == domain))
     161             :         {
     162     5166046 :                 return;
     163             :         }
     164             : 
     165      354934 :         fstrcpy(current_user_info.smb_name, smb_name);
     166      354934 :         fstrcpy(current_user_info.unix_name, unix_name);
     167      354934 :         fstrcpy(current_user_info.domain, domain);
     168             : 
     169      354934 :         last_smb_name = smb_name;
     170      354934 :         last_unix_name = unix_name;
     171      354934 :         last_domain = domain;
     172             : }
     173             : 
     174             : /*******************************************************************
     175             :  Return the current active user name.
     176             : *******************************************************************/
     177             : 
     178    13627867 : const char *get_current_username(void)
     179             : {
     180    13627867 :         return current_user_info.smb_name;
     181             : }
     182             : 
     183             : /*******************************************************************
     184             :  Given a pointer to a %$(NAME) in p and the whole string in str
     185             :  expand it as an environment variable.
     186             :  str must be a talloced string.
     187             :  Return a new allocated and expanded string.
     188             :  Based on code by Branko Cibej <branko.cibej@hermes.si>
     189             :  When this is called p points at the '%' character.
     190             :  May substitute multiple occurrencies of the same env var.
     191             : ********************************************************************/
     192             : 
     193           0 : static char *realloc_expand_env_var(char *str, char *p)
     194             : {
     195             :         char *envname;
     196             :         char *envval;
     197             :         char *q, *r;
     198             :         int copylen;
     199             : 
     200           0 :         if (p[0] != '%' || p[1] != '$' || p[2] != '(') {
     201           0 :                 return str;
     202             :         }
     203             : 
     204             :         /*
     205             :          * Look for the terminating ')'.
     206             :          */
     207             : 
     208           0 :         if ((q = strchr_m(p,')')) == NULL) {
     209           0 :                 DEBUG(0,("expand_env_var: Unterminated environment variable [%s]\n", p));
     210           0 :                 return str;
     211             :         }
     212             : 
     213             :         /*
     214             :          * Extract the name from within the %$(NAME) string.
     215             :          */
     216             : 
     217           0 :         r = p + 3;
     218           0 :         copylen = q - r;
     219             : 
     220             :         /* reserve space for use later add %$() chars */
     221           0 :         if ( (envname = talloc_array(talloc_tos(), char, copylen + 1 + 4)) == NULL ) {
     222           0 :                 return NULL;
     223             :         }
     224             : 
     225           0 :         strncpy(envname,r,copylen);
     226           0 :         envname[copylen] = '\0';
     227             : 
     228           0 :         if ((envval = getenv(envname)) == NULL) {
     229           0 :                 DEBUG(0,("expand_env_var: Environment variable [%s] not set\n", envname));
     230           0 :                 TALLOC_FREE(envname);
     231           0 :                 return str;
     232             :         }
     233             : 
     234             :         /*
     235             :          * Copy the full %$(NAME) into envname so it
     236             :          * can be replaced.
     237             :          */
     238             : 
     239           0 :         copylen = q + 1 - p;
     240           0 :         strncpy(envname,p,copylen);
     241           0 :         envname[copylen] = '\0';
     242           0 :         r = realloc_string_sub(str, envname, envval);
     243           0 :         TALLOC_FREE(envname);
     244             : 
     245           0 :         return r;
     246             : }
     247             : 
     248             : /****************************************************************************
     249             :  Do some standard substitutions in a string.
     250             :  len is the length in bytes of the space allowed in string str. If zero means
     251             :  don't allow expansions.
     252             : ****************************************************************************/
     253             : 
     254    10602120 : void standard_sub_basic(const char *smb_name, const char *domain_name,
     255             :                         char *str, size_t len)
     256             : {
     257             :         char *s;
     258             : 
     259    10602120 :         if ( (s = talloc_sub_basic(talloc_tos(), smb_name, domain_name, str )) != NULL ) {
     260    10568177 :                 strncpy( str, s, len );
     261             :         }
     262             : 
     263    10602120 :         TALLOC_FREE( s );
     264    10602120 : }
     265             : 
     266             : /*
     267             :  * Limit addresses to hexalpha charactes and underscore, safe for path
     268             :  * components for Windows clients.
     269             :  */
     270        1316 : static void make_address_pathsafe(char *addr)
     271             : {
     272       14816 :         while(addr && *addr) {
     273       12616 :                 if(!isxdigit(*addr)) {
     274        3948 :                         *addr = '_';
     275             :                 }
     276       12616 :                 ++addr;
     277             :         }
     278        1316 : }
     279             : 
     280             : /****************************************************************************
     281             :  Do some standard substitutions in a string.
     282             :  This function will return a talloced string that has to be freed.
     283             : ****************************************************************************/
     284             : 
     285    13898634 : char *talloc_sub_basic(TALLOC_CTX *mem_ctx,
     286             :                         const char *smb_name,
     287             :                         const char *domain_name,
     288             :                         const char *str)
     289             : {
     290             :         char *b, *p, *s, *r, *a_string;
     291             :         fstring pidstr, vnnstr;
     292    13898634 :         const char *local_machine_name = get_local_machine_name();
     293    13898634 :         TALLOC_CTX *tmp_ctx = NULL;
     294             : 
     295             :         /* workaround to prevent a crash while looking at bug #687 */
     296             : 
     297    13898634 :         if (!str) {
     298           0 :                 DEBUG(0,("talloc_sub_basic: NULL source string!  This should not happen\n"));
     299           0 :                 return NULL;
     300             :         }
     301             : 
     302    13898634 :         a_string = talloc_strdup(mem_ctx, str);
     303    13898634 :         if (a_string == NULL) {
     304           0 :                 DEBUG(0, ("talloc_sub_basic: Out of memory!\n"));
     305           0 :                 return NULL;
     306             :         }
     307             : 
     308    13898634 :         tmp_ctx = talloc_stackframe();
     309             : 
     310    14137029 :         for (s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) {
     311             : 
     312      238395 :                 r = NULL;
     313      238395 :                 b = a_string;
     314             : 
     315      238395 :                 switch (*(p+1)) {
     316      100388 :                 case 'U' : 
     317      100388 :                         r = strlower_talloc(tmp_ctx, smb_name);
     318      100388 :                         if (r == NULL) {
     319           0 :                                 goto error;
     320             :                         }
     321      100388 :                         a_string = realloc_string_sub(a_string, "%U", r);
     322      100388 :                         break;
     323          52 :                 case 'G' : {
     324             :                         struct passwd *pass;
     325          52 :                         bool is_domain_name = false;
     326          52 :                         const char *sep = lp_winbind_separator();
     327             : 
     328         102 :                         if (domain_name != NULL && domain_name[0] != '\0' &&
     329          50 :                             (lp_security() == SEC_ADS ||
     330           0 :                              lp_security() == SEC_DOMAIN)) {
     331          50 :                                 r = talloc_asprintf(tmp_ctx,
     332             :                                                     "%s%c%s",
     333             :                                                     domain_name,
     334          50 :                                                     *sep,
     335             :                                                     smb_name);
     336          50 :                                 is_domain_name = true;
     337             :                         } else {
     338           2 :                                 r = talloc_strdup(tmp_ctx, smb_name);
     339             :                         }
     340          52 :                         if (r == NULL) {
     341           0 :                                 goto error;
     342             :                         }
     343             : 
     344          52 :                         pass = Get_Pwnam_alloc(tmp_ctx, r);
     345          52 :                         if (pass != NULL) {
     346             :                                 char *group_name;
     347             : 
     348          28 :                                 group_name = gidtoname(pass->pw_gid);
     349          28 :                                 if (is_domain_name) {
     350             :                                         char *group_sep;
     351          28 :                                         group_sep = strchr_m(group_name, *sep);
     352          28 :                                         if (group_sep != NULL) {
     353          28 :                                                 group_name = group_sep + 1;
     354             :                                         }
     355             :                                 }
     356          28 :                                 a_string = realloc_string_sub(a_string,
     357             :                                                               "%G",
     358             :                                                               group_name);
     359             :                         }
     360          52 :                         TALLOC_FREE(pass);
     361          52 :                         break;
     362             :                 }
     363         159 :                 case 'D' :
     364         159 :                         r = strupper_talloc(tmp_ctx, domain_name);
     365         159 :                         if (r == NULL) {
     366           0 :                                 goto error;
     367             :                         }
     368         159 :                         a_string = realloc_string_sub(a_string, "%D", r);
     369         159 :                         break;
     370           3 :                 case 'I' : {
     371           3 :                         a_string = realloc_string_sub(
     372             :                                 a_string, "%I",
     373           3 :                                 sub_peeraddr[0] ? sub_peeraddr : "0.0.0.0");
     374           3 :                         break;
     375             :                 }
     376           1 :                 case 'J' : {
     377           1 :                         r = talloc_strdup(tmp_ctx,
     378           1 :                                 sub_peeraddr[0] ? sub_peeraddr : "0.0.0.0");
     379           1 :                         make_address_pathsafe(r);
     380           1 :                         a_string = realloc_string_sub(a_string, "%J", r);
     381           1 :                         break;
     382             :                 }
     383           3 :                 case 'i': 
     384           3 :                         a_string = realloc_string_sub(
     385             :                                 a_string, "%i",
     386           3 :                                 sub_sockaddr[0] ? sub_sockaddr : "0.0.0.0");
     387           3 :                         break;
     388        1315 :                 case 'j' : {
     389        1315 :                         r = talloc_strdup(tmp_ctx,
     390        1315 :                                 sub_sockaddr[0] ? sub_sockaddr : "0.0.0.0");
     391        1315 :                         make_address_pathsafe(r);
     392        1315 :                         a_string = realloc_string_sub(a_string, "%j", r);
     393        1315 :                         break;
     394             :                 }
     395           6 :                 case 'L' : 
     396           6 :                         if ( strncasecmp_m(p, "%LOGONSERVER%", strlen("%LOGONSERVER%")) == 0 ) {
     397           0 :                                 break;
     398             :                         }
     399           6 :                         if (local_machine_name && *local_machine_name) {
     400           6 :                                 a_string = realloc_string_sub(a_string, "%L", local_machine_name); 
     401             :                         } else {
     402           0 :                                 a_string = realloc_string_sub(a_string, "%L", lp_netbios_name());
     403             :                         }
     404           6 :                         break;
     405       94176 :                 case 'N' :
     406       94176 :                         a_string = realloc_string_sub(a_string,
     407             :                                                       "%N",
     408             :                                                       lp_netbios_name());
     409       94176 :                         break;
     410           2 :                 case 'M' :
     411           2 :                         a_string = realloc_string_sub(a_string, "%M",
     412           2 :                                                       sub_peername ? sub_peername : "");
     413           2 :                         break;
     414           2 :                 case 'R' :
     415           2 :                         a_string = realloc_string_sub(a_string, "%R", remote_proto);
     416           2 :                         break;
     417           2 :                 case 'T' :
     418           2 :                         a_string = realloc_string_sub(a_string, "%T", current_timestring(tmp_ctx, False));
     419           2 :                         break;
     420         163 :                 case 't' :
     421         163 :                         a_string = realloc_string_sub(a_string, "%t",
     422         163 :                                                       current_minimal_timestring(tmp_ctx, False));
     423         163 :                         break;
     424           2 :                 case 'a' :
     425           2 :                         a_string = realloc_string_sub(a_string, "%a",
     426             :                                         get_remote_arch_str());
     427           2 :                         break;
     428           2 :                 case 'd' :
     429           2 :                         slprintf(pidstr,sizeof(pidstr)-1, "%d",(int)getpid());
     430           2 :                         a_string = realloc_string_sub(a_string, "%d", pidstr);
     431           2 :                         break;
     432           2 :                 case 'h' :
     433           2 :                         a_string = realloc_string_sub(a_string, "%h", myhostname());
     434           2 :                         break;
     435       40652 :                 case 'm' :
     436       40652 :                         a_string = realloc_string_sub(a_string, "%m",
     437             :                                                       remote_machine);
     438       40652 :                         break;
     439           2 :                 case 'v' :
     440           2 :                         a_string = realloc_string_sub(a_string, "%v", samba_version_string());
     441           2 :                         break;
     442           2 :                 case 'w' :
     443           2 :                         a_string = realloc_string_sub(a_string, "%w", lp_winbind_separator());
     444           2 :                         break;
     445           0 :                 case '$' :
     446           0 :                         a_string = realloc_expand_env_var(a_string, p); /* Expand environment variables */
     447           0 :                         break;
     448           2 :                 case 'V' :
     449           2 :                         slprintf(vnnstr,sizeof(vnnstr)-1, "%u", get_my_vnn());
     450           2 :                         a_string = realloc_string_sub(a_string, "%V", vnnstr);
     451           2 :                         break;
     452        1459 :                 default: 
     453        1459 :                         break;
     454             :                 }
     455             : 
     456      238395 :                 p++;
     457      238395 :                 TALLOC_FREE(r);
     458             : 
     459      238395 :                 if (a_string == NULL) {
     460           0 :                         goto done;
     461             :                 }
     462             :         }
     463             : 
     464    13840418 :         goto done;
     465             : 
     466           0 : error:
     467           0 :         TALLOC_FREE(a_string);
     468             : 
     469    13048090 : done:
     470    13898634 :         TALLOC_FREE(tmp_ctx);
     471    13840418 :         return a_string;
     472             : }
     473             : 
     474             : /****************************************************************************
     475             :  Do some specific substitutions in a string.
     476             :  This function will return an allocated string that have to be freed.
     477             : ****************************************************************************/
     478             : 
     479      101229 : char *talloc_sub_specified(TALLOC_CTX *mem_ctx,
     480             :                         const char *input_string,
     481             :                         const char *username,
     482             :                         const char *grpname,
     483             :                         const char *domain,
     484             :                         uid_t uid,
     485             :                         gid_t gid)
     486             : {
     487             :         char *a_string;
     488      101229 :         char *ret_string = NULL;
     489             :         char *b, *p, *s;
     490             :         TALLOC_CTX *tmp_ctx;
     491             : 
     492      101229 :         if (!(tmp_ctx = talloc_new(mem_ctx))) {
     493           0 :                 DEBUG(0, ("talloc_new failed\n"));
     494           0 :                 return NULL;
     495             :         }
     496             : 
     497      101229 :         a_string = talloc_strdup(tmp_ctx, input_string);
     498      101229 :         if (a_string == NULL) {
     499           0 :                 DEBUG(0, ("talloc_sub_specified: Out of memory!\n"));
     500           0 :                 goto done;
     501             :         }
     502             : 
     503      203567 :         for (s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) {
     504             : 
     505      102347 :                 b = a_string;
     506             : 
     507      102347 :                 switch (*(p+1)) {
     508       50610 :                 case 'U' : 
     509       50610 :                         a_string = talloc_string_sub(
     510             :                                 tmp_ctx, a_string, "%U", username);
     511       50610 :                         break;
     512           2 :                 case 'u' : 
     513           2 :                         a_string = talloc_string_sub(
     514             :                                 tmp_ctx, a_string, "%u", username);
     515           2 :                         break;
     516        1120 :                 case 'G' :
     517        1120 :                         if (gid != -1) {
     518             :                                 const char *name;
     519             : 
     520        1119 :                                 if (grpname != NULL) {
     521        1118 :                                         name = grpname;
     522             :                                 } else {
     523           1 :                                         name = gidtoname(gid);
     524             :                                 }
     525             : 
     526        1119 :                                 a_string = talloc_string_sub(tmp_ctx,
     527             :                                                              a_string,
     528             :                                                              "%G",
     529             :                                                              name);
     530             :                         } else {
     531           1 :                                 a_string = talloc_string_sub(
     532             :                                         tmp_ctx, a_string,
     533             :                                         "%G", "NO_GROUP");
     534             :                         }
     535        1118 :                         break;
     536           2 :                 case 'g' :
     537           2 :                         if (gid != -1) {
     538             :                                 const char *name;
     539             : 
     540           1 :                                 if (grpname != NULL) {
     541           0 :                                         name = grpname;
     542             :                                 } else {
     543           1 :                                         name = gidtoname(gid);
     544             :                                 }
     545             : 
     546           1 :                                 a_string = talloc_string_sub(tmp_ctx,
     547             :                                                              a_string,
     548             :                                                              "%g",
     549             :                                                              name);
     550             :                         } else {
     551           1 :                                 a_string = talloc_string_sub(
     552             :                                         tmp_ctx, a_string, "%g", "NO_GROUP");
     553             :                         }
     554           0 :                         break;
     555       45329 :                 case 'D' :
     556       45329 :                         a_string = talloc_string_sub(tmp_ctx, a_string,
     557             :                                                      "%D", domain);
     558       45329 :                         break;
     559        5280 :                 case 'N' :
     560        5280 :                         a_string = talloc_string_sub(tmp_ctx, a_string,
     561             :                                                      "%N", lp_netbios_name());
     562        5280 :                         break;
     563           0 :                 default: 
     564           0 :                         break;
     565             :                 }
     566             : 
     567      102347 :                 p++;
     568      102347 :                 if (a_string == NULL) {
     569           0 :                         goto done;
     570             :                 }
     571             :         }
     572             : 
     573             :         /* Watch out, using "mem_ctx" here, so all intermediate stuff goes
     574             :          * away with the TALLOC_FREE(tmp_ctx) further down. */
     575             : 
     576      101229 :         ret_string = talloc_sub_basic(mem_ctx, username, domain, a_string);
     577             : 
     578      101229 :  done:
     579      101229 :         TALLOC_FREE(tmp_ctx);
     580      101229 :         return ret_string;
     581             : }
     582             : 
     583             : /****************************************************************************
     584             : ****************************************************************************/
     585             : 
     586       62693 : char *talloc_sub_advanced(TALLOC_CTX *ctx,
     587             :                         const char *servicename,
     588             :                         const char *user,
     589             :                         const char *connectpath,
     590             :                         gid_t gid,
     591             :                         const char *str)
     592             : {
     593             :         char *a_string;
     594             :         char *b, *p, *s;
     595             : 
     596       62693 :         a_string = talloc_strdup(talloc_tos(), str);
     597       62693 :         if (a_string == NULL) {
     598           0 :                 DEBUG(0, ("talloc_sub_advanced_only: Out of memory!\n"));
     599           0 :                 return NULL;
     600             :         }
     601             : 
     602       64196 :         for (s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) {
     603             : 
     604        2030 :                 b = a_string;
     605             : 
     606        2030 :                 switch (*(p+1)) {
     607           0 :                 case 'N':
     608           0 :                         a_string = realloc_string_sub(a_string,
     609             :                                                       "%N",
     610             :                                                       lp_netbios_name());
     611           0 :                         break;
     612           0 :                 case 'H': {
     613             :                         char *h;
     614           0 :                         if ((h = get_user_home_dir(talloc_tos(), user)))
     615           0 :                                 a_string = realloc_string_sub(a_string, "%H", h);
     616           0 :                         TALLOC_FREE(h);
     617           0 :                         break;
     618             :                 }
     619          10 :                 case 'P': 
     620          10 :                         a_string = realloc_string_sub(a_string, "%P", connectpath); 
     621          10 :                         break;
     622           0 :                 case 'S': 
     623           0 :                         a_string = realloc_string_sub(a_string, "%S", servicename);
     624           0 :                         break;
     625           2 :                 case 'g': 
     626           2 :                         a_string = realloc_string_sub(a_string, "%g", gidtoname(gid)); 
     627           2 :                         break;
     628          36 :                 case 'u': 
     629          36 :                         a_string = realloc_string_sub(a_string, "%u", user); 
     630          36 :                         break;
     631        1982 :                 default: 
     632        1982 :                         break;
     633             :                 }
     634             : 
     635        2030 :                 p++;
     636        2030 :                 if (a_string == NULL) {
     637           0 :                         return NULL;
     638             :                 }
     639             :         }
     640             : 
     641       62166 :         return a_string;
     642             : }
     643             : 
     644       61871 : char *talloc_sub_full(TALLOC_CTX *ctx,
     645             :                         const char *servicename,
     646             :                         const char *user,
     647             :                         const char *connectpath,
     648             :                         gid_t gid,
     649             :                         const char *smb_name,
     650             :                         const char *domain_name,
     651             :                         const char *str)
     652             : {
     653             :         char *a_string, *ret_string;
     654             : 
     655       61871 :         a_string = talloc_sub_advanced(ctx, servicename, user, connectpath,
     656             :                                        gid, str);
     657       61871 :         if (a_string == NULL) {
     658           0 :                 return NULL;
     659             :         }
     660             : 
     661       61871 :         ret_string = talloc_sub_basic(ctx, smb_name, domain_name, a_string);
     662       61871 :         TALLOC_FREE(a_string);
     663       61871 :         return ret_string;
     664             : }

Generated by: LCOV version 1.13