00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024
00025 extern struct current_user current_user;
00026
00027 fstring local_machine="";
00028 fstring remote_arch="UNKNOWN";
00029 userdom_struct current_user_info;
00030 fstring remote_proto="UNKNOWN";
00031
00032 static fstring remote_machine;
00033 static fstring smb_user_name;
00034
00035
00036
00037
00038
00039
00040
00041 void set_local_machine_name(const char* local_name, BOOL perm)
00042 {
00043 static BOOL already_perm = False;
00044 fstring tmp_local_machine;
00045
00046 fstrcpy(tmp_local_machine,local_name);
00047 trim_char(tmp_local_machine,' ',' ');
00048
00049
00050
00051
00052
00053
00054 if ( strequal(tmp_local_machine, "*SMBSERVER") || strequal(tmp_local_machine, "*SMBSERV") ) {
00055 fstrcpy( local_machine, client_socket_addr() );
00056 return;
00057 }
00058
00059 if (already_perm)
00060 return;
00061
00062 already_perm = perm;
00063
00064 alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
00065 strlower_m(local_machine);
00066 }
00067
00068
00069
00070
00071
00072
00073
00074 void set_remote_machine_name(const char* remote_name, BOOL perm)
00075 {
00076 static BOOL already_perm = False;
00077 fstring tmp_remote_machine;
00078
00079 if (already_perm)
00080 return;
00081
00082 already_perm = perm;
00083
00084 fstrcpy(tmp_remote_machine,remote_name);
00085 trim_char(tmp_remote_machine,' ',' ');
00086 alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1);
00087 strlower_m(remote_machine);
00088 }
00089
00090 const char* get_remote_machine_name(void)
00091 {
00092 return remote_machine;
00093 }
00094
00095 const char* get_local_machine_name(void)
00096 {
00097 if (!*local_machine) {
00098 return global_myname();
00099 }
00100
00101 return local_machine;
00102 }
00103
00104
00105
00106
00107
00108 void sub_set_smb_name(const char *name)
00109 {
00110 fstring tmp;
00111 int len;
00112 BOOL is_machine_account = False;
00113
00114
00115 if (! *name)
00116 return;
00117
00118
00119 fstrcpy( tmp, name );
00120 trim_char( tmp, ' ', ' ' );
00121 strlower_m( tmp );
00122
00123 len = strlen( tmp );
00124
00125 if ( len == 0 )
00126 return;
00127
00128
00129
00130
00131
00132
00133 if ( tmp[len-1] == '$' )
00134 is_machine_account = True;
00135
00136 alpha_strcpy( smb_user_name, tmp, SAFE_NETBIOS_CHARS, sizeof(smb_user_name)-1 );
00137
00138 if ( is_machine_account ) {
00139 len = strlen( smb_user_name );
00140 smb_user_name[len-1] = '$';
00141 }
00142 }
00143
00144 char* sub_get_smb_name( void )
00145 {
00146 return smb_user_name;
00147 }
00148
00149
00150
00151
00152
00153
00154 void set_current_user_info(const userdom_struct *pcui)
00155 {
00156 current_user_info = *pcui;
00157
00158
00159 fstrcpy(smb_user_name, current_user_info.smb_name);
00160 }
00161
00162
00163
00164
00165
00166 const char* get_current_username( void )
00167 {
00168 if ( current_user_info.smb_name[0] == '\0' )
00169 return smb_user_name;
00170
00171 return current_user_info.smb_name;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 static char * realloc_expand_env_var(char *str, char *p)
00184 {
00185 char *envname;
00186 char *envval;
00187 char *q, *r;
00188 int copylen;
00189
00190 if (p[0] != '%' || p[1] != '$' || p[2] != '(') {
00191 return str;
00192 }
00193
00194
00195
00196
00197
00198 if ((q = strchr_m(p,')')) == NULL) {
00199 DEBUG(0,("expand_env_var: Unterminated environment variable [%s]\n", p));
00200 return str;
00201 }
00202
00203
00204
00205
00206
00207 r = p + 3;
00208 copylen = q - r;
00209
00210
00211 if ( (envname = (char *)SMB_MALLOC(copylen + 1 + 4)) == NULL ) {
00212 return NULL;
00213 }
00214
00215 strncpy(envname,r,copylen);
00216 envname[copylen] = '\0';
00217
00218 if ((envval = getenv(envname)) == NULL) {
00219 DEBUG(0,("expand_env_var: Environment variable [%s] not set\n", envname));
00220 SAFE_FREE(envname);
00221 return str;
00222 }
00223
00224
00225
00226
00227
00228
00229 copylen = q + 1 - p;
00230 strncpy(envname,p,copylen);
00231 envname[copylen] = '\0';
00232 r = realloc_string_sub(str, envname, envval);
00233 SAFE_FREE(envname);
00234
00235 return r;
00236 }
00237
00238
00239
00240
00241 static char *longvar_domainsid( void )
00242 {
00243 DOM_SID sid;
00244 char *sid_string;
00245
00246 if ( !secrets_fetch_domain_sid( lp_workgroup(), &sid ) ) {
00247 return NULL;
00248 }
00249
00250 sid_string = SMB_STRDUP( sid_string_static( &sid ) );
00251
00252 if ( !sid_string ) {
00253 DEBUG(0,("longvar_domainsid: failed to dup SID string!\n"));
00254 }
00255
00256 return sid_string;
00257 }
00258
00259
00260
00261
00262 struct api_longvar {
00263 const char *name;
00264 char* (*fn)( void );
00265 };
00266
00267 struct api_longvar longvar_table[] = {
00268 { "DomainSID", longvar_domainsid },
00269 { NULL, NULL }
00270 };
00271
00272 static char *get_longvar_val( const char *varname )
00273 {
00274 int i;
00275
00276 DEBUG(7,("get_longvar_val: expanding variable [%s]\n", varname));
00277
00278 for ( i=0; longvar_table[i].name; i++ ) {
00279 if ( strequal( longvar_table[i].name, varname ) ) {
00280 return longvar_table[i].fn();
00281 }
00282 }
00283
00284 return NULL;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293 static char *realloc_expand_longvar(char *str, char *p)
00294 {
00295 fstring varname;
00296 char *value;
00297 char *q, *r;
00298 int copylen;
00299
00300 if ( p[0] != '%' || p[1] != '(' ) {
00301 return str;
00302 }
00303
00304
00305
00306 if ((q = strchr_m(p,')')) == NULL) {
00307 DEBUG(0,("realloc_expand_longvar: Unterminated environment variable [%s]\n", p));
00308 return str;
00309 }
00310
00311
00312
00313 r = p+2;
00314 copylen = MIN( (q-r), (sizeof(varname)-1) );
00315 strncpy(varname, r, copylen);
00316 varname[copylen] = '\0';
00317
00318 if ((value = get_longvar_val(varname)) == NULL) {
00319 DEBUG(0,("realloc_expand_longvar: Variable [%s] not set. Skipping\n", varname));
00320 return str;
00321 }
00322
00323
00324
00325 copylen = MIN( (q+1-p),(sizeof(varname)-1) );
00326 strncpy( varname, p, copylen );
00327 varname[copylen] = '\0';
00328 r = realloc_string_sub(str, varname, value);
00329 SAFE_FREE( value );
00330
00331
00332
00333 return r;
00334 }
00335
00336
00337
00338
00339
00340
00341 static char *automount_path(const char *user_name)
00342 {
00343 static pstring server_path;
00344
00345
00346
00347
00348 pstrcpy(server_path, get_user_home_dir(user_name));
00349
00350 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
00351
00352 if (lp_nis_home_map()) {
00353 const char *home_path_start;
00354 const char *automount_value = automount_lookup(user_name);
00355
00356 if(strlen(automount_value) > 0) {
00357 home_path_start = strchr_m(automount_value,':');
00358 if (home_path_start != NULL) {
00359 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
00360 home_path_start?(home_path_start+1):""));
00361 pstrcpy(server_path, home_path_start+1);
00362 }
00363 } else {
00364
00365 DEBUG(5, ("NIS lookup failed. Using Home path from passwd file. Home path is: %s\n", server_path ));
00366 }
00367 }
00368 #endif
00369
00370 DEBUG(4,("Home server path: %s\n", server_path));
00371
00372 return server_path;
00373 }
00374
00375
00376
00377
00378
00379
00380
00381 static const char *automount_server(const char *user_name)
00382 {
00383 static pstring server_name;
00384 const char *local_machine_name = get_local_machine_name();
00385
00386
00387
00388 if (local_machine_name && *local_machine_name)
00389 pstrcpy(server_name, local_machine_name);
00390 else
00391 pstrcpy(server_name, global_myname());
00392
00393 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
00394
00395 if (lp_nis_home_map()) {
00396 int home_server_len;
00397 char *automount_value = automount_lookup(user_name);
00398 home_server_len = strcspn(automount_value,":");
00399 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
00400 if (home_server_len > sizeof(pstring))
00401 home_server_len = sizeof(pstring);
00402 strncpy(server_name, automount_value, home_server_len);
00403 server_name[home_server_len] = '\0';
00404 }
00405 #endif
00406
00407 DEBUG(4,("Home server: %s\n", server_name));
00408
00409 return server_name;
00410 }
00411
00412
00413
00414
00415
00416
00417
00418 void standard_sub_basic(const char *smb_name, const char *domain_name,
00419 char *str, size_t len)
00420 {
00421 char *s;
00422
00423 if ( (s = alloc_sub_basic( smb_name, domain_name, str )) != NULL ) {
00424 strncpy( str, s, len );
00425 }
00426
00427 SAFE_FREE( s );
00428
00429 }
00430
00431
00432
00433
00434
00435
00436 char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name,
00437 const char *domain_name, const char *str)
00438 {
00439 char *a, *t;
00440
00441 if ( (a = alloc_sub_basic(smb_name, domain_name, str)) == NULL ) {
00442 return NULL;
00443 }
00444 t = talloc_strdup(mem_ctx, a);
00445 SAFE_FREE(a);
00446 return t;
00447 }
00448
00449
00450
00451
00452 char *alloc_sub_basic(const char *smb_name, const char *domain_name,
00453 const char *str)
00454 {
00455 char *b, *p, *s, *r, *a_string;
00456 fstring pidstr;
00457 struct passwd *pass;
00458 const char *local_machine_name = get_local_machine_name();
00459
00460
00461
00462 if (!str) {
00463 DEBUG(0,("alloc_sub_basic: NULL source string! This should not happen\n"));
00464 return NULL;
00465 }
00466
00467 a_string = SMB_STRDUP(str);
00468 if (a_string == NULL) {
00469 DEBUG(0, ("alloc_sub_basic: Out of memory!\n"));
00470 return NULL;
00471 }
00472
00473 for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) {
00474
00475 r = NULL;
00476 b = a_string;
00477
00478 switch (*(p+1)) {
00479 case 'U' :
00480 r = strdup_lower(smb_name);
00481 if (r == NULL) {
00482 goto error;
00483 }
00484 a_string = realloc_string_sub(a_string, "%U", r);
00485 break;
00486 case 'G' :
00487 r = SMB_STRDUP(smb_name);
00488 if (r == NULL) {
00489 goto error;
00490 }
00491 if ((pass = Get_Pwnam(r))!=NULL) {
00492 a_string = realloc_string_sub(a_string, "%G", gidtoname(pass->pw_gid));
00493 }
00494 break;
00495 case 'D' :
00496 r = strdup_upper(domain_name);
00497 if (r == NULL) {
00498 goto error;
00499 }
00500 a_string = realloc_string_sub(a_string, "%D", r);
00501 break;
00502 case 'I' :
00503 a_string = realloc_string_sub(a_string, "%I", client_addr());
00504 break;
00505 case 'i':
00506 a_string = realloc_string_sub( a_string, "%i", client_socket_addr() );
00507 break;
00508 case 'L' :
00509 if ( StrnCaseCmp(p, "%LOGONSERVER%", strlen("%LOGONSERVER%")) == 0 ) {
00510 break;
00511 }
00512 if (local_machine_name && *local_machine_name) {
00513 a_string = realloc_string_sub(a_string, "%L", local_machine_name);
00514 } else {
00515 a_string = realloc_string_sub(a_string, "%L", global_myname());
00516 }
00517 break;
00518 case 'N':
00519 a_string = realloc_string_sub(a_string, "%N", automount_server(smb_name));
00520 break;
00521 case 'M' :
00522 a_string = realloc_string_sub(a_string, "%M", client_name());
00523 break;
00524 case 'R' :
00525 a_string = realloc_string_sub(a_string, "%R", remote_proto);
00526 break;
00527 case 'T' :
00528 a_string = realloc_string_sub(a_string, "%T", current_timestring(False));
00529 break;
00530 case 'a' :
00531 a_string = realloc_string_sub(a_string, "%a", remote_arch);
00532 break;
00533 case 'd' :
00534 slprintf(pidstr,sizeof(pidstr)-1, "%d",(int)sys_getpid());
00535 a_string = realloc_string_sub(a_string, "%d", pidstr);
00536 break;
00537 case 'h' :
00538 a_string = realloc_string_sub(a_string, "%h", myhostname());
00539 break;
00540 case 'm' :
00541 a_string = realloc_string_sub(a_string, "%m", remote_machine);
00542 break;
00543 case 'v' :
00544 a_string = realloc_string_sub(a_string, "%v", SAMBA_VERSION_STRING);
00545 break;
00546 case 'w' :
00547 a_string = realloc_string_sub(a_string, "%w", lp_winbind_separator());
00548 break;
00549 case '$' :
00550 a_string = realloc_expand_env_var(a_string, p);
00551 break;
00552 case '(':
00553 a_string = realloc_expand_longvar( a_string, p );
00554 break;
00555 default:
00556 break;
00557 }
00558
00559 p++;
00560 SAFE_FREE(r);
00561
00562 if ( !a_string ) {
00563 return NULL;
00564 }
00565 }
00566
00567 return a_string;
00568
00569 error:
00570 SAFE_FREE(a_string);
00571 return NULL;
00572 }
00573
00574
00575
00576
00577
00578
00579 char *talloc_sub_specified(TALLOC_CTX *mem_ctx,
00580 const char *input_string,
00581 const char *username,
00582 const char *domain,
00583 uid_t uid,
00584 gid_t gid)
00585 {
00586 char *a_string;
00587 char *ret_string = NULL;
00588 char *b, *p, *s;
00589 TALLOC_CTX *tmp_ctx;
00590
00591 if (!(tmp_ctx = talloc_new(mem_ctx))) {
00592 DEBUG(0, ("talloc_new failed\n"));
00593 return NULL;
00594 }
00595
00596 a_string = talloc_strdup(tmp_ctx, input_string);
00597 if (a_string == NULL) {
00598 DEBUG(0, ("talloc_sub_specified: Out of memory!\n"));
00599 goto done;
00600 }
00601
00602 for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) {
00603
00604 b = a_string;
00605
00606 switch (*(p+1)) {
00607 case 'U' :
00608 a_string = talloc_string_sub(
00609 tmp_ctx, a_string, "%U", username);
00610 break;
00611 case 'u' :
00612 a_string = talloc_string_sub(
00613 tmp_ctx, a_string, "%u", username);
00614 break;
00615 case 'G' :
00616 if (gid != -1) {
00617 a_string = talloc_string_sub(
00618 tmp_ctx, a_string, "%G",
00619 gidtoname(gid));
00620 } else {
00621 a_string = talloc_string_sub(
00622 tmp_ctx, a_string,
00623 "%G", "NO_GROUP");
00624 }
00625 break;
00626 case 'g' :
00627 if (gid != -1) {
00628 a_string = talloc_string_sub(
00629 tmp_ctx, a_string, "%g",
00630 gidtoname(gid));
00631 } else {
00632 a_string = talloc_string_sub(
00633 tmp_ctx, a_string, "%g", "NO_GROUP");
00634 }
00635 break;
00636 case 'D' :
00637 a_string = talloc_string_sub(tmp_ctx, a_string,
00638 "%D", domain);
00639 break;
00640 case 'N' :
00641 a_string = talloc_string_sub(
00642 tmp_ctx, a_string, "%N",
00643 automount_server(username));
00644 break;
00645 default:
00646 break;
00647 }
00648
00649 p++;
00650 if (a_string == NULL) {
00651 goto done;
00652 }
00653 }
00654
00655
00656
00657
00658 ret_string = talloc_sub_basic(mem_ctx, username, domain, a_string);
00659
00660 done:
00661 TALLOC_FREE(tmp_ctx);
00662 return ret_string;
00663 }
00664
00665
00666
00667
00668 static char *alloc_sub_advanced(const char *servicename, const char *user,
00669 const char *connectpath, gid_t gid,
00670 const char *smb_name, const char *domain_name,
00671 const char *str)
00672 {
00673 char *a_string, *ret_string;
00674 char *b, *p, *s, *h;
00675
00676 a_string = SMB_STRDUP(str);
00677 if (a_string == NULL) {
00678 DEBUG(0, ("alloc_sub_advanced: Out of memory!\n"));
00679 return NULL;
00680 }
00681
00682 for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) {
00683
00684 b = a_string;
00685
00686 switch (*(p+1)) {
00687 case 'N' :
00688 a_string = realloc_string_sub(a_string, "%N", automount_server(user));
00689 break;
00690 case 'H':
00691 if ((h = get_user_home_dir(user)))
00692 a_string = realloc_string_sub(a_string, "%H", h);
00693 break;
00694 case 'P':
00695 a_string = realloc_string_sub(a_string, "%P", connectpath);
00696 break;
00697 case 'S':
00698 a_string = realloc_string_sub(a_string, "%S", servicename);
00699 break;
00700 case 'g':
00701 a_string = realloc_string_sub(a_string, "%g", gidtoname(gid));
00702 break;
00703 case 'u':
00704 a_string = realloc_string_sub(a_string, "%u", user);
00705 break;
00706
00707
00708
00709
00710
00711
00712
00713
00714 case 'p':
00715 a_string = realloc_string_sub(a_string, "%p",
00716 automount_path(servicename));
00717 break;
00718
00719 default:
00720 break;
00721 }
00722
00723 p++;
00724 if (a_string == NULL) {
00725 return NULL;
00726 }
00727 }
00728
00729 ret_string = alloc_sub_basic(smb_name, domain_name, a_string);
00730 SAFE_FREE(a_string);
00731 return ret_string;
00732 }
00733
00734
00735
00736
00737
00738
00739 char *talloc_sub_advanced(TALLOC_CTX *mem_ctx,
00740 const char *servicename, const char *user,
00741 const char *connectpath, gid_t gid,
00742 const char *smb_name, const char *domain_name,
00743 const char *str)
00744 {
00745 char *a, *t;
00746
00747 if (!(a = alloc_sub_advanced(servicename, user, connectpath, gid,
00748 smb_name, domain_name, str))) {
00749 return NULL;
00750 }
00751 t = talloc_strdup(mem_ctx, a);
00752 SAFE_FREE(a);
00753 return t;
00754 }
00755
00756
00757 void standard_sub_advanced(const char *servicename, const char *user,
00758 const char *connectpath, gid_t gid,
00759 const char *smb_name, const char *domain_name,
00760 char *str, size_t len)
00761 {
00762 char *s;
00763
00764 s = alloc_sub_advanced(servicename, user, connectpath,
00765 gid, smb_name, domain_name, str);
00766
00767 if ( s ) {
00768 strncpy( str, s, len );
00769 SAFE_FREE( s );
00770 }
00771 }
00772
00773
00774
00775
00776
00777 void standard_sub_conn(connection_struct *conn, char *str, size_t len)
00778 {
00779 char *s;
00780
00781 s = alloc_sub_advanced(lp_servicename(SNUM(conn)), conn->user, conn->connectpath,
00782 conn->gid, smb_user_name, "", str);
00783
00784 if ( s ) {
00785 strncpy( str, s, len );
00786 SAFE_FREE( s );
00787 }
00788 }
00789