r22732: - Testing of libsmbclient against Vista revealed what is likely a bug in
[vlendec/samba-autobuild/.git] / source3 / libsmb / clierror.c
index fcedc3bdab163aeb808b824f5c47e304a7745948..d98f42821790c151df0c0e91c67c76ef423003d1 100644 (file)
@@ -84,6 +84,7 @@ static NTSTATUS cli_smb_rw_error_to_ntstatus(struct cli_state *cli)
                case WRITE_ERROR:
                        return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
                case READ_BAD_SIG:
+               case READ_BAD_DECRYPT:
                        return NT_STATUS_INVALID_PARAMETER;
                default:
                        break;
@@ -133,6 +134,10 @@ const char *cli_errstr(struct cli_state *cli)
                                slprintf(cli_error_message, sizeof(cli_error_message) - 1,
                                        "Server packet had invalid SMB signature!");
                                break;
+                       case READ_BAD_DECRYPT:
+                               slprintf(cli_error_message, sizeof(cli_error_message) - 1,
+                                       "Server packet could not be decrypted !");
+                               break;
                        default:
                                slprintf(cli_error_message, sizeof(cli_error_message) - 1,
                                        "Unknown error code %d\n", cli->smb_rw_error );
@@ -380,6 +385,15 @@ int cli_errno(struct cli_state *cli)
                return cli_errno_from_nt(status);
         }
 
+        /*
+         * Yuck!  A special case for this Vista error.  Since its high-order
+         * byte isn't 0xc0, it doesn't match cli_is_nt_error() above.
+         */
+        status = cli_nt_error(cli);
+        if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT)) {
+            return EACCES;
+        }
+
        /* for other cases */
        return EINVAL;
 }
@@ -451,3 +465,12 @@ NTSTATUS cli_get_nt_error(struct cli_state *cli)
                return NT_STATUS_UNSUCCESSFUL;
        }
 }
+
+/* Push an error code into the inbuf to be returned on the next
+ * query. */
+
+void cli_set_nt_error(struct cli_state *cli, NTSTATUS status)
+{
+       SSVAL(cli->inbuf,smb_flg2, SVAL(cli->inbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES);
+       SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(status));
+}