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:
parent
66f6ad9729
commit
4d6b6eb94a
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user