Fix Bug 8989 - Samba 3.5.x (and probably all other versions of Samba) does not send...
[samba.git] / source3 / smbd / nttrans.c
index d311cc32684b20149f0e90c45dc6bf7994dd9de3..2ca14f477d208c7bea6851a8ee555627cd18667b 100644 (file)
@@ -133,11 +133,6 @@ void send_nt_replies(connection_struct *conn,
                             total_sent_thistime + alignment_offset
                             + data_alignment_offset);
 
-               /*
-                * We might have had SMBnttranss in req->inbuf, fix that.
-                */
-               SCVAL(req->outbuf, smb_com, SMBnttrans);
-
                /*
                 * Set total params and data to be sent.
                 */
@@ -860,6 +855,12 @@ static NTSTATUS set_sd(files_struct *fsp, uint8 *data, uint32 sd_len,
 
        /* Ensure we have at least one thing set. */
        if ((security_info_sent & (SECINFO_OWNER|SECINFO_GROUP|SECINFO_DACL|SECINFO_SACL)) == 0) {
+               if (security_info_sent & SECINFO_LABEL) {
+                       /* Only consider SECINFO_LABEL if no other
+                          bits are set. Just like W2K3 we don't
+                          store this. */
+                       return NT_STATUS_OK;
+               }
                return NT_STATUS_INVALID_PARAMETER;
        }
 
@@ -1837,8 +1838,30 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
         * Get the permissions to return.
         */
 
+       if ((security_info_wanted & SECINFO_SACL) &&
+                       !(fsp->access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
+               reply_nterror(req,  NT_STATUS_ACCESS_DENIED);
+               return;
+       }
+
+       if ((security_info_wanted & (SECINFO_DACL|SECINFO_OWNER|SECINFO_GROUP)) &&
+                       !(fsp->access_mask & SEC_STD_READ_CONTROL)) {
+               reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+               return;
+       }
+
+       if (security_info_wanted & (SECINFO_DACL|SECINFO_OWNER|
+                       SECINFO_GROUP|SECINFO_SACL)) {
+               /* Don't return SECINFO_LABEL if anything else was
+                  requested. See bug #8458. */
+               security_info_wanted &= ~SECINFO_LABEL;
+       }
+
        if (!lp_nt_acl_support(SNUM(conn))) {
                status = get_null_nt_acl(talloc_tos(), &psd);
+       } else if (security_info_wanted & SECINFO_LABEL) {
+               /* Like W2K3 return a null object. */
+               status = get_null_nt_acl(talloc_tos(), &psd);
        } else {
                status = SMB_VFS_FGET_NT_ACL(
                        fsp, security_info_wanted, &psd);
@@ -1855,9 +1878,11 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
                psd->group_sid = NULL;
        }
        if (!(security_info_wanted & SECINFO_DACL)) {
+               psd->type &= ~SEC_DESC_DACL_PRESENT;
                psd->dacl = NULL;
        }
        if (!(security_info_wanted & SECINFO_SACL)) {
+               psd->type &= ~SEC_DESC_SACL_PRESENT;
                psd->sacl = NULL;
        }
 
@@ -1870,6 +1895,15 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
            security_info_wanted & DACL_SECURITY_INFORMATION)
                psd->type |= SEC_DESC_DACL_PRESENT;
 
+       if (security_info_wanted & SECINFO_LABEL) {
+               /* Like W2K3 return a null object. */
+               psd->owner_sid = NULL;
+               psd->group_sid = NULL;
+               psd->dacl = NULL;
+               psd->sacl = NULL;
+               psd->type &= ~(SEC_DESC_DACL_PRESENT|SEC_DESC_SACL_PRESENT);
+       }
+
        sd_size = ndr_size_security_descriptor(psd, NULL, 0);
 
        DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));
@@ -2298,7 +2332,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
        ZERO_STRUCT(qt);
 
        /* access check */
-       if (conn->server_info->utok.uid != 0) {
+       if (conn->server_info->utok.uid != 0 && !conn->admin_user) {
                DEBUG(1,("get_user_quota: access_denied service [%s] user "
                         "[%s]\n", lp_servicename(SNUM(conn)),
                         conn->server_info->unix_name));
@@ -2568,7 +2602,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn,
        ZERO_STRUCT(qt);
 
        /* access check */
-       if (conn->server_info->utok.uid != 0) {
+       if (conn->server_info->utok.uid != 0 && !conn->admin_user) {
                DEBUG(1,("set_user_quota: access_denied service [%s] user "
                         "[%s]\n", lp_servicename(SNUM(conn)),
                         conn->server_info->unix_name));
@@ -3029,6 +3063,12 @@ void reply_nttranss(struct smb_request *req)
 
        show_msg((char *)req->inbuf);
 
+       /* Windows clients expect all replies to
+          an NT transact secondary (SMBnttranss 0xA1)
+          to have a command code of NT transact
+          (SMBnttrans 0xA0). See bug #8989 for details. */
+       req->cmd = SMBnttrans;
+
        if (req->wct < 18) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                END_PROFILE(SMBnttranss);