1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

lib/system.c: Fix for pw caching.

srv_samr.c: Fix for pw caching.
smbd/nttrans.c: Fix to allow trans create to set ACL on open.
Jeremy.
(This used to be commit c4f810a758)
This commit is contained in:
Jeremy Allison 2001-01-31 05:14:31 +00:00
parent 66f6ad9729
commit 4d6b6eb94a
5 changed files with 141 additions and 64 deletions

View File

@ -649,6 +649,9 @@ void sys_srandom(unsigned int seed);
int groups_max(void);
int sys_getgroups(int setlen, gid_t *gidset);
int sys_setgroups(int setlen, gid_t *gidset);
void sys_setpwent(void);
struct passwd *sys_getpwent(void);
void sys_endpwent(void);
struct passwd *sys_getpwnam(const char *name);
struct passwd *sys_getpwuid(uid_t uid);
int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf);

View File

@ -73,6 +73,8 @@
#define DACL_SECURITY_INFORMATION 0x00000004
#define SACL_SECURITY_INFORMATION 0x00000008
#define ALL_SECURITY_INFORMATION (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|\
DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION)
#ifndef _SEC_ACCESS
/* SEC_ACCESS */

View File

@ -611,20 +611,47 @@ static struct passwd *setup_pwret(struct passwd *pass)
getpw[nam|uid]() call. Patch by "Richard Bollinger"
<rabollinger@home.com> */
/*
* This next static pointer is used to cache the results
* from the real getpwXX calls. It is never returned to
* the caller, only the output from calling setup_pwret with
* this is returned. JRA.
*/
static struct passwd *sv_pw_ret; /* implicitly initialized to NULL */
static int num_lookups; /* Counter so we don't always use cache. */
#ifndef PW_RET_CACHE_MAX_LOOKUPS
#define PW_RET_CACHE_MAX_LOOKUPS 100
#endif
/**************************************************************************
Wrappers for setpwent(), getpwent() and endpwent()
****************************************************************************/
void sys_setpwent(void)
{
sv_pw_ret = NULL;
setpwent();
}
struct passwd *sys_getpwent(void)
{
sv_pw_ret = getpwent();
return setup_pwret(sv_pw_ret);
}
void sys_endpwent(void)
{
sv_pw_ret = NULL;
endpwent();
}
/**************************************************************************
Wrapper for getpwnam(). Always returns a static that can be modified.
****************************************************************************/
struct passwd *sys_getpwnam(const char *name)
{
struct passwd *pw_ret;
if (!name || !name[0])
return NULL;
@ -634,17 +661,17 @@ struct passwd *sys_getpwnam(const char *name)
DEBUG(2,("getpwnam(%s) avoided - using cached results\n",name));
num_lookups++;
num_lookups = (num_lookups % PW_RET_CACHE_MAX_LOOKUPS);
return sv_pw_ret;
return setup_pwret(sv_pw_ret);
}
/* no cache hit--use old lookup instead */
DEBUG(2,("getpwnam(%s) called\n",name));
if (!(pw_ret = getpwnam(name)))
return NULL;
num_lookups = 1;
return (sv_pw_ret = setup_pwret(pw_ret));
sv_pw_ret = getpwnam(name);
return setup_pwret(sv_pw_ret);
}
/**************************************************************************
@ -653,23 +680,21 @@ struct passwd *sys_getpwnam(const char *name)
struct passwd *sys_getpwuid(uid_t uid)
{
struct passwd *pw_ret;
if (num_lookups && sv_pw_ret && (uid == sv_pw_ret->pw_uid))
{
DEBUG(2,("getpwuid(%d) avoided - using cached results\n",uid));
num_lookups++;
num_lookups = (num_lookups % PW_RET_CACHE_MAX_LOOKUPS);
return sv_pw_ret;
return setup_pwret(sv_pw_ret);
}
DEBUG(2,("getpwuid(%d) called\n",uid));
if (!(pw_ret = getpwuid(uid)))
return NULL;
num_lookups = 1;
return (sv_pw_ret = setup_pwret(pw_ret));
sv_pw_ret = getpwuid(uid);
return setup_pwret(sv_pw_ret);
}
/**************************************************************************

View File

@ -217,7 +217,7 @@ static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
if (pw_buf == NULL) return False;
if (current_idx == 0) {
setpwent();
sys_setpwent();
}
/* These two cases are inefficient, but should be called very rarely */
@ -230,7 +230,7 @@ static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
char *unmap_name;
if(!orig_done) {
if ((pwd = getpwent()) == NULL) break;
if ((pwd = sys_getpwent()) == NULL) break;
current_idx++;
orig_done = True;
}
@ -248,8 +248,8 @@ static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
}
} else if (start_idx < current_idx) {
/* We are already too far; start over and advance to start_idx */
endpwent();
setpwent();
sys_endpwent();
sys_setpwent();
current_idx = 0;
mapped_idx = 0;
orig_done = False;
@ -257,7 +257,7 @@ static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
char *unmap_name;
if(!orig_done) {
if ((pwd = getpwent()) == NULL) break;
if ((pwd = sys_getpwent()) == NULL) break;
current_idx++;
orig_done = True;
}
@ -284,7 +284,7 @@ static BOOL get_passwd_entries(SAM_USER_INFO_21 *pw_buf,
/* This does the original UNIX user itself */
if(!orig_done) {
if ((pwd = getpwent()) == NULL) break;
if ((pwd = sys_getpwent()) == NULL) break;
/* Don't enumerate winbind users as they are not local */

View File

@ -1057,6 +1057,77 @@ static int do_nt_transact_create_pipe( connection_struct *conn,
return -1;
}
/****************************************************************************
Internal fn to set security descriptors.
****************************************************************************/
static BOOL set_sd(files_struct *fsp, char *data, uint32 sd_len, uint security_info_sent, int *pdef_class,uint32 *pdef_code)
{
prs_struct pd;
SEC_DESC *psd = NULL;
TALLOC_CTX *mem_ctx;
BOOL ret;
if (sd_len == 0) {
*pdef_class = ERRDOS;
*pdef_code = ERRbadaccess;
return False;
}
/*
* Init the parse struct we will unmarshall from.
*/
if ((mem_ctx = talloc_init()) == NULL) {
DEBUG(0,("set_sd: talloc_init failed.\n"));
*pdef_class = ERRDOS;
*pdef_code = ERRnomem;
return False;
}
prs_init(&pd, 0, 4, mem_ctx, UNMARSHALL);
/*
* Setup the prs_struct to point at the memory we just
* allocated.
*/
prs_give_memory( &pd, data, sd_len, False);
/*
* Finally, unmarshall from the data buffer.
*/
if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
free_sec_desc(&psd);
DEBUG(0,("set_sd: Error in unmarshalling security descriptor.\n"));
/*
* Return access denied for want of a better error message..
*/
talloc_destroy(mem_ctx);
*pdef_class = ERRDOS;
*pdef_code = ERRnomem;
return False;
}
ret = set_nt_acl( fsp, security_info_sent, psd);
if (!ret) {
free_sec_desc(&psd);
talloc_destroy(mem_ctx);
*pdef_class = ERRDOS;
*pdef_code = ERRnoaccess;
return False;
}
free_sec_desc(&psd);
talloc_destroy(mem_ctx);
*pdef_class = 0;
*pdef_code = 0;
return True;
}
/****************************************************************************
Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
****************************************************************************/
@ -1068,6 +1139,7 @@ static int call_nt_transact_create(connection_struct *conn,
{
pstring fname;
char *params = *ppparams;
char *data = *ppdata;
int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
/* Breakout the oplock request bits so we can set the
reply bits separately. */
@ -1088,10 +1160,13 @@ static int call_nt_transact_create(connection_struct *conn,
uint32 create_disposition;
uint32 create_options;
uint32 fname_len;
uint32 sd_len;
uint16 root_dir_fid;
int smb_ofun;
int smb_open_mode;
int smb_attr;
int error_class;
uint32 error_code;
DEBUG(5,("call_nt_transact_create\n"));
@ -1122,6 +1197,7 @@ static int call_nt_transact_create(connection_struct *conn,
share_access = IVAL(params,24);
create_disposition = IVAL(params,28);
create_options = IVAL(params,32);
sd_len = IVAL(params,36);
fname_len = MIN(((uint32)IVAL(params,44)),((uint32)sizeof(fname)-1));
root_dir_fid = (uint16)IVAL(params,4);
smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
@ -1336,6 +1412,16 @@ static int call_nt_transact_create(connection_struct *conn,
smb_action |= EXTENDED_OPLOCK_GRANTED;
}
/*
* Now try and apply the desired SD.
*/
if (!set_sd( fsp, data, sd_len, ALL_SECURITY_INFORMATION, &error_class, &error_code)) {
close_file(fsp,False);
restore_case_semantics(file_attributes);
return(ERROR(error_class, error_code));
}
restore_case_semantics(file_attributes);
/* Realloc the size of parameters and data we will return */
@ -1621,13 +1707,11 @@ static int call_nt_transact_set_security_desc(connection_struct *conn,
uint32 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
char *params= *ppparams;
char *data = *ppdata;
prs_struct pd;
SEC_DESC *psd = NULL;
uint32 total_data_count = (uint32)IVAL(inbuf, smb_nts_TotalDataCount);
files_struct *fsp = NULL;
uint32 security_info_sent = 0;
TALLOC_CTX *mem_ctx;
BOOL ret;
int error_class;
uint32 error_code;
if(!lp_nt_acl_support())
return(UNIXERROR(ERRDOS,ERRnoaccess));
@ -1643,49 +1727,9 @@ static int call_nt_transact_set_security_desc(connection_struct *conn,
DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
(unsigned int)security_info_sent ));
/*
* Init the parse struct we will unmarshall from.
*/
if (!set_sd( fsp, data, total_data_count, security_info_sent, &error_class, &error_code))
return (ERROR(error_class, error_code));
if ((mem_ctx = talloc_init()) == NULL) {
DEBUG(0,("call_nt_transact_query_security_desc: talloc_init failed.\n"));
return(ERROR(ERRDOS,ERRnomem));
}
prs_init(&pd, 0, 4, mem_ctx, UNMARSHALL);
/*
* Setup the prs_struct to point at the memory we just
* allocated.
*/
prs_give_memory( &pd, data, total_data_count, False);
/*
* Finally, unmarshall from the data buffer.
*/
if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
free_sec_desc(&psd);
DEBUG(0,("call_nt_transact_set_security_desc: Error in unmarshalling \
security descriptor.\n"));
/*
* Return access denied for want of a better error message..
*/
talloc_destroy(mem_ctx);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
ret = set_nt_acl( fsp, security_info_sent, psd);
if (!ret) {
free_sec_desc(&psd);
talloc_destroy(mem_ctx);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
free_sec_desc(&psd);
talloc_destroy(mem_ctx);
send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
return -1;
}
@ -1774,6 +1818,9 @@ due to being in oplock break state.\n" ));
if ((total_parameter_count && !params) || (total_data_count && !data) ||
(setup_count && !setup)) {
safe_free(setup);
safe_free(params);
safe_free(data);
DEBUG(0,("reply_nttrans : Out of memory\n"));
END_PROFILE(SMBnttrans);
return(ERROR(ERRDOS,ERRnomem));