summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-01-23 01:52:30 +0000
committerJeremy Allison <jra@samba.org>2001-01-23 01:52:30 +0000
commit2f7c1db093504a9798cdfd9c5d08a259cb4abc46 (patch)
tree31db36db246f4f9bb42135b7526f64168f4dd6c5 /source3/smbd
parent3ea544fecba9d6aa662491ea4006b57a6fb6e79f (diff)
downloadsamba-2f7c1db093504a9798cdfd9c5d08a259cb4abc46.tar.gz
samba-2f7c1db093504a9798cdfd9c5d08a259cb4abc46.tar.bz2
samba-2f7c1db093504a9798cdfd9c5d08a259cb4abc46.zip
include/vfs.h:
smbd/vfs-wrap.c: smbd/vfs.c: Added fchmod_acl and chmod_acl. lib/substitute.c: smbd/lanman.c: smbd/open.c: smbd/process.c: smbd/reply.c: smbd/service.c: Removed sessetup_user variable. Added current_user_info struct which conatins domain info etc. Added '%D' for client domain parameter. Jeremy. (This used to be commit 2844ec3d511680609d6794b8718001a1bda9e89f)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/lanman.c4
-rw-r--r--source3/smbd/open.c4
-rw-r--r--source3/smbd/posix_acls.c319
-rw-r--r--source3/smbd/process.c6
-rw-r--r--source3/smbd/reply.c6
-rw-r--r--source3/smbd/service.c32
-rw-r--r--source3/smbd/vfs-wrap.c38
-rw-r--r--source3/smbd/vfs.c12
8 files changed, 389 insertions, 32 deletions
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index fd59f4603a..33da479361 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -2187,7 +2187,7 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
char *p2;
- extern pstring sesssetup_user;
+ extern userdom_struct current_user_info;
int level = SVAL(p,0);
DEBUG(4,("NetWkstaGetInfo level %d\n",level));
@@ -2216,7 +2216,7 @@ static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param
p += 4;
SIVAL(p,0,PTR_DIFF(p2,*rdata));
- pstrcpy(p2,sesssetup_user);
+ pstrcpy(p2,current_user_info.smb_name);
p2 = skip_string(p2,1);
p += 4;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index b23da55542..77962562e3 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -25,7 +25,7 @@
extern int DEBUGLEVEL;
-extern pstring sesssetup_user;
+extern userdom_struct current_user_info;
extern uint16 global_oplock_port;
extern BOOL global_client_failed_oplock_break;
@@ -188,7 +188,7 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
fsp->wcp = NULL; /* Write cache pointer. */
DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
- *sesssetup_user ? sesssetup_user : conn->user,fsp->fsp_name,
+ *current_user_info.smb_name ? current_user_info.smb_name : conn->user,fsp->fsp_name,
BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
conn->num_files_open + 1));
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 0071f8786d..2bd0065d58 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -42,6 +42,22 @@ typedef struct canon_ace {
static void free_canon_ace_list( canon_ace *list_head );
/****************************************************************************
+ Function to duplicate a canon_ace entry.
+****************************************************************************/
+
+static canon_ace *dup_canon_ace( canon_ace *src_ace)
+{
+ canon_ace *dst_ace = (canon_ace *)malloc(sizeof(canon_ace));
+
+ if (dst_ace == NULL)
+ return NULL;
+
+ *dst_ace = *src_ace;
+ dst_ace->prev = dst_ace->next = NULL;
+ return dst_ace;
+}
+
+/****************************************************************************
Function to create owner and group SIDs from a SMB_STRUCT_STAT.
****************************************************************************/
@@ -254,11 +270,120 @@ static BOOL merge_aces( canon_ace *list_head, canon_ace *p_ace)
}
/****************************************************************************
+ Create a default mode for a directory default ACE.
+****************************************************************************/
+
+static mode_t get_default_ace_mode(files_struct *fsp, int type)
+{
+ mode_t force_mode = lp_force_dir_security_mode(SNUM(fsp->conn));
+ mode_t mode = 0;
+
+ switch(type) {
+ case S_IRUSR:
+ mode |= (force_mode & S_IRUSR) ? S_IRUSR : 0;
+ mode |= (force_mode & S_IWUSR) ? S_IWUSR : 0;
+ mode |= (force_mode & S_IXUSR) ? S_IXUSR : 0;
+ break;
+ case S_IRGRP:
+ mode |= (force_mode & S_IRGRP) ? S_IRUSR : 0;
+ mode |= (force_mode & S_IWGRP) ? S_IWUSR : 0;
+ mode |= (force_mode & S_IXGRP) ? S_IXUSR : 0;
+ break;
+ case S_IROTH:
+ mode |= (force_mode & S_IROTH) ? S_IRUSR : 0;
+ mode |= (force_mode & S_IWOTH) ? S_IWUSR : 0;
+ mode |= (force_mode & S_IXOTH) ? S_IXUSR : 0;
+ break;
+ }
+
+ return mode;
+}
+
+/****************************************************************************
+ A well formed POSIX file or default ACL has at least 3 entries, a
+ SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER_OBJ.
+****************************************************************************/
+
+static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
+ files_struct *fsp,
+ DOM_SID *pfile_owner_sid,
+ DOM_SID *pfile_grp_sid,
+ SMB_STRUCT_STAT *pst,
+ BOOL default_acl)
+{
+ extern DOM_SID global_sid_World;
+ canon_ace *pace;
+ BOOL got_user = False;
+ BOOL got_grp = False;
+ BOOL got_other = False;
+
+ for (pace = *pp_ace; pace; pace = pace->next) {
+ if (pace->type == SMB_ACL_USER_OBJ)
+ got_user = True;
+ else if (pace->type == SMB_ACL_GROUP_OBJ)
+ got_grp = True;
+ else if (pace->type == SMB_ACL_OTHER)
+ got_other = True;
+ }
+
+ if (!got_user) {
+ if ((pace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL) {
+ DEBUG(0,("ensure_canon_entry_valid: malloc fail.\n"));
+ return False;
+ }
+
+ ZERO_STRUCTP(pace);
+ pace->type = SMB_ACL_USER_OBJ;
+ pace->owner_type = UID_ACE;
+ pace->unix_ug.uid = pst->st_uid;
+ pace->sid = *pfile_owner_sid;
+ pace->perms = default_acl ? get_default_ace_mode(fsp, S_IRUSR): 0;
+
+ DLIST_ADD(*pp_ace, pace);
+ }
+
+ if (!got_grp) {
+ if ((pace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL) {
+ DEBUG(0,("ensure_canon_entry_valid: malloc fail.\n"));
+ return False;
+ }
+
+ ZERO_STRUCTP(pace);
+ pace->type = SMB_ACL_GROUP_OBJ;
+ pace->owner_type = GID_ACE;
+ pace->unix_ug.uid = pst->st_gid;
+ pace->sid = *pfile_grp_sid;
+ pace->perms = default_acl ? get_default_ace_mode(fsp, S_IRGRP): 0;
+
+ DLIST_ADD(*pp_ace, pace);
+ }
+
+ if (!got_other) {
+ if ((pace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL) {
+ DEBUG(0,("ensure_canon_entry_valid: malloc fail.\n"));
+ return False;
+ }
+
+ ZERO_STRUCTP(pace);
+ pace->type = SMB_ACL_OTHER;
+ pace->owner_type = WORLD_ACE;
+ pace->unix_ug.world = -1;
+ pace->sid = global_sid_World;
+ pace->perms = default_acl ? get_default_ace_mode(fsp, S_IROTH): 0;
+
+ DLIST_ADD(*pp_ace, pace);
+ }
+
+ return True;
+}
+
+/****************************************************************************
Unpack a SEC_DESC into two canonical ace lists. We don't depend on this
succeeding.
****************************************************************************/
static BOOL unpack_canon_ace(files_struct *fsp,
+ SMB_STRUCT_STAT *pst,
DOM_SID *pfile_owner_sid,
DOM_SID *pfile_grp_sid,
canon_ace **ppfile_ace, canon_ace **ppdir_ace,
@@ -383,7 +508,8 @@ static BOOL unpack_canon_ace(files_struct *fsp,
current_ace->type = (current_ace->owner_type == UID_ACE) ? SMB_ACL_USER : SMB_ACL_GROUP;
}
- if (fsp->is_directory && (psa->flags & SEC_ACE_FLAG_INHERIT_ONLY)) {
+ if (fsp->is_directory) {
+
/*
* We can only add to the default POSIX ACE list if the ACE is
* designed to be inherited by both files and directories.
@@ -391,14 +517,45 @@ static BOOL unpack_canon_ace(files_struct *fsp,
if ((psa->flags & (SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT)) ==
(SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT)) {
DLIST_ADD(dir_ace, current_ace);
- } else {
- DEBUG(0,("unpack_canon_ace: unable to use a non-generic default ACE.\n"));
- free(current_ace);
+
+ /*
+ * If this is not an inherit only ACE we need to add a duplicate
+ * to the file acl.
+ */
+
+ if (!(psa->flags & SEC_ACE_FLAG_INHERIT_ONLY)) {
+ canon_ace *dup_ace = dup_canon_ace(current_ace);
+
+ if (!dup_ace) {
+ DEBUG(0,("unpack_canon_ace: malloc fail !\n"));
+ free_canon_ace_list(file_ace);
+ free_canon_ace_list(dir_ace);
+ return False;
+ }
+
+ current_ace = dup_ace;
+ } else {
+ current_ace = NULL;
+ }
}
- } else {
+ }
+
+ /*
+ * Only add to the file ACL if not inherit only.
+ */
+
+ if (!(psa->flags & SEC_ACE_FLAG_INHERIT_ONLY)) {
DLIST_ADD(file_ace, current_ace);
all_aces_are_inherit_only = False;
+ current_ace = NULL;
}
+
+ /*
+ * Free if ACE was not addedd.
+ */
+
+ if (current_ace)
+ free(current_ace);
}
if (fsp->is_directory && all_aces_are_inherit_only) {
@@ -431,6 +588,36 @@ static BOOL unpack_canon_ace(files_struct *fsp,
goto again_dir;
}
+ /*
+ * A well formed POSIX file or default ACL has at least 3 entries, a
+ * SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER_OBJ
+ * and optionally a mask entry. Ensure this is the case.
+ */
+
+ if (!ensure_canon_entry_valid(&file_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst, False)) {
+ free_canon_ace_list(file_ace);
+ free_canon_ace_list(dir_ace);
+ return False;
+ }
+
+ if (!ensure_canon_entry_valid(&dir_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst, True)) {
+ free_canon_ace_list(file_ace);
+ free_canon_ace_list(dir_ace);
+ return False;
+ }
+
+ if( DEBUGLVL( 10 )) {
+ dbgtext("unpack_canon_ace: File ACL:\n");
+ for (i = 0, current_ace = file_ace; current_ace; current_ace = current_ace->next, i++ ) {
+ print_canon_ace( current_ace, i);
+ }
+
+ dbgtext("unpack_canon_ace: Directory ACL:\n");
+ for (i = 0, current_ace = dir_ace; current_ace; current_ace = current_ace->next, i++ ) {
+ print_canon_ace( current_ace, i);
+ }
+ }
+
*ppfile_ace = file_ace;
*ppdir_ace = dir_ace;
return True;
@@ -914,7 +1101,7 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf)
Attempt to apply an ACL to a file or directory.
****************************************************************************/
-static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL default_ace)
+static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL default_ace, BOOL *pacl_set_support)
{
BOOL ret = False;
SMB_ACL_T the_acl = sys_acl_init((int)count_canon_ace_list(the_ace) + 1);
@@ -933,6 +1120,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
DEBUG(0,("set_canon_ace_list: Unable to init %s ACL. (%s)\n",
default_ace ? "default" : "file", strerror(errno) ));
#endif
+ *pacl_set_support = False;
return False;
}
@@ -951,6 +1139,13 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
}
/*
+ * Ok - we now know the ACL calls should be working, don't
+ * allow fallback to chmod.
+ */
+
+ *pacl_set_support = True;
+
+ /*
* Initialise the entry from the canon_ace.
*/
@@ -1041,7 +1236,9 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
*/
if (sys_acl_valid(the_acl) == -1) {
- DEBUG(0,("set_canon_ace_list: ACL is invalid for set (%s).\n", strerror(errno) ));
+ DEBUG(0,("set_canon_ace_list: ACL type (%s) is invalid for set (%s).\n",
+ the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file",
+ strerror(errno) ));
goto done;
}
@@ -1051,7 +1248,8 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
if(default_ace || fsp->is_directory || fsp->fd == -1) {
if (sys_acl_set_file(fsp->fsp_name, the_acl_type, the_acl) == -1) {
- DEBUG(0,("set_canon_ace_list: sys_acl_set_file failed for file %s (%s).\n",
+ DEBUG(0,("set_canon_ace_list: sys_acl_set_file type %s failed for file %s (%s).\n",
+ the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file",
fsp->fsp_name, strerror(errno) ));
goto done;
}
@@ -1150,7 +1348,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
num_acls = count_canon_ace_list(file_ace);
if (fsp->is_directory) {
- if (dir_ace)
+ if (dir_acl)
dir_ace = canonicalise_acl( dir_acl, &sbuf);
else
dir_ace = unix_canonicalise_acl(fsp, &sbuf, &owner_sid, &group_sid);
@@ -1302,7 +1500,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
- acl_perms = unpack_canon_ace( fsp, &file_owner_sid, &file_grp_sid,
+ acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid,
&file_ace_list, &dir_ace_list, security_info_sent, psd);
posix_perms = unpack_posix_permissions( fsp, &sbuf, &perms, security_info_sent, psd, acl_perms);
@@ -1324,17 +1522,31 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
if((security_info_sent & DACL_SECURITY_INFORMATION) && (psd->dacl != NULL)) {
BOOL acl_set_support = False;
+ BOOL ret = False;
/*
* Try using the POSIX ACL set first. All back to chmod if
* we have no ACL support on this filesystem.
*/
- if (acl_perms && file_ace_list && set_canon_ace_list(fsp, file_ace_list, False))
- acl_set_support = True;
+ if (acl_perms && file_ace_list) {
+ ret = set_canon_ace_list(fsp, file_ace_list, False, &acl_set_support);
+ if (acl_set_support && ret == False) {
+ DEBUG(3,("set_nt_acl: failed to set file acl on file %s (%s).\n", fsp->fsp_name, strerror(errno) ));
+ free_canon_ace_list(file_ace_list);
+ free_canon_ace_list(dir_ace_list);
+ return False;
+ }
+ }
- if (acl_perms && acl_set_support && fsp->is_directory && dir_ace_list)
- set_canon_ace_list(fsp, dir_ace_list, True);
+ if (acl_perms && acl_set_support && fsp->is_directory && dir_ace_list) {
+ if (!set_canon_ace_list(fsp, dir_ace_list, True, &acl_set_support)) {
+ DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) ));
+ free_canon_ace_list(file_ace_list);
+ free_canon_ace_list(dir_ace_list);
+ return False;
+ }
+ }
/*
* If we cannot set using POSIX ACLs we fall back to checking if we need to chmod.
@@ -1347,7 +1559,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
file_ace_list = NULL;
dir_ace_list = NULL;
- DEBUG(3,("call_nt_transact_set_security_desc: chmod %s. perms = 0%o.\n",
+ DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n",
fsp->fsp_name, (unsigned int)perms ));
if(conn->vfs_ops.chmod(conn,dos_to_unix(fsp->fsp_name, False), perms) == -1) {
@@ -1363,4 +1575,81 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
return True;
}
+
+/****************************************************************************
+ Do a chmod by setting the ACL USER_OBJ, GROUP_OBJ and OTHER bits in an ACL
+ and set the mask to rwx. Needed to preserve complex ACLs set by NT.
+****************************************************************************/
+
+static int chmod_acl_internals( SMB_ACL_T posix_acl, mode_t mode)
+{
+ int entry_id = SMB_ACL_FIRST_ENTRY;
+ SMB_ACL_ENTRY_T entry;
+ int num_entries = 0;
+
+#if 1
+ return -1;
+#else
+ while ( sys_acl_get_entry(posix_acl, entry_id, &entry) == 1) {
+ SMB_ACL_TAG_T tagtype;
+ SMB_ACL_PERMSET_T permset;
+
+ if (sys_acl_get_tag_type(entry, &tagtype) == -1)
+ return -1;
+
+ if (sys_acl_get_permset(entry, &permset) == -1)
+ return -1;
+
+ num_entries++;
+
+ switch(tagtype) {
+ case SMB_ACL_USER_OBJ:
+ break;
+ case SMB_ACL_USER:
+ break;
+ case SMB_ACL_GROUP_OBJ:
+ break;
+ case SMB_ACL_GROUP:
+ break;
+ case SMB_ACL_MASK:
+ break;
+ case SMB_ACL_OTHER:
+ break;
+ }
+
+ }
+#endif
+}
+
+/****************************************************************************
+ Do a chmod by setting the ACL USER_OBJ, GROUP_OBJ and OTHER bits in an ACL
+ and set the mask to rwx. Needed to preserve complex ACLs set by NT.
+ Note that name is in UNIX character set.
+****************************************************************************/
+
+int chmod_acl(char *name, mode_t mode)
+{
+ SMB_ACL_T posix_acl = NULL;
+
+ if ((posix_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS)) == NULL)
+ return -1;
+
+ return chmod_acl_internals(posix_acl, mode);
+}
+
+/****************************************************************************
+ Do an fchmod by setting the ACL USER_OBJ, GROUP_OBJ and OTHER bits in an ACL
+ and set the mask to rwx. Needed to preserve complex ACLs set by NT.
+****************************************************************************/
+
+int fchmod_acl(int fd, mode_t mode)
+{
+ SMB_ACL_T posix_acl = NULL;
+
+ if ((posix_acl = sys_acl_get_fd(fd)) == NULL)
+ return -1;
+
+ return chmod_acl_internals(posix_acl, mode);
+}
+
#undef OLD_NTDOMAIN
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index ea0309599f..0916dc5b7e 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -44,7 +44,7 @@ int max_recv = BUFFER_SIZE;
extern int last_message;
extern int global_oplock_break;
-extern pstring sesssetup_user;
+extern userdom_struct current_user_info;
extern char *last_inbuf;
extern char *InBuffer;
extern char *OutBuffer;
@@ -524,7 +524,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
SSVAL(inbuf,smb_uid,session_tag);
/*
- * Ensure the correct username is in sesssetup_user.
+ * Ensure the correct username is in current_user_info.
* This is a really ugly bugfix for problems with
* multiple session_setup_and_X's being done and
* allowing %U and %G substitutions to work correctly.
@@ -539,7 +539,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
if(session_tag != UID_FIELD_INVALID)
vuser = get_valid_user_struct(session_tag);
if(vuser != NULL)
- pstrcpy( sesssetup_user, vuser->user.smb_name);
+ current_user_info = vuser->user;
}
/* does this protocol need to be run as root? */
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 7738f2594f..624dc59084 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -36,7 +36,7 @@ extern char magic_char;
extern BOOL case_sensitive;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
-extern pstring sesssetup_user;
+extern userdom_struct current_user_info;
extern pstring global_myname;
extern fstring global_myworkgroup;
extern int global_oplock_break;
@@ -879,7 +879,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
guest = True;
}
- pstrcpy(sesssetup_user,user);
+ pstrcpy(current_user_info.smb_name,user);
reload_services(True);
@@ -1042,7 +1042,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
/* register the name and uid as being validated, so further connections
to a uid can get through without a password, on the same VC */
- sess_vuid = register_vuid(uid,gid,user,sesssetup_user,domain,guest);
+ sess_vuid = register_vuid(uid,gid,user,current_user_info.smb_name,domain,guest);
SSVAL(outbuf,smb_uid,sess_vuid);
SSVAL(inbuf,smb_uid,sess_vuid);
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 1db5dc4a5f..a6e66965c3 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -33,7 +33,7 @@ extern BOOL case_mangle;
extern BOOL case_sensitive;
extern BOOL use_mangled_map;
extern fstring remote_machine;
-extern pstring sesssetup_user;
+extern userdom_struct current_user_info;
extern fstring remote_machine;
@@ -113,8 +113,28 @@ int find_service(char *service)
int iHomeService;
if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
{
- lp_add_home(service,iHomeService,phome_dir);
- iService = lp_servicenumber(service);
+ /*
+ * If this is a winbindd provided username, remove
+ * the domain component before adding the service.
+ * Log a warning if the "path=" parameter does not
+ * include any macros.
+ */
+
+ fstring new_service;
+ char *usr_p = NULL;
+
+ fstrcpy(new_service, service);
+
+ if ((usr_p = strchr(service,*lp_winbind_separator())) != NULL)
+ fstrcpy(new_service, usr_p+1);
+
+ lp_add_home(new_service,iHomeService,phome_dir);
+ iService = lp_servicenumber(new_service);
+
+ if (usr_p && (strchr(lp_pathname(iService),'%') == NULL))
+ DEBUG(0,("find_service: Service %s added for user %s - contains non-local (Domain) user \
+with non parameterised path (%s). This may be cause the wrong directory to be seen.\n",
+ new_service, service, lp_pathname(iService) ));
}
}
}
@@ -234,11 +254,11 @@ connection_struct *make_connection(char *service,char *user,char *password, int
return(make_connection(dos_username,user,password,pwlen,dev,vuid,ecode));
}
} else {
- /* Security = share. Try with sesssetup_user
+ /* Security = share. Try with current_user_info.smb_name
* as the username. */
- if(*sesssetup_user) {
+ if(*current_user_info.smb_name) {
fstring dos_username;
- fstrcpy(user,sesssetup_user);
+ fstrcpy(user,current_user_info.smb_name);
fstrcpy(dos_username, user);
unix_to_dos(dos_username, True);
return(make_connection(dos_username,user,password,pwlen,dev,vuid,ecode));
diff --git a/source3/smbd/vfs-wrap.c b/source3/smbd/vfs-wrap.c
index a9d8a32430..ad4d4ddbef 100644
--- a/source3/smbd/vfs-wrap.c
+++ b/source3/smbd/vfs-wrap.c
@@ -107,6 +107,20 @@ int vfswrap_mkdir(connection_struct *conn, char *path, mode_t mode)
#endif
result = mkdir(path, mode);
+
+ if (result == 0) {
+ /*
+ * We need to do this as the default behavior of POSIX ACLs
+ * is to set the mask to be the requested group permission
+ * bits, not the group permission bits to be the requested
+ * group permission bits. This is not what we want, as it will
+ * mess up any inherited ACL bits that were set. JRA.
+ */
+ if (conn->vfs_ops.chmod_acl != NULL) {
+ conn->vfs_ops.chmod_acl(conn, path, mode);
+ }
+ }
+
END_PROFILE(syscall_mkdir);
return result;
}
@@ -332,6 +346,19 @@ int vfswrap_chmod(connection_struct *conn, char *path, mode_t mode)
}
#endif
+ /*
+ * We need to do this due to the fact that the default POSIX ACL
+ * chmod modifies the ACL *mask* for the group owner, not the
+ * group owner bits directly. JRA.
+ */
+
+ if (conn->vfs_ops.chmod_acl != NULL) {
+ if ((result = conn->vfs_ops.chmod_acl(conn, path, mode)) == 0) {
+ END_PROFILE(syscall_chmod);
+ return result;
+ }
+ }
+
result = chmod(path, mode);
END_PROFILE(syscall_chmod);
return result;
@@ -506,4 +533,15 @@ BOOL vfswrap_set_nt_acl(files_struct *fsp, char *name, uint32 security_info_sent
{
return set_nt_acl(fsp, security_info_sent, psd);
}
+
+int vfswrap_chmod_acl(connection_struct *conn, char *name, mode_t mode)
+{
+ return chmod_acl(name, mode);
+}
+
+int vfswrap_fchmod_acl(files_struct *fsp, int fd, mode_t mode)
+{
+ return fchmod_acl(fd, mode);
+}
+
#undef OLD_NTDOMAIN
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index cbd1fd6825..2cd83c37f3 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -74,7 +74,10 @@ struct vfs_ops default_vfs_ops = {
vfswrap_fget_nt_acl,
vfswrap_get_nt_acl,
vfswrap_fset_nt_acl,
- vfswrap_set_nt_acl
+ vfswrap_set_nt_acl,
+
+ vfswrap_chmod_acl,
+ vfswrap_fchmod_acl
};
/****************************************************************************
@@ -257,6 +260,13 @@ BOOL vfs_init_custom(connection_struct *conn)
conn->vfs_ops.set_nt_acl = default_vfs_ops.set_nt_acl;
}
+ if (conn->vfs_ops.chmod_acl == NULL) {
+ conn->vfs_ops.chmod_acl = default_vfs_ops.chmod_acl;
+ }
+
+ if (conn->vfs_ops.fchmod_acl == NULL) {
+ conn->vfs_ops.fchmod_acl = default_vfs_ops.fchmod_acl;
+ }
return True;
}
#endif