summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2003-05-29 23:49:31 +0000
committerJeremy Allison <jra@samba.org>2003-05-29 23:49:31 +0000
commit545e8d499947fec55832352d741e8a904122d564 (patch)
treed34f5f33168c1ba3237e0a954f9e199f888060f1 /source3/smbd
parentc76ecf6bad492af9822874fde3ff733be366d14a (diff)
downloadsamba-545e8d499947fec55832352d741e8a904122d564.tar.gz
samba-545e8d499947fec55832352d741e8a904122d564.tar.bz2
samba-545e8d499947fec55832352d741e8a904122d564.zip
Change get_nt_acl() to include security_info wanted. Only return this.
This gets us closer to W2k+ in what we return for file ACLs. Fix horribly broken make_sec_desc() that screwed up the size when given a SD with no owner or group (how did it get this bad... ?). Jeremy. (This used to be commit 183c9ed4052ab14e269ed1234ca557053f77e77a)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/dir.c6
-rw-r--r--source3/smbd/nttrans.c194
-rw-r--r--source3/smbd/posix_acls.c283
-rw-r--r--source3/smbd/vfs-wrap.c8
4 files changed, 256 insertions, 235 deletions
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 910ab35de8..94b605ee8f 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -715,7 +715,8 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
return False;
/* Get NT ACL -allocated in main loop talloc context. No free needed here. */
- sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, &psd);
+ sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd,
+ (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
close_file(fsp, True);
/* No access if SD get failed. */
@@ -768,7 +769,8 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
return False;
/* Get NT ACL -allocated in main loop talloc context. No free needed here. */
- sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, &psd);
+ sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd,
+ (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
close_file(fsp, False);
/* No access if SD get failed. */
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index d0066c367c..fa7b78ecc2 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -964,13 +964,12 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
Reply to a NT_TRANSACT_CREATE call to open a pipe.
****************************************************************************/
-static int do_nt_transact_create_pipe( connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize, char **ppsetup, char **ppparams,
- char **ppdata)
+static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
pstring fname;
- int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
char *params = *ppparams;
int ret;
int pnum = -1;
@@ -980,12 +979,12 @@ static int do_nt_transact_create_pipe( connection_struct *conn,
* Ensure minimum number of parameters sent.
*/
- if(total_parameter_count < 54) {
- DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)total_parameter_count));
+ if(parameter_count < 54) {
+ DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
- srvstr_pull(inbuf, fname, params+53, sizeof(fname), total_parameter_count-53, STR_TERMINATE);
+ srvstr_pull(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE);
if ((ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum)) != 0)
return ret;
@@ -1091,15 +1090,14 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
****************************************************************************/
-static int call_nt_transact_create(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize, char **ppsetup, char **ppparams,
- char **ppdata)
+static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
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. */
int oplock_request = 0;
mode_t unixmode;
@@ -1135,7 +1133,10 @@ static int call_nt_transact_create(connection_struct *conn,
if (IS_IPC(conn)) {
if (lp_nt_pipe_support())
return do_nt_transact_create_pipe(conn, inbuf, outbuf, length,
- bufsize, ppsetup, ppparams, ppdata);
+ bufsize,
+ ppsetup, setup_count,
+ ppparams, parameter_count,
+ ppdata, data_count);
else
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
@@ -1144,8 +1145,8 @@ static int call_nt_transact_create(connection_struct *conn,
* Ensure minimum number of parameters sent.
*/
- if(total_parameter_count < 54) {
- DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)total_parameter_count));
+ if(parameter_count < 54) {
+ DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
@@ -1189,7 +1190,7 @@ static int call_nt_transact_create(connection_struct *conn,
if(!dir_fsp->is_directory) {
- srvstr_pull(inbuf, fname, params+53, sizeof(fname), total_parameter_count-53, STR_TERMINATE);
+ srvstr_pull(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE);
/*
* Check to see if this is a mac fork of some kind.
@@ -1218,9 +1219,9 @@ static int call_nt_transact_create(connection_struct *conn,
}
srvstr_pull(inbuf, &fname[dir_name_len], params+53, sizeof(fname)-dir_name_len,
- total_parameter_count-53, STR_TERMINATE);
+ parameter_count-53, STR_TERMINATE);
} else {
- srvstr_pull(inbuf, fname, params+53, sizeof(fname), total_parameter_count-53, STR_TERMINATE);
+ srvstr_pull(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE);
/*
* Check to see if this is a mac fork of some kind.
@@ -1467,11 +1468,10 @@ int reply_nttranss(connection_struct *conn,
don't allow a directory to be opened.
****************************************************************************/
-static int call_nt_transact_notify_change(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **ppsetup,
- char **ppparams, char **ppdata)
+static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
char *setup = *ppsetup;
files_struct *fsp;
@@ -1501,17 +1501,22 @@ name = %s\n", fsp->fsp_name ));
Reply to an NT transact rename command.
****************************************************************************/
-static int call_nt_transact_rename(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **ppsetup, char **ppparams, char **ppdata)
+static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
char *params = *ppparams;
pstring new_name;
- files_struct *fsp = file_fsp(params, 0);
- BOOL replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
+ files_struct *fsp = NULL;
+ BOOL replace_if_exists = False;
NTSTATUS status;
+ if(parameter_count < 4)
+ return ERROR_DOS(ERRDOS,ERRbadfunc);
+
+ fsp = file_fsp(params, 0);
+ replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
CHECK_FSP(fsp, conn);
srvstr_pull(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE);
@@ -1557,15 +1562,13 @@ static size_t get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
}
/****************************************************************************
- Reply to query a security descriptor - currently this is not implemented (it
- is planned to be though). Right now it just returns the same thing NT would
- when queried on a FAT filesystem. JRA.
+ Reply to query a security descriptor.
****************************************************************************/
-static int call_nt_transact_query_security_desc(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int bufsize,
- char **ppsetup, char **ppparams, char **ppdata)
+static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
char *params = *ppparams;
@@ -1573,13 +1576,19 @@ static int call_nt_transact_query_security_desc(connection_struct *conn,
prs_struct pd;
SEC_DESC *psd = NULL;
size_t sd_size;
+ uint32 security_info_wanted;
TALLOC_CTX *mem_ctx;
+ files_struct *fsp = NULL;
- files_struct *fsp = file_fsp(params,0);
+ if(parameter_count < 8)
+ return ERROR_DOS(ERRDOS,ERRbadfunc);
+ fsp = file_fsp(params,0);
if(!fsp)
return ERROR_DOS(ERRDOS,ERRbadfid);
+ security_info_wanted = IVAL(params,4);
+
DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
params = nttrans_realloc(ppparams, 4);
@@ -1598,7 +1607,7 @@ static int call_nt_transact_query_security_desc(connection_struct *conn,
if (!lp_nt_acl_support(SNUM(conn)))
sd_size = get_null_nt_acl(mem_ctx, &psd);
else
- sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, &psd);
+ sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, security_info_wanted, &psd);
if (sd_size == 0) {
talloc_destroy(mem_ctx);
@@ -1665,23 +1674,21 @@ security descriptor.\n"));
}
/****************************************************************************
- Reply to set a security descriptor. Map to UNIX perms.
+ Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.
****************************************************************************/
-static int call_nt_transact_set_security_desc(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize, char **ppsetup,
- char **ppparams, char **ppdata)
+static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
- uint32 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
char *params= *ppparams;
char *data = *ppdata;
- uint32 total_data_count = (uint32)IVAL(inbuf, smb_nts_TotalDataCount);
files_struct *fsp = NULL;
uint32 security_info_sent = 0;
NTSTATUS nt_status;
- if(total_parameter_count < 8)
+ if(parameter_count < 8)
return ERROR_DOS(ERRDOS,ERRbadfunc);
if((fsp = file_fsp(params,0)) == NULL)
@@ -1695,10 +1702,10 @@ 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 ));
- if (total_data_count == 0)
+ if (data_count == 0)
return ERROR_DOS(ERRDOS, ERRnoaccess);
- if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, total_data_count, security_info_sent)))
+ if (!NT_STATUS_IS_OK(nt_status = set_sd( fsp, data, data_count, security_info_sent)))
return ERROR_NT(nt_status);
done:
@@ -1710,12 +1717,11 @@ static int call_nt_transact_set_security_desc(connection_struct *conn,
/****************************************************************************
Reply to NT IOCTL
****************************************************************************/
-static int call_nt_transact_ioctl(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **ppsetup, int setup_count,
- char **ppparams, int parameter_count,
- char **ppdata, int data_count)
+
+static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
unsigned fnum, control;
static BOOL logged_message;
@@ -1835,12 +1841,10 @@ static int call_nt_transact_ioctl(connection_struct *conn,
Reply to get user quota
****************************************************************************/
-static int call_nt_transact_get_user_quota(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int bufsize,
- char **ppsetup, int setup_count,
- char **ppparams, int params_count,
- char **ppdata, int data_count)
+static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
NTSTATUS nt_status = NT_STATUS_OK;
uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
@@ -1872,8 +1876,8 @@ static int call_nt_transact_get_user_quota(connection_struct *conn,
* Ensure minimum number of parameters sent.
*/
- if (params_count < 4) {
- DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",params_count));
+ if (parameter_count < 4) {
+ DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count));
return ERROR_DOS(ERRDOS,ERRinvalidparam);
}
@@ -2086,12 +2090,10 @@ static int call_nt_transact_get_user_quota(connection_struct *conn,
Reply to set user quota
****************************************************************************/
-static int call_nt_transact_set_user_quota(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int bufsize,
- char **ppsetup, int setup_count,
- char **ppparams, int params_count,
- char **ppdata, int data_count)
+static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **ppsetup, uint32 setup_count,
+ char **ppparams, uint32 parameter_count,
+ char **ppdata, uint32 data_count)
{
char *params = *ppparams;
char *pdata = *ppdata;
@@ -2114,8 +2116,8 @@ static int call_nt_transact_set_user_quota(connection_struct *conn,
* Ensure minimum number of parameters sent.
*/
- if (params_count < 2) {
- DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",params_count));
+ if (parameter_count < 2) {
+ DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
return ERROR_DOS(ERRDOS,ERRinvalidparam);
}
@@ -2403,8 +2405,10 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
case NT_TRANSACT_CREATE:
START_PROFILE_NESTED(NT_transact_create);
outsize = call_nt_transact_create(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_create);
break;
case NT_TRANSACT_IOCTL:
@@ -2412,56 +2416,64 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
outsize = call_nt_transact_ioctl(conn, inbuf, outbuf,
length, bufsize,
&setup, setup_count,
- &params, parameter_count,
- &data, data_count);
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_ioctl);
break;
case NT_TRANSACT_SET_SECURITY_DESC:
START_PROFILE_NESTED(NT_transact_set_security_desc);
outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_set_security_desc);
break;
case NT_TRANSACT_NOTIFY_CHANGE:
START_PROFILE_NESTED(NT_transact_notify_change);
outsize = call_nt_transact_notify_change(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_notify_change);
break;
case NT_TRANSACT_RENAME:
START_PROFILE_NESTED(NT_transact_rename);
outsize = call_nt_transact_rename(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_rename);
break;
case NT_TRANSACT_QUERY_SECURITY_DESC:
START_PROFILE_NESTED(NT_transact_query_security_desc);
outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf,
- length, bufsize,
- &setup, &params, &data);
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_query_security_desc);
break;
#ifdef HAVE_SYS_QUOTAS
case NT_TRANSACT_GET_USER_QUOTA:
START_PROFILE_NESTED(NT_transact_get_user_quota);
outsize = call_nt_transact_get_user_quota(conn, inbuf, outbuf,
- length, bufsize,
- &setup, setup_count,
- &params, parameter_count,
- &data, data_count);
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_get_user_quota);
break;
case NT_TRANSACT_SET_USER_QUOTA:
START_PROFILE_NESTED(NT_transact_set_user_quota);
outsize = call_nt_transact_set_user_quota(conn, inbuf, outbuf,
- length, bufsize,
- &setup, setup_count,
- &params, parameter_count,
- &data, data_count);
+ length, bufsize,
+ &setup, setup_count,
+ &params, total_parameter_count,
+ &data, total_data_count);
END_PROFILE_NESTED(NT_transact_set_user_quota);
break;
#endif /* HAVE_SYS_QUOTAS */
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index d775a82d2d..9773076a46 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -2165,7 +2165,7 @@ static size_t merge_default_aces( SEC_ACE *nt_ace_list, size_t num_aces)
the UNIX style get ACL.
****************************************************************************/
-size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
+size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
{
extern DOM_SID global_sid_Builtin_Administrators;
extern DOM_SID global_sid_Builtin_Users;
@@ -2241,177 +2241,184 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
create_file_sids(&sbuf, &owner_sid, &group_sid);
}
- /*
- * In the optimum case Creator Owner and Creator Group would be used for
- * the ACL_USER_OBJ and ACL_GROUP_OBJ entries, respectively, but this
- * would lead to usability problems under Windows: The Creator entries
- * are only available in browse lists of directories and not for files;
- * additionally the identity of the owning group couldn't be determined.
- * We therefore use those identities only for Default ACLs.
- */
-
- /* Create the canon_ace lists. */
- file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, SMB_ACL_TYPE_ACCESS );
+ if (security_info & DACL_SECURITY_INFORMATION) {
- /* We must have *some* ACLS. */
+ /*
+ * In the optimum case Creator Owner and Creator Group would be used for
+ * the ACL_USER_OBJ and ACL_GROUP_OBJ entries, respectively, but this
+ * would lead to usability problems under Windows: The Creator entries
+ * are only available in browse lists of directories and not for files;
+ * additionally the identity of the owning group couldn't be determined.
+ * We therefore use those identities only for Default ACLs.
+ */
- if (count_canon_ace_list(file_ace) == 0) {
- DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", fsp->fsp_name ));
- return 0;
- }
+ /* Create the canon_ace lists. */
+ file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, SMB_ACL_TYPE_ACCESS );
- if (fsp->is_directory && dir_acl) {
- dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf,
- &global_sid_Creator_Owner,
- &global_sid_Creator_Group, SMB_ACL_TYPE_DEFAULT );
- }
+ /* We must have *some* ACLS. */
+
+ if (count_canon_ace_list(file_ace) == 0) {
+ DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", fsp->fsp_name ));
+ return 0;
+ }
- /*
- * Create the NT ACE list from the canonical ace lists.
- */
+ if (fsp->is_directory && dir_acl) {
+ dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf,
+ &global_sid_Creator_Owner,
+ &global_sid_Creator_Group, SMB_ACL_TYPE_DEFAULT );
+ }
- {
- canon_ace *ace;
- int nt_acl_type;
- int i;
+ /*
+ * Create the NT ACE list from the canonical ace lists.
+ */
- if (nt4_compatible_acls() && dir_ace) {
- /*
- * NT 4 chokes if an ACL contains an INHERIT_ONLY entry
- * but no non-INHERIT_ONLY entry for one SID. So we only
- * remove entries from the Access ACL if the
- * corresponding Default ACL entries have also been
- * removed. ACEs for CREATOR-OWNER and CREATOR-GROUP
- * are exceptions. We can do nothing
- * intelligent if the Default ACL contains entries that
- * are not also contained in the Access ACL, so this
- * case will still fail under NT 4.
- */
+ {
+ canon_ace *ace;
+ int nt_acl_type;
+ int i;
- ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(dir_ace, ace);
- SAFE_FREE(ace);
+ if (nt4_compatible_acls() && dir_ace) {
+ /*
+ * NT 4 chokes if an ACL contains an INHERIT_ONLY entry
+ * but no non-INHERIT_ONLY entry for one SID. So we only
+ * remove entries from the Access ACL if the
+ * corresponding Default ACL entries have also been
+ * removed. ACEs for CREATOR-OWNER and CREATOR-GROUP
+ * are exceptions. We can do nothing
+ * intelligent if the Default ACL contains entries that
+ * are not also contained in the Access ACL, so this
+ * case will still fail under NT 4.
+ */
- ace = canon_ace_entry_for(file_ace, SMB_ACL_OTHER, NULL);
+ ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL);
if (ace && !ace->perms) {
- DLIST_REMOVE(file_ace, ace);
+ DLIST_REMOVE(dir_ace, ace);
SAFE_FREE(ace);
+
+ ace = canon_ace_entry_for(file_ace, SMB_ACL_OTHER, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(file_ace, ace);
+ SAFE_FREE(ace);
+ }
}
- }
- /*
- * WinNT doesn't usually have Creator Group
- * in browse lists, so we send this entry to
- * WinNT even if it contains no relevant
- * permissions. Once we can add
- * Creator Group to browse lists we can
- * re-enable this.
- */
+ /*
+ * WinNT doesn't usually have Creator Group
+ * in browse lists, so we send this entry to
+ * WinNT even if it contains no relevant
+ * permissions. Once we can add
+ * Creator Group to browse lists we can
+ * re-enable this.
+ */
#if 0
- ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(dir_ace, ace);
- SAFE_FREE(ace);
- }
+ ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(dir_ace, ace);
+ SAFE_FREE(ace);
+ }
#endif
- ace = canon_ace_entry_for(file_ace, SMB_ACL_GROUP_OBJ, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(file_ace, ace);
- SAFE_FREE(ace);
+ ace = canon_ace_entry_for(file_ace, SMB_ACL_GROUP_OBJ, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(file_ace, ace);
+ SAFE_FREE(ace);
+ }
+ } else {
+
+ ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(dir_ace, ace);
+ SAFE_FREE(ace);
+ }
+ ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL);
+ if (ace && !ace->perms) {
+ DLIST_REMOVE(dir_ace, ace);
+ SAFE_FREE(ace);
+ }
}
- } else {
+
+ num_acls = count_canon_ace_list(file_ace);
+ num_dir_acls = count_canon_ace_list(dir_ace);
- ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(dir_ace, ace);
- SAFE_FREE(ace);
- }
- ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL);
- if (ace && !ace->perms) {
- DLIST_REMOVE(dir_ace, ace);
- SAFE_FREE(ace);
+ /* Allocate the ace list. */
+ if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) {
+ DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
+ goto done;
}
- }
-
- num_acls = count_canon_ace_list(file_ace);
- num_dir_acls = count_canon_ace_list(dir_ace);
-
- /* Allocate the ace list. */
- if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_profile_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) {
- DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
- goto done;
- }
- memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) );
-
- /*
- * Create the NT ACE list from the canonical ace lists.
- */
-
- ace = file_ace;
-
- for (i = 0; i < num_acls; i++, ace = ace->next) {
- SEC_ACCESS acc;
+ memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) );
+
+ /*
+ * Create the NT ACE list from the canonical ace lists.
+ */
+
+ ace = file_ace;
- acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
- init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0);
- }
+ for (i = 0; i < num_acls; i++, ace = ace->next) {
+ SEC_ACCESS acc;
- /* The User must have access to a profile share - even if we can't map the SID. */
- if (lp_profile_acls(SNUM(fsp->conn))) {
- SEC_ACCESS acc;
+ acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
+ init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0);
+ }
- init_sec_access(&acc,FILE_GENERIC_ALL);
- init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, 0);
- }
+ /* The User must have access to a profile share - even if we can't map the SID. */
+ if (lp_profile_acls(SNUM(fsp->conn))) {
+ SEC_ACCESS acc;
- ace = dir_ace;
+ init_sec_access(&acc,FILE_GENERIC_ALL);
+ init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, 0);
+ }
- for (i = 0; i < num_dir_acls; i++, ace = ace->next) {
- SEC_ACCESS acc;
+ ace = dir_ace;
- acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
- init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc,
- SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
- }
+ for (i = 0; i < num_dir_acls; i++, ace = ace->next) {
+ SEC_ACCESS acc;
+
+ acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
+ init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc,
+ SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
+ }
- /* The User must have access to a profile share - even if we can't map the SID. */
- if (lp_profile_acls(SNUM(fsp->conn))) {
- SEC_ACCESS acc;
+ /* The User must have access to a profile share - even if we can't map the SID. */
+ if (lp_profile_acls(SNUM(fsp->conn))) {
+ SEC_ACCESS acc;
- init_sec_access(&acc,FILE_GENERIC_ALL);
- init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc,
- SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
- SEC_ACE_FLAG_INHERIT_ONLY);
- }
-
- /*
- * Merge POSIX default ACLs and normal ACLs into one NT ACE.
- * Win2K needs this to get the inheritance correct when replacing ACLs
- * on a directory tree. Based on work by Jim @ IBM.
- */
+ init_sec_access(&acc,FILE_GENERIC_ALL);
+ init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc,
+ SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
+ SEC_ACE_FLAG_INHERIT_ONLY);
+ }
- num_aces = merge_default_aces(nt_ace_list, num_aces);
+ /*
+ * Merge POSIX default ACLs and normal ACLs into one NT ACE.
+ * Win2K needs this to get the inheritance correct when replacing ACLs
+ * on a directory tree. Based on work by Jim @ IBM.
+ */
- /*
- * Sort to force deny entries to the front.
- */
+ num_aces = merge_default_aces(nt_ace_list, num_aces);
- if (num_aces)
- qsort( nt_ace_list, num_aces, sizeof(nt_ace_list[0]), QSORT_CAST nt_ace_comp);
- }
+ /*
+ * Sort to force deny entries to the front.
+ */
+
+ if (num_aces)
+ qsort( nt_ace_list, num_aces, sizeof(nt_ace_list[0]), QSORT_CAST nt_ace_comp);
+ }
- if (num_aces) {
- if((psa = make_sec_acl( main_loop_talloc_get(), ACL_REVISION, num_aces, nt_ace_list)) == NULL) {
- DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
- goto done;
+ if (num_aces) {
+ if((psa = make_sec_acl( main_loop_talloc_get(), ACL_REVISION, num_aces, nt_ace_list)) == NULL) {
+ DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
+ goto done;
+ }
}
- }
+ } /* security_info & DACL_SECURITY_INFORMATION */
- *ppdesc = make_standard_sec_desc( main_loop_talloc_get(), &owner_sid, &group_sid, psa, &sd_size);
+ *ppdesc = make_standard_sec_desc( main_loop_talloc_get(),
+ (security_info & OWNER_SECURITY_INFORMATION) ? &owner_sid : NULL,
+ (security_info & GROUP_SECURITY_INFORMATION) ? &group_sid : NULL,
+ psa,
+ &sd_size);
if(!*ppdesc) {
DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n"));
diff --git a/source3/smbd/vfs-wrap.c b/source3/smbd/vfs-wrap.c
index 2160bca9f7..f923d22aea 100644
--- a/source3/smbd/vfs-wrap.c
+++ b/source3/smbd/vfs-wrap.c
@@ -576,22 +576,22 @@ char *vfswrap_realpath(vfs_handle_struct *handle, connection_struct *conn, const
return result;
}
-size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, SEC_DESC **ppdesc)
+size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc)
{
size_t result;
START_PROFILE(fget_nt_acl);
- result = get_nt_acl(fsp, ppdesc);
+ result = get_nt_acl(fsp, security_info, ppdesc);
END_PROFILE(fget_nt_acl);
return result;
}
-size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, SEC_DESC **ppdesc)
+size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc)
{
size_t result;
START_PROFILE(get_nt_acl);
- result = get_nt_acl(fsp, ppdesc);
+ result = get_nt_acl(fsp, security_info, ppdesc);
END_PROFILE(get_nt_acl);
return result;
}