mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r14075: * add support for long variable names in smb.conf in the form of %(....)
* add support for %(DomainSID)
* replace standard_sub_XXX() functions with wrappers around their
alloc_sub_XXX() counterparts
* add support for using SIDs in read list, et. al. (anything that
is checked by nt_token_contains_name_in_list())
(This used to be commit 71d960250d
)
This commit is contained in:
parent
e11a85eebd
commit
9f18298bee
@ -635,7 +635,8 @@ EVTLOGADM_OBJ0 = utils/eventlogadm.o
|
||||
|
||||
EVTLOGADM_OBJ = $(EVTLOGADM_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(REGOBJS_OBJ) \
|
||||
$(ERRORMAP_OBJ) $(RPC_PARSE_OBJ1) $(LIBSAMBA_OBJ) $(DOSERR_OBJ) \
|
||||
registry/reg_eventlog.o rpc_server/srv_eventlog_lib.o registry/reg_util.o \
|
||||
$(SECRETS_OBJ) \
|
||||
registry/reg_eventlog.o rpc_server/srv_eventlog_lib.o registry/reg_util.o \
|
||||
registry/reg_db.o
|
||||
|
||||
TALLOCTORT_OBJ = lib/talloctort.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
|
||||
|
@ -2,6 +2,7 @@
|
||||
Unix SMB/CIFS implementation.
|
||||
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
|
||||
@ -170,61 +171,6 @@ const char* get_current_username( void )
|
||||
return current_user_info.smb_name;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Given a pointer to a %$(NAME) expand it as an environment variable.
|
||||
Return the number of characters by which the pointer should be advanced.
|
||||
Based on code by Branko Cibej <branko.cibej@hermes.si>
|
||||
When this is called p points at the '%' character.
|
||||
********************************************************************/
|
||||
|
||||
static size_t expand_env_var(char *p, int len)
|
||||
{
|
||||
fstring envname;
|
||||
char *envval;
|
||||
char *q, *r;
|
||||
int copylen;
|
||||
|
||||
if (p[1] != '$')
|
||||
return 1;
|
||||
|
||||
if (p[2] != '(')
|
||||
return 2;
|
||||
|
||||
/*
|
||||
* Look for the terminating ')'.
|
||||
*/
|
||||
|
||||
if ((q = strchr_m(p,')')) == NULL) {
|
||||
DEBUG(0,("expand_env_var: Unterminated environment variable [%s]\n", p));
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the name from within the %$(NAME) string.
|
||||
*/
|
||||
|
||||
r = p+3;
|
||||
copylen = MIN((q-r),(sizeof(envname)-1));
|
||||
strncpy(envname,r,copylen);
|
||||
envname[copylen] = '\0';
|
||||
|
||||
if ((envval = getenv(envname)) == NULL) {
|
||||
DEBUG(0,("expand_env_var: Environment variable [%s] not set\n", envname));
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the full %$(NAME) into envname so it
|
||||
* can be replaced.
|
||||
*/
|
||||
|
||||
copylen = MIN((q+1-p),(sizeof(envname)-1));
|
||||
strncpy(envname,p,copylen);
|
||||
envname[copylen] = '\0';
|
||||
string_sub(p,envname,envval,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.
|
||||
@ -234,7 +180,6 @@ static size_t expand_env_var(char *p, int len)
|
||||
May substitute multiple occurrencies of the same env var.
|
||||
********************************************************************/
|
||||
|
||||
|
||||
static char * realloc_expand_env_var(char *str, char *p)
|
||||
{
|
||||
char *envname;
|
||||
@ -242,8 +187,9 @@ static char * realloc_expand_env_var(char *str, char *p)
|
||||
char *q, *r;
|
||||
int copylen;
|
||||
|
||||
if (p[0] != '%' || p[1] != '$' || p[2] != '(')
|
||||
if (p[0] != '%' || p[1] != '$' || p[2] != '(') {
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for the terminating ')'.
|
||||
@ -260,8 +206,12 @@ static char * realloc_expand_env_var(char *str, char *p)
|
||||
|
||||
r = p + 3;
|
||||
copylen = q - r;
|
||||
envname = (char *)SMB_MALLOC(copylen + 1 + 4); /* reserve space for use later add %$() chars */
|
||||
if (envname == NULL) return NULL;
|
||||
|
||||
/* 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';
|
||||
|
||||
@ -281,7 +231,105 @@ static char * realloc_expand_env_var(char *str, char *p)
|
||||
envname[copylen] = '\0';
|
||||
r = realloc_string_sub(str, envname, envval);
|
||||
SAFE_FREE(envname);
|
||||
if (r == NULL) return NULL;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*******************************************************************/
|
||||
|
||||
static char *longvar_domainsid( void )
|
||||
{
|
||||
DOM_SID sid;
|
||||
char *sid_string;
|
||||
|
||||
if ( !secrets_fetch_domain_sid( lp_workgroup(), &sid ) ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sid_string = SMB_STRDUP( sid_string_static( &sid ) );
|
||||
|
||||
if ( !sid_string ) {
|
||||
DEBUG(0,("longvar_domainsid: failed to dup SID string!\n"));
|
||||
}
|
||||
|
||||
return sid_string;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
*******************************************************************/
|
||||
|
||||
struct api_longvar {
|
||||
const char *name;
|
||||
char* (*fn)( void );
|
||||
};
|
||||
|
||||
struct api_longvar longvar_table[] = {
|
||||
{ "DomainSID", longvar_domainsid },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Expand the long smb.conf variable names given a pointer to a %(NAME).
|
||||
Return the number of characters by which the pointer should be advanced.
|
||||
When this is called p points at the '%' character.
|
||||
********************************************************************/
|
||||
|
||||
static char *realloc_expand_longvar(char *str, char *p)
|
||||
{
|
||||
fstring varname;
|
||||
char *value;
|
||||
char *q, *r;
|
||||
int copylen;
|
||||
|
||||
if ( p[0] != '%' || p[1] != '(' ) {
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Look for the terminating ')'.*/
|
||||
|
||||
if ((q = strchr_m(p,')')) == NULL) {
|
||||
DEBUG(0,("realloc_expand_longvar: Unterminated environment variable [%s]\n", p));
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Extract the name from within the %(NAME) string.*/
|
||||
|
||||
r = p+2;
|
||||
copylen = MIN( (q-r), (sizeof(varname)-1) );
|
||||
strncpy(varname, r, copylen);
|
||||
varname[copylen] = '\0';
|
||||
|
||||
if ((value = get_longvar_val(varname)) == NULL) {
|
||||
DEBUG(0,("realloc_expand_longvar: Variable [%s] not set. Skipping\n", varname));
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Copy the full %(NAME) into envname so it can be replaced.*/
|
||||
|
||||
copylen = MIN( (q+1-p),(sizeof(varname)-1) );
|
||||
strncpy( varname, p, copylen );
|
||||
varname[copylen] = '\0';
|
||||
r = realloc_string_sub(str, varname, value);
|
||||
SAFE_FREE( value );
|
||||
|
||||
/* skip over the %(varname) */
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -367,160 +415,16 @@ static const char *automount_server(const char *user_name)
|
||||
don't allow expansions.
|
||||
****************************************************************************/
|
||||
|
||||
void standard_sub_basic(const char *smb_name, char *str,size_t len)
|
||||
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;
|
||||
|
||||
int l = (int)len - (int)(p-str);
|
||||
|
||||
if (l < 0)
|
||||
l = 0;
|
||||
|
||||
switch (*(p+1)) {
|
||||
case 'U' :
|
||||
fstrcpy(tmp_str, smb_name);
|
||||
strlower_m(tmp_str);
|
||||
string_sub(p,"%U",tmp_str,l);
|
||||
break;
|
||||
case 'G' :
|
||||
fstrcpy(tmp_str, smb_name);
|
||||
if ((pass = Get_Pwnam(tmp_str))!=NULL) {
|
||||
string_sub(p,"%G",gidtoname(pass->pw_gid),l);
|
||||
} else {
|
||||
p += 2;
|
||||
}
|
||||
break;
|
||||
case 'D' :
|
||||
fstrcpy(tmp_str, current_user_info.domain);
|
||||
strupper_m(tmp_str);
|
||||
string_sub(p,"%D", tmp_str,l);
|
||||
break;
|
||||
case 'I' :
|
||||
string_sub(p,"%I", client_addr(),l);
|
||||
break;
|
||||
case 'i' :
|
||||
string_sub(p,"%i", client_socket_addr(),l);
|
||||
break;
|
||||
case 'L' :
|
||||
if (!StrnCaseCmp(p, "%LOGONSERVER%", strlen("%LOGONSERVER%"))) {
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (local_machine_name && *local_machine_name) {
|
||||
string_sub_once(p, "%L", local_machine_name, l);
|
||||
} else {
|
||||
pstring temp_name;
|
||||
|
||||
pstrcpy(temp_name, global_myname());
|
||||
strlower_m(temp_name);
|
||||
string_sub_once(p, "%L", temp_name, l);
|
||||
}
|
||||
break;
|
||||
case 'M' :
|
||||
string_sub(p,"%M", client_name(),l);
|
||||
break;
|
||||
case 'R' :
|
||||
string_sub(p,"%R", remote_proto,l);
|
||||
break;
|
||||
case 'T' :
|
||||
string_sub(p,"%T", timestring(False),l);
|
||||
break;
|
||||
case 'a' :
|
||||
string_sub(p,"%a", remote_arch,l);
|
||||
break;
|
||||
case 'd' :
|
||||
slprintf(pidstr,sizeof(pidstr)-1, "%d",(int)sys_getpid());
|
||||
string_sub(p,"%d", pidstr,l);
|
||||
break;
|
||||
case 'h' :
|
||||
string_sub(p,"%h", myhostname(),l);
|
||||
break;
|
||||
case 'm' :
|
||||
string_sub(p,"%m", get_remote_machine_name(),l);
|
||||
break;
|
||||
case 'v' :
|
||||
string_sub(p,"%v", SAMBA_VERSION_STRING,l);
|
||||
break;
|
||||
case 'w' :
|
||||
string_sub(p,"%w", lp_winbind_separator(),l);
|
||||
break;
|
||||
case '$' :
|
||||
p += expand_env_var(p,l);
|
||||
break; /* Expand environment variables */
|
||||
case '\0':
|
||||
p++;
|
||||
break; /* don't run off the end of the string */
|
||||
|
||||
default: p+=2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
char *p, *s, *home;
|
||||
|
||||
for (s=str; (p=strchr_m(s, '%'));s=p) {
|
||||
int l = (int)len - (int)(p-str);
|
||||
char *s;
|
||||
|
||||
if (l < 0)
|
||||
l = 0;
|
||||
|
||||
switch (*(p+1)) {
|
||||
case 'N' :
|
||||
string_sub(p,"%N", automount_server(user),l);
|
||||
break;
|
||||
case 'H':
|
||||
if ((home = get_user_home_dir(user)))
|
||||
string_sub(p,"%H",home, l);
|
||||
else
|
||||
p += 2;
|
||||
break;
|
||||
case 'P':
|
||||
string_sub(p,"%P", connectpath, l);
|
||||
break;
|
||||
case 'S':
|
||||
if ( snum != -1 )
|
||||
string_sub(p,"%S", lp_servicename(snum), l);
|
||||
break;
|
||||
case 'g':
|
||||
string_sub(p,"%g", gidtoname(gid), l);
|
||||
break;
|
||||
case 'u':
|
||||
string_sub(p,"%u", user, l);
|
||||
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
|
||||
* 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':
|
||||
if ( snum != -1 )
|
||||
string_sub(p,"%p", automount_path(lp_servicename(snum)), l);
|
||||
break;
|
||||
case '\0':
|
||||
p++;
|
||||
break; /* don't run off the end of the string */
|
||||
|
||||
default: p+=2;
|
||||
break;
|
||||
}
|
||||
if ( (s = alloc_sub_basic( smb_name, str )) != NULL ) {
|
||||
strncpy( str, s, len );
|
||||
}
|
||||
|
||||
standard_sub_basic(smb_name, str, len);
|
||||
|
||||
SAFE_FREE( s );
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -531,8 +435,8 @@ static void standard_sub_advanced(int snum, const char *user,
|
||||
char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, const char *str)
|
||||
{
|
||||
char *a, *t;
|
||||
a = alloc_sub_basic(smb_name, str);
|
||||
if (!a) {
|
||||
|
||||
if ( (a = alloc_sub_basic(smb_name, str)) == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
t = talloc_strdup(mem_ctx, a);
|
||||
@ -540,6 +444,9 @@ char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, const char *st
|
||||
return t;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
|
||||
char *alloc_sub_basic(const char *smb_name, const char *str)
|
||||
{
|
||||
char *b, *p, *s, *r, *a_string;
|
||||
@ -592,7 +499,13 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
|
||||
case 'I' :
|
||||
a_string = realloc_string_sub(a_string, "%I", client_addr());
|
||||
break;
|
||||
case 'i':
|
||||
a_string = realloc_string_sub( a_string, "%i", client_socket_addr() );
|
||||
break;
|
||||
case 'L' :
|
||||
if ( StrnCaseCmp(p, "%LOGONSERVER%", strlen("%LOGONSERVER%")) == 0 ) {
|
||||
break;
|
||||
}
|
||||
if (local_machine_name && *local_machine_name) {
|
||||
a_string = realloc_string_sub(a_string, "%L", local_machine_name);
|
||||
} else {
|
||||
@ -633,14 +546,17 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
|
||||
case '$' :
|
||||
a_string = realloc_expand_env_var(a_string, p); /* Expand environment variables */
|
||||
break;
|
||||
|
||||
case '(':
|
||||
a_string = realloc_expand_longvar( a_string, p );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
p++;
|
||||
SAFE_FREE(r);
|
||||
if (a_string == NULL) {
|
||||
|
||||
if ( !a_string ) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -674,6 +590,9 @@ char *talloc_sub_specified(TALLOC_CTX *mem_ctx,
|
||||
return t;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
|
||||
char *alloc_sub_specified(const char *input_string,
|
||||
const char *username,
|
||||
const char *domain,
|
||||
@ -735,6 +654,9 @@ char *alloc_sub_specified(const char *input_string,
|
||||
return ret_string;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
|
||||
char *talloc_sub_advanced(TALLOC_CTX *mem_ctx,
|
||||
int snum,
|
||||
const char *user,
|
||||
@ -753,6 +675,9 @@ char *talloc_sub_advanced(TALLOC_CTX *mem_ctx,
|
||||
return t;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
|
||||
char *alloc_sub_advanced(int snum, const char *user,
|
||||
const char *connectpath, gid_t gid,
|
||||
const char *smb_name, const char *str)
|
||||
@ -823,10 +748,20 @@ char *alloc_sub_advanced(int snum, const char *user,
|
||||
|
||||
void standard_sub_conn(connection_struct *conn, char *str, size_t len)
|
||||
{
|
||||
standard_sub_advanced(SNUM(conn), conn->user, conn->connectpath,
|
||||
conn->gid, smb_user_name, str, len);
|
||||
char *s;
|
||||
|
||||
s = alloc_sub_advanced(SNUM(conn), conn->user, conn->connectpath,
|
||||
conn->gid, smb_user_name, str);
|
||||
|
||||
if ( s ) {
|
||||
strncpy( str, s, len );
|
||||
SAFE_FREE( s );
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
|
||||
char *talloc_sub_conn(TALLOC_CTX *mem_ctx, connection_struct *conn, const char *str)
|
||||
{
|
||||
return talloc_sub_advanced(mem_ctx, SNUM(conn), conn->user,
|
||||
@ -834,6 +769,9 @@ char *talloc_sub_conn(TALLOC_CTX *mem_ctx, connection_struct *conn, const char *
|
||||
smb_user_name, str);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
|
||||
char *alloc_sub_conn(connection_struct *conn, const char *str)
|
||||
{
|
||||
return alloc_sub_advanced(SNUM(conn), conn->user, conn->connectpath,
|
||||
@ -848,6 +786,8 @@ void standard_sub_snum(int snum, char *str, size_t len)
|
||||
{
|
||||
static uid_t cached_uid = -1;
|
||||
static fstring cached_user;
|
||||
char *s;
|
||||
|
||||
/* calling uidtoname() on every substitute would be too expensive, so
|
||||
we cache the result here as nearly every call is for the same uid */
|
||||
|
||||
@ -856,6 +796,11 @@ void standard_sub_snum(int snum, char *str, size_t len)
|
||||
cached_uid = current_user.ut.uid;
|
||||
}
|
||||
|
||||
standard_sub_advanced(snum, cached_user, "", current_user.ut.gid,
|
||||
smb_user_name, str, len);
|
||||
s = alloc_sub_advanced(snum, cached_user, "", current_user.ut.gid,
|
||||
smb_user_name, str);
|
||||
|
||||
if ( s ) {
|
||||
strncpy( str, s, len );
|
||||
SAFE_FREE( s );
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +85,13 @@ static BOOL token_contains_name(TALLOC_CTX *mem_ctx,
|
||||
* result that might be interpreted in a wrong way. */
|
||||
smb_panic("substitutions failed\n");
|
||||
}
|
||||
|
||||
/* check to see is we already have a SID */
|
||||
|
||||
if ( string_to_sid( &sid, name ) ) {
|
||||
DEBUG(5,("token_contains_name: Checking for SID [%s] in token\n", name));
|
||||
return nt_token_check_sid( &sid, token );
|
||||
}
|
||||
|
||||
if (!do_group_checks(&name, &prefix)) {
|
||||
if (!lookup_name(mem_ctx, name, LOOKUP_NAME_ALL,
|
||||
@ -153,14 +160,12 @@ BOOL token_contains_name_in_list(const char *username,
|
||||
return False;
|
||||
}
|
||||
|
||||
mem_ctx = talloc_new(NULL);
|
||||
if (mem_ctx == NULL) {
|
||||
if ( (mem_ctx = talloc_new(NULL)) == NULL ) {
|
||||
smb_panic("talloc_new failed\n");
|
||||
}
|
||||
|
||||
while (*list != NULL) {
|
||||
if (token_contains_name(mem_ctx, username, sharename,
|
||||
token, *list)) {
|
||||
if (token_contains_name(mem_ctx, username, sharename,token, *list)) {
|
||||
TALLOC_FREE(mem_ctx);
|
||||
return True;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user