From nobody@FreeBSD.org  Sun Oct 17 14:14:19 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 3A14B106564A
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 17 Oct 2010 14:14:19 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 275448FC2F
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 17 Oct 2010 14:14:19 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o9HEEIWQ097377
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 17 Oct 2010 14:14:18 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o9HEEILr097375;
	Sun, 17 Oct 2010 14:14:18 GMT
	(envelope-from nobody)
Message-Id: <201010171414.o9HEEILr097375@www.freebsd.org>
Date: Sun, 17 Oct 2010 14:14:18 GMT
From: Michael Meelis <m.meelis@easybow.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: 'force create user' patch for samba33
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         151517
>Category:       ports
>Synopsis:       'force create user' patch for net/samba33
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Oct 17 14:20:07 UTC 2010
>Closed-Date:    Mon Oct 18 12:13:10 UTC 2010
>Last-Modified:  Mon Oct 18 12:13:10 UTC 2010
>Originator:     Michael Meelis
>Release:        8.1-RELEASE
>Organization:
EasyBOW
>Environment:
8.1-RELEASE
>Description:
Patch for samba33 to allow a file created/modified to get the system UID of the 'force create user' (set in smb.conf) and not the user name under which the user is logged in. It in the style of 'force create mode = xxx'.

The 'force create user = UID' will be set in smb.conf.

>How-To-Repeat:

>Fix:
diff --git a/source/include/proto.h b/source/include/proto.h
index 8fdd454..e2bb6a8 100644
--- source/include/proto.h
+++ source/include/proto.h
@@ -5923,6 +5923,7 @@ bool lp_acl_group_control(int );
 bool lp_acl_map_full_control(int );
 int lp_create_mask(int );
 int lp_force_create_mode(int );
+int lp_force_create_user(int );
 int lp_security_mask(int );
 int lp_force_security_mode(int );
 int lp_dir_mask(int );
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index ce1e6b6..54f65ad 100644
--- source/param/loadparm.c
+++ source/param/loadparm.c
@@ -403,6 +403,7 @@ struct service {
        int iWriteCacheSize;
        int iCreate_mask;
        int iCreate_force_mode;
+       int iCreate_force_user;
        int iSecurity_mask;
        int iSecurity_force_mode;
        int iDir_mask;
@@ -546,6 +547,7 @@ static struct service sDefault = {
        0,                      /* iWriteCacheSize */
        0744,                   /* iCreate_mask */
        0000,                   /* iCreate_force_mode */
+       -1,                     /* iCreate_force_user */
        0777,                   /* iSecurity_mask */
        0,                      /* iSecurity_force_mode */
        0755,                   /* iDir_mask */
@@ -1545,6 +1547,15 @@ static struct parm_struct parm_table[] = {
                .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
        },
        {
+               .label          = "force create user",
+               .type           = P_INTEGER,
+               .p_class        = P_LOCAL,
+               .ptr            = &sDefault.iCreate_force_user,
+               .special        = NULL,
+               .enum_list      = NULL,
+               .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
+       },
+       {
                .label          = "security mask",
                .type           = P_OCTAL,
                .p_class        = P_LOCAL,
@@ -5346,6 +5357,7 @@ FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
+FN_LOCAL_INTEGER(lp_force_create_user, iCreate_force_user)
 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 2ec9632..654c3b1 100644
--- source/smbd/open.c
+++ source/smbd/open.c
@@ -156,6 +156,102 @@ NTSTATUS fd_close(files_struct *fsp)
        return NT_STATUS_OK;
 }

+static void change_file_owner(connection_struct *conn,
+                    int uid,
+                    files_struct *fsp)
+{
+       int ret;
+       if (uid == -1)
+               return;
+
+       become_root();
+       ret = SMB_VFS_FCHOWN(fsp, uid, (gid_t)-1);
+       unbecome_root();
+       if (ret == -1) {
+               DEBUG(0,("change_file_owner: failed to fchown "
+                        "file %s to parent directory uid %u. Error "
+                        "was %s\n", fsp->fsp_name,
+                        (unsigned int)uid,
+                        strerror(errno) ));
+       }
+
+       DEBUG(10,("change_file_owner: changed new file %s to "
+                 "uid %u.\n",  fsp->fsp_name,
+                 (unsigned int)uid ));
+}
+
+static NTSTATUS change_dir_owner(connection_struct *conn,
+                                      int uid,
+                                      const char *fname,
+                                      SMB_STRUCT_STAT *psbuf)
+{
+       char *saved_dir = NULL;
+       SMB_STRUCT_STAT sbuf;
+       TALLOC_CTX *ctx = talloc_tos();
+       NTSTATUS status = NT_STATUS_OK;
+       int ret;
+
+       saved_dir = vfs_GetWd(ctx,conn);
+       if (!saved_dir) {
+               status = map_nt_error_from_unix(errno);
+               DEBUG(0,("change_dir_owner: failed to get "
+                        "current working directory. Error was %s\n",
+                        strerror(errno)));
+               return status;
+       }
+
+       /* Chdir into the new path. */
+       if (vfs_ChDir(conn, fname) == -1) {
+               status = map_nt_error_from_unix(errno);
+               DEBUG(0,("change_dir_owner: failed to change "
+                        "current working directory to %s. Error "
+                        "was %s\n", fname, strerror(errno) ));
+               goto out2;
+       }
+
+       if (SMB_VFS_STAT(conn,".",&sbuf) == -1) {
+               status = map_nt_error_from_unix(errno);
+               DEBUG(0,("change_dir_owner: failed to stat "
+                        "directory '.' (%s) Error was %s\n",
+                        fname, strerror(errno)));
+               goto out2;
+       }
+
+       /* Ensure we're pointing at the same place. */
+       if (sbuf.st_dev != psbuf->st_dev ||
+           sbuf.st_ino != psbuf->st_ino ||
+           sbuf.st_mode != psbuf->st_mode ) {
+               DEBUG(0,("change_dir_owner: "
+                        "device/inode/mode on directory %s changed. "
+                        "Refusing to chown !\n", fname ));
+               status = NT_STATUS_ACCESS_DENIED;
+               goto out2;
+       }
+
+       become_root();
+       ret = SMB_VFS_CHOWN(conn, ".", uid, (gid_t)-1);
+       unbecome_root();
+       if (ret == -1) {
+               status = map_nt_error_from_unix(errno);
+               DEBUG(10,("change_dir_owner: failed to chown "
+                         "directory %s to parent directory uid %u. "
+                         "Error was %s\n", fname,
+                         (unsigned int)uid, strerror(errno) ));
+               goto out2;
+       }
+
+       DEBUG(10,("change_dir_owner: changed ownership of new "
+                 "directory %s to parent directory uid %u.\n",
+                 fname, (unsigned int)uid ));
+
+ out2:
+
+       vfs_ChDir(conn,saved_dir);
+       return status;
+}
+
+
+
 /****************************************************************************
  Change the ownership of a file to that of the parent directory.
  Do this by fd if possible.
@@ -299,6 +395,7 @@ static NTSTATUS open_file(files_struct *fsp,
        int accmode = (flags & O_ACCMODE);
        int local_flags = flags;
        bool file_existed = VALID_STAT(*psbuf);
+       int uid = -1;

        fsp->fh->fd = -1;
        errno = EPERM;
@@ -410,6 +507,10 @@ static NTSTATUS open_file(files_struct *fsp,
                                                            fsp);
                        }

+                       if ((uid = lp_force_create_user(SNUM(conn))) != -1) {
+                               change_file_owner(conn, uid, fsp);
+                       }
+
                        notify_fname(conn, NOTIFY_ACTION_ADDED,
                                     FILE_NOTIFY_CHANGE_FILE_NAME, path);
                }
@@ -2282,6 +2383,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
        const char *dirname;
        NTSTATUS status;
        bool posix_open = false;
+       int uid = -1;

        if(!CAN_WRITE(conn)) {
                DEBUG(5,("mkdir_internal: failing create on read-only share "
@@ -2356,6 +2458,10 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
                change_dir_owner_to_parent(conn, parent_dir, name, psbuf);
        }

+       if ((uid = lp_force_create_user(SNUM(conn))) != -1) {
+               change_dir_owner(conn, uid, name, psbuf);
+       }
+
        notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
                     name);


>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: linimon 
State-Changed-When: Mon Oct 18 12:11:37 UTC 2010 
State-Changed-Why:  
net/samba33 has just been removed as being obsolete.  If this patch is 
needed for later versions, please let us know and we can re-open it. 


Responsible-Changed-From-To: freebsd-bugs->freebsd-ports-bugs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Mon Oct 18 12:11:37 UTC 2010 
Responsible-Changed-Why:  

http://www.freebsd.org/cgi/query-pr.cgi?pr=151517 
>Unformatted:
